mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-23 22:53:31 +08:00
Compare commits
52 Commits
Author | SHA1 | Date | |
---|---|---|---|
3d12ac8dc2 | |||
f01839123f | |||
e1b3b0ac6a | |||
4b0a2fdbfc | |||
db551eb24a | |||
18b49bb731 | |||
17653888a3 | |||
ee16616df4 | |||
ea450005e0 | |||
4c5ad14f6b | |||
49dda2aea5 | |||
a74a004540 | |||
2b89f6b37b | |||
c699e35e6b | |||
e28d90d0aa | |||
4fc7600865 | |||
19f62a461b | |||
7ddc2778c0 | |||
b96fa2a995 | |||
fcfb73af6e | |||
43bebc03b9 | |||
c5f25cbc7d | |||
3feb6ce84d | |||
08d6b45fc5 | |||
56d0de64dc | |||
1813e8e8c7 | |||
e27c764a55 | |||
e5a2057382 | |||
8457ff7433 | |||
888a6f2feb | |||
b57b64fc36 | |||
0d239ba1cf | |||
8927e08217 | |||
0636069584 | |||
4d0f73c84e | |||
74a2478e10 | |||
acc6f3e887 | |||
185ab9750a | |||
48adc050d6 | |||
b0e318c9db | |||
f9a6efc00f | |||
bd4a6775dd | |||
e3a43d0062 | |||
0cf281cac0 | |||
7322f67ae0 | |||
b927c6d7b4 | |||
01212cd1f3 | |||
bf55f94d41 | |||
f14711d315 | |||
58e1c28f7c | |||
922b19c64b | |||
1d21c3fa90 |
@ -25,7 +25,10 @@ enableErrorMask = false
|
|||||||
enableGzip = true
|
enableGzip = true
|
||||||
inactiveTimeoutMinutes =
|
inactiveTimeoutMinutes =
|
||||||
ldapServerPort = 389
|
ldapServerPort = 389
|
||||||
|
ldapsCertId = ""
|
||||||
|
ldapsServerPort = 636
|
||||||
radiusServerPort = 1812
|
radiusServerPort = 1812
|
||||||
|
radiusDefaultOrganization = "built-in"
|
||||||
radiusSecret = "secret"
|
radiusSecret = "secret"
|
||||||
quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
|
quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
|
||||||
logConfig = {"filename": "logs/casdoor.log", "maxdays":99999, "perm":"0770"}
|
logConfig = {"filename": "logs/casdoor.log", "maxdays":99999, "perm":"0770"}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -330,6 +331,8 @@ func (c *ApiController) Login() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verificationType := ""
|
||||||
|
|
||||||
if authForm.Username != "" {
|
if authForm.Username != "" {
|
||||||
if authForm.Type == ResponseTypeLogin {
|
if authForm.Type == ResponseTypeLogin {
|
||||||
if c.GetSessionUsername() != "" {
|
if c.GetSessionUsername() != "" {
|
||||||
@ -424,6 +427,12 @@ func (c *ApiController) Login() {
|
|||||||
c.ResponseError(err.Error(), nil)
|
c.ResponseError(err.Error(), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if verificationCodeType == object.VerifyTypePhone {
|
||||||
|
verificationType = "sms"
|
||||||
|
} else {
|
||||||
|
verificationType = "email"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
var application *object.Application
|
var application *object.Application
|
||||||
application, err = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
application, err = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||||
@ -523,9 +532,20 @@ func (c *ApiController) Login() {
|
|||||||
|
|
||||||
if user.IsMfaEnabled() {
|
if user.IsMfaEnabled() {
|
||||||
c.setMfaUserSession(user.GetId())
|
c.setMfaUserSession(user.GetId())
|
||||||
c.ResponseOk(object.NextMfa, user.GetPreferredMfaProps(true))
|
mfaList := object.GetAllMfaProps(user, true)
|
||||||
|
mfaAllowList := []*object.MfaProps{}
|
||||||
|
for _, prop := range mfaList {
|
||||||
|
if prop.MfaType == verificationType || !prop.Enabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mfaAllowList = append(mfaAllowList, prop)
|
||||||
|
}
|
||||||
|
if len(mfaAllowList) >= 1 {
|
||||||
|
c.SetSession("verificationCodeType", verificationType)
|
||||||
|
c.ResponseOk(object.NextMfa, mfaAllowList)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resp = c.HandleLoggedIn(application, user, &authForm)
|
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||||
|
|
||||||
@ -617,6 +637,17 @@ func (c *ApiController) Login() {
|
|||||||
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to login in: %s"), err.Error()))
|
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to login in: %s"), err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if provider.EmailRegex != "" {
|
||||||
|
reg, err := regexp.Compile(provider.EmailRegex)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to login in: %s"), err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reg.MatchString(userInfo.Email) {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("check:Email is invalid")))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if authForm.Method == "signup" {
|
if authForm.Method == "signup" {
|
||||||
@ -854,8 +885,12 @@ func (c *ApiController) Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if authForm.Passcode != "" {
|
if authForm.Passcode != "" {
|
||||||
|
if authForm.MfaType == c.GetSession("verificationCodeType") {
|
||||||
|
c.ResponseError("Invalid multi-factor authentication type")
|
||||||
|
return
|
||||||
|
}
|
||||||
user.CountryCode = user.GetCountryCode(user.CountryCode)
|
user.CountryCode = user.GetCountryCode(user.CountryCode)
|
||||||
mfaUtil := object.GetMfaUtil(authForm.MfaType, user.GetPreferredMfaProps(false))
|
mfaUtil := object.GetMfaUtil(authForm.MfaType, user.GetMfaProps(authForm.MfaType, false))
|
||||||
if mfaUtil == nil {
|
if mfaUtil == nil {
|
||||||
c.ResponseError("Invalid multi-factor authentication type")
|
c.ResponseError("Invalid multi-factor authentication type")
|
||||||
return
|
return
|
||||||
@ -866,6 +901,7 @@ func (c *ApiController) Login() {
|
|||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
c.SetSession("verificationCodeType", "")
|
||||||
} else if authForm.RecoveryCode != "" {
|
} else if authForm.RecoveryCode != "" {
|
||||||
err = object.MfaRecover(user, authForm.RecoveryCode)
|
err = object.MfaRecover(user, authForm.RecoveryCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,6 +21,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *RootController) HandleScim() {
|
func (c *RootController) HandleScim() {
|
||||||
|
_, ok := c.RequireAdmin()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
path := c.Ctx.Request.URL.Path
|
path := c.Ctx.Request.URL.Path
|
||||||
c.Ctx.Request.URL.Path = strings.TrimPrefix(path, "/scim")
|
c.Ctx.Request.URL.Path = strings.TrimPrefix(path, "/scim")
|
||||||
scim.Server.ServeHTTP(c.Ctx.ResponseWriter, c.Ctx.Request)
|
scim.Server.ServeHTTP(c.Ctx.ResponseWriter, c.Ctx.Request)
|
||||||
|
@ -93,7 +93,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
|
// 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" {
|
if len(emailForm.Receivers) == 1 && emailForm.Receivers[0] == "TestSmtpServer" {
|
||||||
err = object.DailSmtpServer(provider)
|
err = object.TestSmtpServer(provider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
|
@ -402,6 +402,7 @@ func (c *ApiController) IntrospectToken() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
introspectionResponse.TokenType = token.TokenType
|
||||||
|
|
||||||
c.Data["json"] = introspectionResponse
|
c.Data["json"] = introspectionResponse
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
|
@ -353,13 +353,7 @@ func (c *ApiController) AddUser() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := object.GetUserCount("", "", "", "")
|
if err := checkQuotaForUser(); err != nil {
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := checkQuotaForUser(int(count)); err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -475,6 +469,16 @@ func (c *ApiController) SetPassword() {
|
|||||||
|
|
||||||
userId := util.GetId(userOwner, userName)
|
userId := util.GetId(userOwner, userName)
|
||||||
|
|
||||||
|
user, err := object.GetUser(userId)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if user == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), userId))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
requestUserId := c.GetSessionUsername()
|
requestUserId := c.GetSessionUsername()
|
||||||
if requestUserId == "" && code == "" {
|
if requestUserId == "" && code == "" {
|
||||||
c.ResponseError(c.T("general:Please login first"), "Please login first")
|
c.ResponseError(c.T("general:Please login first"), "Please login first")
|
||||||
@ -518,7 +522,11 @@ func (c *ApiController) SetPassword() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if code == "" {
|
} else if code == "" {
|
||||||
|
if user.Ldap == "" {
|
||||||
err = object.CheckPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
err = object.CheckPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
||||||
|
} else {
|
||||||
|
err = object.CheckLdapUserPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -563,7 +571,16 @@ func (c *ApiController) SetPassword() {
|
|||||||
targetUser.NeedUpdatePassword = false
|
targetUser.NeedUpdatePassword = false
|
||||||
targetUser.LastChangePasswordTime = util.GetCurrentTime()
|
targetUser.LastChangePasswordTime = util.GetCurrentTime()
|
||||||
|
|
||||||
|
if user.Ldap == "" {
|
||||||
_, err = object.UpdateUser(userId, targetUser, []string{"password", "need_update_password", "password_type", "last_change_password_time"}, false)
|
_, err = object.UpdateUser(userId, targetUser, []string{"password", "need_update_password", "password_type", "last_change_password_time"}, false)
|
||||||
|
} else {
|
||||||
|
if isAdmin {
|
||||||
|
err = object.ResetLdapPassword(targetUser, "", newPassword, c.GetAcceptLanguage())
|
||||||
|
} else {
|
||||||
|
err = object.ResetLdapPassword(targetUser, oldPassword, newPassword, c.GetAcceptLanguage())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
|
@ -294,12 +294,18 @@ func checkQuotaForProvider(count int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkQuotaForUser(count int) error {
|
func checkQuotaForUser() error {
|
||||||
quota := conf.GetConfigQuota().User
|
quota := conf.GetConfigQuota().User
|
||||||
if quota == -1 {
|
if quota == -1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if count >= quota {
|
|
||||||
|
count, err := object.GetUserCount("", "", "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if int(count) >= quota {
|
||||||
return fmt.Errorf("user quota is exceeded")
|
return fmt.Errorf("user quota is exceeded")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -16,7 +16,9 @@ package email
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/gomail/v2"
|
"github.com/casdoor/gomail/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,6 +35,13 @@ func NewSmtpEmailProvider(userName string, password string, host string, port in
|
|||||||
|
|
||||||
dialer.SSL = !disableSsl
|
dialer.SSL = !disableSsl
|
||||||
|
|
||||||
|
if strings.HasSuffix(host, ".amazonaws.com") {
|
||||||
|
socks5Proxy := conf.GetConfigString("socks5Proxy")
|
||||||
|
if socks5Proxy != "" {
|
||||||
|
dialer.SetSocks5Proxy(socks5Proxy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &SmtpEmailProvider{Dialer: dialer}
|
return &SmtpEmailProvider{Dialer: dialer}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
go.mod
9
go.mod
@ -10,9 +10,9 @@ require (
|
|||||||
github.com/beevik/etree v1.1.0
|
github.com/beevik/etree v1.1.0
|
||||||
github.com/casbin/casbin/v2 v2.77.2
|
github.com/casbin/casbin/v2 v2.77.2
|
||||||
github.com/casdoor/go-sms-sender v0.25.0
|
github.com/casdoor/go-sms-sender v0.25.0
|
||||||
github.com/casdoor/gomail/v2 v2.0.1
|
github.com/casdoor/gomail/v2 v2.1.0
|
||||||
github.com/casdoor/ldapserver v1.2.0
|
github.com/casdoor/ldapserver v1.2.0
|
||||||
github.com/casdoor/notify v0.45.0
|
github.com/casdoor/notify v1.0.0
|
||||||
github.com/casdoor/oss v1.8.0
|
github.com/casdoor/oss v1.8.0
|
||||||
github.com/casdoor/xorm-adapter/v3 v3.1.0
|
github.com/casdoor/xorm-adapter/v3 v3.1.0
|
||||||
github.com/casvisor/casvisor-go-sdk v1.4.0
|
github.com/casvisor/casvisor-go-sdk v1.4.0
|
||||||
@ -60,9 +60,10 @@ require (
|
|||||||
github.com/xorm-io/core v0.7.4
|
github.com/xorm-io/core v0.7.4
|
||||||
github.com/xorm-io/xorm v1.1.6
|
github.com/xorm-io/xorm v1.1.6
|
||||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||||
golang.org/x/crypto v0.21.0
|
golang.org/x/crypto v0.32.0
|
||||||
golang.org/x/net v0.21.0
|
golang.org/x/net v0.34.0
|
||||||
golang.org/x/oauth2 v0.17.0
|
golang.org/x/oauth2 v0.17.0
|
||||||
|
golang.org/x/text v0.21.0
|
||||||
google.golang.org/api v0.150.0
|
google.golang.org/api v0.150.0
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0
|
gopkg.in/square/go-jose.v2 v2.6.0
|
||||||
|
41
go.sum
41
go.sum
@ -1089,12 +1089,12 @@ github.com/casdoor/go-reddit/v2 v2.1.0 h1:kIbfdJ7AA7H0uTQ8s0q4GGZqSS5V9wVE74RrXy
|
|||||||
github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc=
|
github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc=
|
||||||
github.com/casdoor/go-sms-sender v0.25.0 h1:eF4cOCSbjVg7+0uLlJQnna/FQ0BWW+Fp/x4cXhzQu1Y=
|
github.com/casdoor/go-sms-sender v0.25.0 h1:eF4cOCSbjVg7+0uLlJQnna/FQ0BWW+Fp/x4cXhzQu1Y=
|
||||||
github.com/casdoor/go-sms-sender v0.25.0/go.mod h1:bOm4H8/YfJmEHjBatEVQFOnAf0OOn1B0Wi5B7zDhws0=
|
github.com/casdoor/go-sms-sender v0.25.0/go.mod h1:bOm4H8/YfJmEHjBatEVQFOnAf0OOn1B0Wi5B7zDhws0=
|
||||||
github.com/casdoor/gomail/v2 v2.0.1 h1:J+FG6x80s9e5lBHUn8Sv0Y56mud34KiWih5YdmudR/w=
|
github.com/casdoor/gomail/v2 v2.1.0 h1:ua97E3CARnF1Ik8ga/Drz9uGZfaElXJumFexiErWUxM=
|
||||||
github.com/casdoor/gomail/v2 v2.0.1/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q=
|
github.com/casdoor/gomail/v2 v2.1.0/go.mod h1:GFzOD9RhY0nODiiPaQiOa6DfoKtmO9aTesu5qrp26OI=
|
||||||
github.com/casdoor/ldapserver v1.2.0 h1:HdSYe+ULU6z9K+2BqgTrJKQRR4//ERAXB64ttOun6Ow=
|
github.com/casdoor/ldapserver v1.2.0 h1:HdSYe+ULU6z9K+2BqgTrJKQRR4//ERAXB64ttOun6Ow=
|
||||||
github.com/casdoor/ldapserver v1.2.0/go.mod h1:VwYU2vqQ2pA8sa00PRekH71R2XmgfzMKhmp1XrrDu2s=
|
github.com/casdoor/ldapserver v1.2.0/go.mod h1:VwYU2vqQ2pA8sa00PRekH71R2XmgfzMKhmp1XrrDu2s=
|
||||||
github.com/casdoor/notify v0.45.0 h1:OlaFvcQFjGOgA4mRx07M8AH1gvb5xNo21mcqrVGlLgk=
|
github.com/casdoor/notify v1.0.0 h1:oldsaaQFPrlufm/OA314z8DwFVE1Tc9Gt1z4ptRHhXw=
|
||||||
github.com/casdoor/notify v0.45.0/go.mod h1:wNHQu0tiDROMBIvz0j3Om3Lhd5yZ+AIfnFb8MYb8OLQ=
|
github.com/casdoor/notify v1.0.0/go.mod h1:wNHQu0tiDROMBIvz0j3Om3Lhd5yZ+AIfnFb8MYb8OLQ=
|
||||||
github.com/casdoor/oss v1.8.0 h1:uuyKhDIp7ydOtV4lpqhAY23Ban2Ln8La8+QT36CwylM=
|
github.com/casdoor/oss v1.8.0 h1:uuyKhDIp7ydOtV4lpqhAY23Ban2Ln8La8+QT36CwylM=
|
||||||
github.com/casdoor/oss v1.8.0/go.mod h1:uaqO7KBI2lnZcnB8rF7O6C2bN7llIbfC5Ql8ex1yR1U=
|
github.com/casdoor/oss v1.8.0/go.mod h1:uaqO7KBI2lnZcnB8rF7O6C2bN7llIbfC5Ql8ex1yR1U=
|
||||||
github.com/casdoor/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk=
|
github.com/casdoor/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk=
|
||||||
@ -2163,8 +2163,10 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf
|
|||||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
|
||||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@ -2230,8 +2232,10 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|||||||
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
|
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||||
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20171115151908-9dfe39835686/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20171115151908-9dfe39835686/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -2319,8 +2323,10 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|||||||
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
|
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -2375,8 +2381,11 @@ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
|
||||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -2503,8 +2512,11 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@ -2524,8 +2536,10 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
|||||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
|
||||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
|
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||||
|
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -2546,8 +2560,10 @@ golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|||||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@ -2634,8 +2650,9 @@ golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
|||||||
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||||
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||||
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
|
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
|
||||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||||
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
@ -188,10 +188,23 @@ type GitHubUserInfo struct {
|
|||||||
} `json:"plan"`
|
} `json:"plan"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GitHubUserEmailInfo struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
Primary bool `json:"primary"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Visibility string `json:"visibility"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GitHubErrorInfo struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
DocumentationUrl string `json:"documentation_url"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||||
req, err := http.NewRequest("GET", "https://api.github.com/user", nil)
|
req, err := http.NewRequest("GET", "https://api.github.com/user", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Add("Authorization", "token "+token.AccessToken)
|
req.Header.Add("Authorization", "token "+token.AccessToken)
|
||||||
resp, err := idp.Client.Do(req)
|
resp, err := idp.Client.Do(req)
|
||||||
@ -212,6 +225,42 @@ func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if githubUserInfo.Email == "" {
|
||||||
|
reqEmail, err := http.NewRequest("GET", "https://api.github.com/user/emails", nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reqEmail.Header.Add("Authorization", "token "+token.AccessToken)
|
||||||
|
respEmail, err := idp.Client.Do(reqEmail)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer respEmail.Body.Close()
|
||||||
|
emailBody, err := io.ReadAll(respEmail.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if respEmail.StatusCode != 200 {
|
||||||
|
var errMessage GitHubErrorInfo
|
||||||
|
err = json.Unmarshal(emailBody, &errMessage)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("GithubIdProvider:GetUserInfo() error, status code = %d, error message = %v\n", respEmail.StatusCode, errMessage)
|
||||||
|
} else {
|
||||||
|
var userEmails []GitHubUserEmailInfo
|
||||||
|
err = json.Unmarshal(emailBody, &userEmails)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
githubUserInfo.Email = idp.getEmailFromEmailsResult(userEmails)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
userInfo := UserInfo{
|
userInfo := UserInfo{
|
||||||
Id: strconv.Itoa(githubUserInfo.Id),
|
Id: strconv.Itoa(githubUserInfo.Id),
|
||||||
Username: githubUserInfo.Login,
|
Username: githubUserInfo.Login,
|
||||||
@ -248,3 +297,27 @@ func (idp *GithubIdProvider) postWithBody(body interface{}, url string) ([]byte,
|
|||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (idp *GithubIdProvider) getEmailFromEmailsResult(emailInfo []GitHubUserEmailInfo) string {
|
||||||
|
primaryEmail := ""
|
||||||
|
verifiedEmail := ""
|
||||||
|
|
||||||
|
for _, addr := range emailInfo {
|
||||||
|
if !addr.Verified || strings.Contains(addr.Email, "users.noreply.github.com") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if addr.Primary {
|
||||||
|
primaryEmail = addr.Email
|
||||||
|
break
|
||||||
|
} else if verifiedEmail == "" {
|
||||||
|
verifiedEmail = addr.Email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if primaryEmail != "" {
|
||||||
|
return primaryEmail
|
||||||
|
}
|
||||||
|
|
||||||
|
return verifiedEmail
|
||||||
|
}
|
||||||
|
161
idp/kwai.go
Normal file
161
idp/kwai.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
package idp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KwaiIdProvider struct {
|
||||||
|
Client *http.Client
|
||||||
|
Config *oauth2.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewKwaiIdProvider(clientId string, clientSecret string, redirectUrl string) *KwaiIdProvider {
|
||||||
|
idp := &KwaiIdProvider{}
|
||||||
|
idp.Config = idp.getConfig(clientId, clientSecret, redirectUrl)
|
||||||
|
return idp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (idp *KwaiIdProvider) SetHttpClient(client *http.Client) {
|
||||||
|
idp.Client = client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (idp *KwaiIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
|
||||||
|
endpoint := oauth2.Endpoint{
|
||||||
|
TokenURL: "https://open.kuaishou.com/oauth2/access_token",
|
||||||
|
AuthURL: "https://open.kuaishou.com/oauth2/authorize", // qr code: /oauth2/connect
|
||||||
|
}
|
||||||
|
|
||||||
|
config := &oauth2.Config{
|
||||||
|
Scopes: []string{"user_info"},
|
||||||
|
Endpoint: endpoint,
|
||||||
|
ClientID: clientId,
|
||||||
|
ClientSecret: clientSecret,
|
||||||
|
RedirectURL: redirectUrl,
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
type KwaiTokenResp struct {
|
||||||
|
Result int `json:"result"`
|
||||||
|
ErrorMsg string `json:"error_msg"`
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
ExpiresIn int `json:"expires_in"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
RefreshTokenExpiresIn int `json:"refresh_token_expires_in"`
|
||||||
|
OpenId string `json:"open_id"`
|
||||||
|
Scopes []string `json:"scopes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetToken use code to get access_token
|
||||||
|
func (idp *KwaiIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||||
|
params := map[string]string{
|
||||||
|
"app_id": idp.Config.ClientID,
|
||||||
|
"app_secret": idp.Config.ClientSecret,
|
||||||
|
"code": code,
|
||||||
|
"grant_type": "authorization_code",
|
||||||
|
}
|
||||||
|
tokenUrl := fmt.Sprintf("%s?app_id=%s&app_secret=%s&code=%s&grant_type=authorization_code",
|
||||||
|
idp.Config.Endpoint.TokenURL, params["app_id"], params["app_secret"], params["code"])
|
||||||
|
resp, err := idp.Client.Get(tokenUrl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var tokenResp KwaiTokenResp
|
||||||
|
err = json.Unmarshal(body, &tokenResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if tokenResp.Result != 1 {
|
||||||
|
return nil, fmt.Errorf("get token error: %s", tokenResp.ErrorMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
token := &oauth2.Token{
|
||||||
|
AccessToken: tokenResp.AccessToken,
|
||||||
|
RefreshToken: tokenResp.RefreshToken,
|
||||||
|
Expiry: time.Now().Add(time.Duration(tokenResp.ExpiresIn) * time.Second),
|
||||||
|
}
|
||||||
|
|
||||||
|
raw := make(map[string]interface{})
|
||||||
|
raw["open_id"] = tokenResp.OpenId
|
||||||
|
token = token.WithExtra(raw)
|
||||||
|
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// More details: https://open.kuaishou.com/openapi/user_info
|
||||||
|
type KwaiUserInfo struct {
|
||||||
|
Result int `json:"result"`
|
||||||
|
ErrorMsg string `json:"error_msg"`
|
||||||
|
UserInfo struct {
|
||||||
|
Head string `json:"head"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Sex string `json:"sex"`
|
||||||
|
City string `json:"city"`
|
||||||
|
} `json:"user_info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserInfo use token to get user profile
|
||||||
|
func (idp *KwaiIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||||
|
userInfoUrl := fmt.Sprintf("https://open.kuaishou.com/openapi/user_info?app_id=%s&access_token=%s",
|
||||||
|
idp.Config.ClientID, token.AccessToken)
|
||||||
|
|
||||||
|
resp, err := idp.Client.Get(userInfoUrl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var kwaiUserInfo KwaiUserInfo
|
||||||
|
err = json.Unmarshal(body, &kwaiUserInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if kwaiUserInfo.Result != 1 {
|
||||||
|
return nil, fmt.Errorf("get user info error: %s", kwaiUserInfo.ErrorMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
userInfo := &UserInfo{
|
||||||
|
Id: token.Extra("open_id").(string),
|
||||||
|
Username: kwaiUserInfo.UserInfo.Name,
|
||||||
|
DisplayName: kwaiUserInfo.UserInfo.Name,
|
||||||
|
AvatarUrl: kwaiUserInfo.UserInfo.Head,
|
||||||
|
Extra: map[string]string{
|
||||||
|
"gender": kwaiUserInfo.UserInfo.Sex,
|
||||||
|
"city": kwaiUserInfo.UserInfo.City,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return userInfo, nil
|
||||||
|
}
|
@ -113,6 +113,8 @@ func GetIdProvider(idpInfo *ProviderInfo, redirectUrl string) (IdProvider, error
|
|||||||
return NewOktaIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl), nil
|
return NewOktaIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl), nil
|
||||||
case "Douyin":
|
case "Douyin":
|
||||||
return NewDouyinIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
return NewDouyinIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
|
case "Kwai":
|
||||||
|
return NewKwaiIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "Bilibili":
|
case "Bilibili":
|
||||||
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl), nil
|
||||||
case "MetaMask":
|
case "MetaMask":
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"log"
|
"log"
|
||||||
@ -27,21 +28,68 @@ import (
|
|||||||
|
|
||||||
func StartLdapServer() {
|
func StartLdapServer() {
|
||||||
ldapServerPort := conf.GetConfigString("ldapServerPort")
|
ldapServerPort := conf.GetConfigString("ldapServerPort")
|
||||||
if ldapServerPort == "" || ldapServerPort == "0" {
|
ldapsServerPort := conf.GetConfigString("ldapsServerPort")
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
server := ldap.NewServer()
|
server := ldap.NewServer()
|
||||||
|
serverSsl := ldap.NewServer()
|
||||||
routes := ldap.NewRouteMux()
|
routes := ldap.NewRouteMux()
|
||||||
|
|
||||||
routes.Bind(handleBind)
|
routes.Bind(handleBind)
|
||||||
routes.Search(handleSearch).Label(" SEARCH****")
|
routes.Search(handleSearch).Label(" SEARCH****")
|
||||||
|
|
||||||
server.Handle(routes)
|
server.Handle(routes)
|
||||||
|
serverSsl.Handle(routes)
|
||||||
|
go func() {
|
||||||
|
if ldapServerPort == "" || ldapServerPort == "0" {
|
||||||
|
return
|
||||||
|
}
|
||||||
err := server.ListenAndServe("0.0.0.0:" + ldapServerPort)
|
err := server.ListenAndServe("0.0.0.0:" + ldapServerPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("StartLdapServer() failed, err = %s", err.Error())
|
log.Printf("StartLdapServer() failed, err = %s", err.Error())
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if ldapsServerPort == "" || ldapsServerPort == "0" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ldapsCertId := conf.GetConfigString("ldapsCertId")
|
||||||
|
if ldapsCertId == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config, err := getTLSconfig(ldapsCertId)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("StartLdapsServer() failed, err = %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
secureConn := func(s *ldap.Server) {
|
||||||
|
s.Listener = tls.NewListener(s.Listener, config)
|
||||||
|
}
|
||||||
|
err = serverSsl.ListenAndServe("0.0.0.0:"+ldapsServerPort, secureConn)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("StartLdapsServer() failed, err = %s", err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTLSconfig(ldapsCertId string) (*tls.Config, error) {
|
||||||
|
rawCert, err := object.GetCert(ldapsCertId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if rawCert == nil {
|
||||||
|
return nil, fmt.Errorf("cert is empty")
|
||||||
|
}
|
||||||
|
cert, err := tls.X509KeyPair([]byte(rawCert.Certificate), []byte(rawCert.PrivateKey))
|
||||||
|
if err != nil {
|
||||||
|
return &tls.Config{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tls.Config{
|
||||||
|
MinVersion: tls.VersionTLS10,
|
||||||
|
MaxVersion: tls.VersionTLS13,
|
||||||
|
Certificates: []tls.Certificate{cert},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleBind(w ldap.ResponseWriter, m *ldap.Message) {
|
func handleBind(w ldap.ResponseWriter, m *ldap.Message) {
|
||||||
|
5
main.go
5
main.go
@ -83,6 +83,11 @@ func main() {
|
|||||||
// logs.SetLevel(logs.LevelInformational)
|
// logs.SetLevel(logs.LevelInformational)
|
||||||
logs.SetLogFuncCall(false)
|
logs.SetLogFuncCall(false)
|
||||||
|
|
||||||
|
err = util.StopOldInstance(port)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
go ldap.StartLdapServer()
|
go ldap.StartLdapServer()
|
||||||
go radius.StartRadiusServer()
|
go radius.StartRadiusServer()
|
||||||
go object.ClearThroughputPerSecond()
|
go object.ClearThroughputPerSecond()
|
||||||
|
29
notification/cucloud.go
Normal file
29
notification/cucloud.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package notification
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/casdoor/notify"
|
||||||
|
"github.com/casdoor/notify/service/cucloud"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCucloudProvider(accessKey, secretKey, topicName, messageTitle, cloudRegionCode, accountId, notifyType string) (notify.Notifier, error) {
|
||||||
|
cucloud := cucloud.New(accessKey, secretKey, topicName, messageTitle, cloudRegionCode, accountId, notifyType)
|
||||||
|
|
||||||
|
notifier := notify.New()
|
||||||
|
notifier.UseServices(cucloud)
|
||||||
|
|
||||||
|
return notifier, nil
|
||||||
|
}
|
@ -16,7 +16,7 @@ package notification
|
|||||||
|
|
||||||
import "github.com/casdoor/notify"
|
import "github.com/casdoor/notify"
|
||||||
|
|
||||||
func GetNotificationProvider(typ string, clientId string, clientSecret string, clientId2 string, clientSecret2 string, appId string, receiver string, method string, title string, metaData string) (notify.Notifier, error) {
|
func GetNotificationProvider(typ string, clientId string, clientSecret string, clientId2 string, clientSecret2 string, appId string, receiver string, method string, title string, metaData string, regionId string) (notify.Notifier, error) {
|
||||||
if typ == "Telegram" {
|
if typ == "Telegram" {
|
||||||
return NewTelegramProvider(clientSecret, receiver)
|
return NewTelegramProvider(clientSecret, receiver)
|
||||||
} else if typ == "Custom HTTP" {
|
} else if typ == "Custom HTTP" {
|
||||||
@ -53,6 +53,8 @@ func GetNotificationProvider(typ string, clientId string, clientSecret string, c
|
|||||||
return NewRocketChatProvider(clientId, clientSecret, appId, receiver)
|
return NewRocketChatProvider(clientId, clientSecret, appId, receiver)
|
||||||
} else if typ == "Viber" {
|
} else if typ == "Viber" {
|
||||||
return NewViberProvider(clientId, clientSecret, appId, receiver)
|
return NewViberProvider(clientId, clientSecret, appId, receiver)
|
||||||
|
} else if typ == "CUCloud" {
|
||||||
|
return NewCucloudProvider(clientId, clientSecret, appId, title, regionId, clientId2, metaData)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -273,7 +273,7 @@ func CheckPasswordComplexity(user *User, password string) string {
|
|||||||
return CheckPasswordComplexityByOrg(organization, password)
|
return CheckPasswordComplexityByOrg(organization, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkLdapUserPassword(user *User, password string, lang string) error {
|
func CheckLdapUserPassword(user *User, password string, lang string) error {
|
||||||
ldaps, err := GetLdaps(user.Owner)
|
ldaps, err := GetLdaps(user.Owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -368,7 +368,7 @@ func CheckUserPassword(organization string, username string, password string, la
|
|||||||
}
|
}
|
||||||
|
|
||||||
// only for LDAP users
|
// only for LDAP users
|
||||||
err = checkLdapUserPassword(user, password, lang)
|
err = CheckLdapUserPassword(user, password, lang)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err.Error() == "user not exist" {
|
if err.Error() == "user not exist" {
|
||||||
return nil, fmt.Errorf(i18n.Translate(lang, "check:The user: %s doesn't exist in LDAP server"), username)
|
return nil, fmt.Errorf(i18n.Translate(lang, "check:The user: %s doesn't exist in LDAP server"), username)
|
||||||
|
@ -16,23 +16,18 @@
|
|||||||
|
|
||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import "github.com/casdoor/casdoor/email"
|
||||||
"crypto/tls"
|
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/email"
|
// TestSmtpServer Test the SMTP server
|
||||||
"github.com/casdoor/gomail/v2"
|
func TestSmtpServer(provider *Provider) error {
|
||||||
)
|
smtpEmailProvider := email.NewSmtpEmailProvider(provider.ClientId, provider.ClientSecret, provider.Host, provider.Port, provider.Type, provider.DisableSsl)
|
||||||
|
sender, err := smtpEmailProvider.Dialer.Dial()
|
||||||
func getDialer(provider *Provider) *gomail.Dialer {
|
if err != nil {
|
||||||
dialer := &gomail.Dialer{}
|
return err
|
||||||
dialer = gomail.NewDialer(provider.Host, provider.Port, provider.ClientId, provider.ClientSecret)
|
|
||||||
if provider.Type == "SUBMAIL" {
|
|
||||||
dialer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
|
||||||
}
|
}
|
||||||
|
defer sender.Close()
|
||||||
|
|
||||||
dialer.SSL = !provider.DisableSsl
|
return nil
|
||||||
|
|
||||||
return dialer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendEmail(provider *Provider, title string, content string, dest string, sender string) error {
|
func SendEmail(provider *Provider, title string, content string, dest string, sender string) error {
|
||||||
@ -50,16 +45,3 @@ func SendEmail(provider *Provider, title string, content string, dest string, se
|
|||||||
|
|
||||||
return emailProvider.Send(fromAddress, fromName, dest, title, content)
|
return emailProvider.Send(fromAddress, fromName, dest, title, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DailSmtpServer Dail Smtp server
|
|
||||||
func DailSmtpServer(provider *Provider) error {
|
|
||||||
dialer := getDialer(provider)
|
|
||||||
|
|
||||||
sender, err := dialer.Dial()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer sender.Close()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -19,235 +19,91 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Dashboard struct {
|
type DashboardDateItem struct {
|
||||||
OrganizationCounts []int `json:"organizationCounts"`
|
CreatedTime string `json:"createTime"`
|
||||||
UserCounts []int `json:"userCounts"`
|
|
||||||
ProviderCounts []int `json:"providerCounts"`
|
|
||||||
ApplicationCounts []int `json:"applicationCounts"`
|
|
||||||
SubscriptionCounts []int `json:"subscriptionCounts"`
|
|
||||||
RoleCounts []int `json:"roleCounts"`
|
|
||||||
GroupCounts []int `json:"groupCounts"`
|
|
||||||
ResourceCounts []int `json:"resourceCounts"`
|
|
||||||
CertCounts []int `json:"certCounts"`
|
|
||||||
PermissionCounts []int `json:"permissionCounts"`
|
|
||||||
TransactionCounts []int `json:"transactionCounts"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDashboard(owner string) (*Dashboard, error) {
|
type DashboardMapItem struct {
|
||||||
|
dashboardDateItems []DashboardDateItem
|
||||||
|
itemCount int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDashboard(owner string) (*map[string][]int64, error) {
|
||||||
if owner == "All" {
|
if owner == "All" {
|
||||||
owner = ""
|
owner = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
dashboard := &Dashboard{
|
dashboard := make(map[string][]int64)
|
||||||
OrganizationCounts: make([]int, 31),
|
dashboardMap := sync.Map{}
|
||||||
UserCounts: make([]int, 31),
|
tableNames := []string{"organization", "user", "provider", "application", "subscription", "role", "group", "resource", "cert", "permission", "transaction", "model", "adapter", "enforcer"}
|
||||||
ProviderCounts: make([]int, 31),
|
|
||||||
ApplicationCounts: make([]int, 31),
|
|
||||||
SubscriptionCounts: make([]int, 31),
|
|
||||||
RoleCounts: make([]int, 31),
|
|
||||||
GroupCounts: make([]int, 31),
|
|
||||||
ResourceCounts: make([]int, 31),
|
|
||||||
CertCounts: make([]int, 31),
|
|
||||||
PermissionCounts: make([]int, 31),
|
|
||||||
TransactionCounts: make([]int, 31),
|
|
||||||
}
|
|
||||||
|
|
||||||
organizations := []Organization{}
|
|
||||||
users := []User{}
|
|
||||||
providers := []Provider{}
|
|
||||||
applications := []Application{}
|
|
||||||
subscriptions := []Subscription{}
|
|
||||||
roles := []Role{}
|
|
||||||
groups := []Group{}
|
|
||||||
resources := []Resource{}
|
|
||||||
certs := []Cert{}
|
|
||||||
permissions := []Permission{}
|
|
||||||
transactions := []Transaction{}
|
|
||||||
|
|
||||||
|
time30day := time.Now().AddDate(0, 0, -30)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(11)
|
var err error
|
||||||
go func() {
|
wg.Add(len(tableNames))
|
||||||
|
ch := make(chan error, len(tableNames))
|
||||||
|
for _, tableName := range tableNames {
|
||||||
|
dashboard[tableName+"Counts"] = make([]int64, 31)
|
||||||
|
tableName := tableName
|
||||||
|
go func(ch chan error) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err := ormer.Engine.Find(&organizations, &Organization{Owner: owner}); err != nil {
|
dashboardDateItems := []DashboardDateItem{}
|
||||||
panic(err)
|
var countResult int64
|
||||||
|
|
||||||
|
dbQueryBefore := ormer.Engine.Cols("created_time")
|
||||||
|
dbQueryAfter := ormer.Engine.Cols("created_time")
|
||||||
|
|
||||||
|
if owner != "" {
|
||||||
|
dbQueryAfter = dbQueryAfter.And("owner = ?", owner)
|
||||||
|
dbQueryBefore = dbQueryBefore.And("owner = ?", owner)
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
if countResult, err = dbQueryBefore.And("created_time < ?", time30day).Table(tableName).Count(); err != nil {
|
||||||
defer wg.Done()
|
ch <- err
|
||||||
|
return
|
||||||
if err := ormer.Engine.Find(&users, &User{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}()
|
if err = dbQueryAfter.And("created_time >= ?", time30day).Table(tableName).Find(&dashboardDateItems); err != nil {
|
||||||
|
ch <- err
|
||||||
go func() {
|
return
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
if err := ormer.Engine.Find(&providers, &Provider{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
dashboardMap.Store(tableName, DashboardMapItem{
|
||||||
defer wg.Done()
|
dashboardDateItems: dashboardDateItems,
|
||||||
|
itemCount: countResult,
|
||||||
if err := ormer.Engine.Find(&applications, &Application{Owner: owner}); err != nil {
|
})
|
||||||
panic(err)
|
}(ch)
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
if err := ormer.Engine.Find(&subscriptions, &Subscription{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
if err := ormer.Engine.Find(&roles, &Role{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
if err := ormer.Engine.Find(&groups, &Group{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
if err := ormer.Engine.Find(&resources, &Resource{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
if err := ormer.Engine.Find(&certs, &Cert{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
if err := ormer.Engine.Find(&permissions, &Permission{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
if err := ormer.Engine.Find(&transactions, &Transaction{Owner: owner}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
close(ch)
|
||||||
|
|
||||||
|
for err = range ch {
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nowTime := time.Now()
|
nowTime := time.Now()
|
||||||
for i := 30; i >= 0; i-- {
|
for i := 30; i >= 0; i-- {
|
||||||
cutTime := nowTime.AddDate(0, 0, -i)
|
cutTime := nowTime.AddDate(0, 0, -i)
|
||||||
dashboard.OrganizationCounts[30-i] = countCreatedBefore(organizations, cutTime)
|
for _, tableName := range tableNames {
|
||||||
dashboard.UserCounts[30-i] = countCreatedBefore(users, cutTime)
|
item, exist := dashboardMap.Load(tableName)
|
||||||
dashboard.ProviderCounts[30-i] = countCreatedBefore(providers, cutTime)
|
if !exist {
|
||||||
dashboard.ApplicationCounts[30-i] = countCreatedBefore(applications, cutTime)
|
continue
|
||||||
dashboard.SubscriptionCounts[30-i] = countCreatedBefore(subscriptions, cutTime)
|
|
||||||
dashboard.RoleCounts[30-i] = countCreatedBefore(roles, cutTime)
|
|
||||||
dashboard.GroupCounts[30-i] = countCreatedBefore(groups, cutTime)
|
|
||||||
dashboard.ResourceCounts[30-i] = countCreatedBefore(resources, cutTime)
|
|
||||||
dashboard.CertCounts[30-i] = countCreatedBefore(certs, cutTime)
|
|
||||||
dashboard.PermissionCounts[30-i] = countCreatedBefore(permissions, cutTime)
|
|
||||||
dashboard.TransactionCounts[30-i] = countCreatedBefore(transactions, cutTime)
|
|
||||||
}
|
}
|
||||||
return dashboard, nil
|
dashboard[tableName+"Counts"][30-i] = countCreatedBefore(item.(DashboardMapItem), cutTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &dashboard, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func countCreatedBefore(objects interface{}, before time.Time) int {
|
func countCreatedBefore(dashboardMapItem DashboardMapItem, before time.Time) int64 {
|
||||||
count := 0
|
count := dashboardMapItem.itemCount
|
||||||
switch obj := objects.(type) {
|
for _, e := range dashboardMapItem.dashboardDateItems {
|
||||||
case []Organization:
|
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", e.CreatedTime)
|
||||||
for _, o := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", o.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
if createdTime.Before(before) {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case []User:
|
|
||||||
for _, u := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", u.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Provider:
|
|
||||||
for _, p := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", p.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Application:
|
|
||||||
for _, a := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", a.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Subscription:
|
|
||||||
for _, s := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", s.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Role:
|
|
||||||
for _, r := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", r.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Group:
|
|
||||||
for _, g := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", g.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Resource:
|
|
||||||
for _, r := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", r.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Cert:
|
|
||||||
for _, c := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", c.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Permission:
|
|
||||||
for _, p := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", p.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []Transaction:
|
|
||||||
for _, t := range obj {
|
|
||||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", t.CreatedTime)
|
|
||||||
if createdTime.Before(before) {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ type Ldap struct {
|
|||||||
Filter string `xorm:"varchar(200)" json:"filter"`
|
Filter string `xorm:"varchar(200)" json:"filter"`
|
||||||
FilterFields []string `xorm:"varchar(100)" json:"filterFields"`
|
FilterFields []string `xorm:"varchar(100)" json:"filterFields"`
|
||||||
DefaultGroup string `xorm:"varchar(100)" json:"defaultGroup"`
|
DefaultGroup string `xorm:"varchar(100)" json:"defaultGroup"`
|
||||||
|
PasswordType string `xorm:"varchar(100)" json:"passwordType"`
|
||||||
|
|
||||||
AutoSync int `json:"autoSync"`
|
AutoSync int `json:"autoSync"`
|
||||||
LastSync string `xorm:"varchar(100)" json:"lastSync"`
|
LastSync string `xorm:"varchar(100)" json:"lastSync"`
|
||||||
@ -149,7 +150,7 @@ func UpdateLdap(ldap *Ldap) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
affected, err := ormer.Engine.ID(ldap.Id).Cols("owner", "server_name", "host",
|
affected, err := ormer.Engine.ID(ldap.Id).Cols("owner", "server_name", "host",
|
||||||
"port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync", "default_group").Update(ldap)
|
"port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync", "default_group", "password_type").Update(ldap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,18 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
goldap "github.com/go-ldap/ldap/v3"
|
goldap "github.com/go-ldap/ldap/v3"
|
||||||
"github.com/thanhpk/randstr"
|
"github.com/thanhpk/randstr"
|
||||||
|
"golang.org/x/text/encoding/unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LdapConn struct {
|
type LdapConn struct {
|
||||||
@ -371,6 +375,88 @@ func GetExistUuids(owner string, uuids []string) ([]string, error) {
|
|||||||
return existUuids, nil
|
return existUuids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ResetLdapPassword(user *User, oldPassword string, newPassword string, lang string) error {
|
||||||
|
ldaps, err := GetLdaps(user.Owner)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ldapServer := range ldaps {
|
||||||
|
conn, err := ldapServer.GetLdapConn()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
searchReq := goldap.NewSearchRequest(ldapServer.BaseDn, goldap.ScopeWholeSubtree, goldap.NeverDerefAliases,
|
||||||
|
0, 0, false, ldapServer.buildAuthFilterString(user), []string{}, nil)
|
||||||
|
|
||||||
|
searchResult, err := conn.Conn.Search(searchReq)
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(searchResult.Entries) == 0 {
|
||||||
|
conn.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(searchResult.Entries) > 1 {
|
||||||
|
conn.Close()
|
||||||
|
return fmt.Errorf(i18n.Translate(lang, "check:Multiple accounts with same uid, please check your ldap server"))
|
||||||
|
}
|
||||||
|
|
||||||
|
userDn := searchResult.Entries[0].DN
|
||||||
|
|
||||||
|
var pwdEncoded string
|
||||||
|
modifyPasswordRequest := goldap.NewModifyRequest(userDn, nil)
|
||||||
|
if conn.IsAD {
|
||||||
|
utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
|
||||||
|
pwdEncoded, err := utf16.NewEncoder().String("\"" + newPassword + "\"")
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
modifyPasswordRequest.Replace("unicodePwd", []string{pwdEncoded})
|
||||||
|
modifyPasswordRequest.Replace("userAccountControl", []string{"512"})
|
||||||
|
} else if oldPassword != "" {
|
||||||
|
modifyPasswordRequestWithOldPassword := goldap.NewPasswordModifyRequest(userDn, oldPassword, newPassword)
|
||||||
|
_, err = conn.Conn.PasswordModify(modifyPasswordRequestWithOldPassword)
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
switch ldapServer.PasswordType {
|
||||||
|
case "SSHA":
|
||||||
|
pwdEncoded, err = generateSSHA(newPassword)
|
||||||
|
break
|
||||||
|
case "MD5":
|
||||||
|
md5Byte := md5.Sum([]byte(newPassword))
|
||||||
|
md5Password := base64.StdEncoding.EncodeToString(md5Byte[:])
|
||||||
|
pwdEncoded = "{MD5}" + md5Password
|
||||||
|
break
|
||||||
|
case "Plain":
|
||||||
|
pwdEncoded = newPassword
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
pwdEncoded = newPassword
|
||||||
|
break
|
||||||
|
}
|
||||||
|
modifyPasswordRequest.Replace("userPassword", []string{pwdEncoded})
|
||||||
|
}
|
||||||
|
|
||||||
|
err = conn.Conn.Modify(modifyPasswordRequest)
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ldapUser *LdapUser) buildLdapUserName(owner string) (string, error) {
|
func (ldapUser *LdapUser) buildLdapUserName(owner string) (string, error) {
|
||||||
user := User{}
|
user := User{}
|
||||||
uidWithNumber := fmt.Sprintf("%s_%s", ldapUser.Uid, ldapUser.UidNumber)
|
uidWithNumber := fmt.Sprintf("%s_%s", ldapUser.Uid, ldapUser.UidNumber)
|
||||||
|
36
object/ldap_password_type.go
Normal file
36
object/ldap_password_type.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package object
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/base64"
|
||||||
|
)
|
||||||
|
|
||||||
|
func generateSSHA(password string) (string, error) {
|
||||||
|
salt := make([]byte, 4)
|
||||||
|
_, err := rand.Read(salt)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
combined := append([]byte(password), salt...)
|
||||||
|
hash := sha1.Sum(combined)
|
||||||
|
hashWithSalt := append(hash[:], salt...)
|
||||||
|
encoded := base64.StdEncoding.EncodeToString(hashWithSalt)
|
||||||
|
|
||||||
|
return "{SSHA}" + encoded, nil
|
||||||
|
}
|
@ -23,7 +23,7 @@ import (
|
|||||||
|
|
||||||
func getNotificationClient(provider *Provider) (notify.Notifier, error) {
|
func getNotificationClient(provider *Provider) (notify.Notifier, error) {
|
||||||
var client notify.Notifier
|
var client notify.Notifier
|
||||||
client, err := notification.GetNotificationProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.ClientId2, provider.ClientSecret2, provider.AppId, provider.Receiver, provider.Method, provider.Title, provider.Metadata)
|
client, err := notification.GetNotificationProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.ClientId2, provider.ClientSecret2, provider.AppId, provider.Receiver, provider.Method, provider.Title, provider.Metadata, provider.RegionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,8 @@ type Organization struct {
|
|||||||
Tags []string `xorm:"mediumtext" json:"tags"`
|
Tags []string `xorm:"mediumtext" json:"tags"`
|
||||||
Languages []string `xorm:"varchar(255)" json:"languages"`
|
Languages []string `xorm:"varchar(255)" json:"languages"`
|
||||||
ThemeData *ThemeData `xorm:"json" json:"themeData"`
|
ThemeData *ThemeData `xorm:"json" json:"themeData"`
|
||||||
MasterPassword string `xorm:"varchar(100)" json:"masterPassword"`
|
MasterPassword string `xorm:"varchar(200)" json:"masterPassword"`
|
||||||
DefaultPassword string `xorm:"varchar(100)" json:"defaultPassword"`
|
DefaultPassword string `xorm:"varchar(200)" json:"defaultPassword"`
|
||||||
MasterVerificationCode string `xorm:"varchar(100)" json:"masterVerificationCode"`
|
MasterVerificationCode string `xorm:"varchar(100)" json:"masterVerificationCode"`
|
||||||
IpWhitelist string `xorm:"varchar(200)" json:"ipWhitelist"`
|
IpWhitelist string `xorm:"varchar(200)" json:"ipWhitelist"`
|
||||||
InitScore int `json:"initScore"`
|
InitScore int `json:"initScore"`
|
||||||
|
@ -16,6 +16,7 @@ package object
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/beego/beego/context"
|
"github.com/beego/beego/context"
|
||||||
@ -70,6 +71,7 @@ type Provider struct {
|
|||||||
IdP string `xorm:"mediumtext" json:"idP"`
|
IdP string `xorm:"mediumtext" json:"idP"`
|
||||||
IssuerUrl string `xorm:"varchar(100)" json:"issuerUrl"`
|
IssuerUrl string `xorm:"varchar(100)" json:"issuerUrl"`
|
||||||
EnableSignAuthnRequest bool `json:"enableSignAuthnRequest"`
|
EnableSignAuthnRequest bool `json:"enableSignAuthnRequest"`
|
||||||
|
EmailRegex string `xorm:"varchar(200)" json:"emailRegex"`
|
||||||
|
|
||||||
ProviderUrl string `xorm:"varchar(200)" json:"providerUrl"`
|
ProviderUrl string `xorm:"varchar(200)" json:"providerUrl"`
|
||||||
}
|
}
|
||||||
@ -200,6 +202,13 @@ func UpdateProvider(id string, provider *Provider) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if provider.EmailRegex != "" {
|
||||||
|
_, err := regexp.Compile(provider.EmailRegex)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if name != provider.Name {
|
if name != provider.Name {
|
||||||
err := providerChangeTrigger(name, provider.Name)
|
err := providerChangeTrigger(name, provider.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -234,6 +243,13 @@ func AddProvider(provider *Provider) (bool, error) {
|
|||||||
provider.IntranetEndpoint = util.GetEndPoint(provider.IntranetEndpoint)
|
provider.IntranetEndpoint = util.GetEndPoint(provider.IntranetEndpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if provider.EmailRegex != "" {
|
||||||
|
_, err := regexp.Compile(provider.EmailRegex)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
affected, err := ormer.Engine.Insert(provider)
|
affected, err := ormer.Engine.Insert(provider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -421,7 +437,7 @@ func FromProviderToIdpInfo(ctx *context.Context, provider *Provider) *idp.Provid
|
|||||||
providerInfo.ClientId = provider.ClientId2
|
providerInfo.ClientId = provider.ClientId2
|
||||||
providerInfo.ClientSecret = provider.ClientSecret2
|
providerInfo.ClientSecret = provider.ClientSecret2
|
||||||
}
|
}
|
||||||
} else if provider.Type == "AzureAD" || provider.Type == "AzureADB2C" || provider.Type == "ADFS" || provider.Type == "Okta" {
|
} else if provider.Type == "ADFS" || provider.Type == "AzureAD" || provider.Type == "AzureADB2C" || provider.Type == "Casdoor" || provider.Type == "Okta" {
|
||||||
providerInfo.HostUrl = provider.Domain
|
providerInfo.HostUrl = provider.Domain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ var (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
logPostOnly = conf.GetConfigBool("logPostOnly")
|
logPostOnly = conf.GetConfigBool("logPostOnly")
|
||||||
passwordRegex = regexp.MustCompile("\"password\":\".+\"")
|
passwordRegex = regexp.MustCompile("\"password\":\"([^\"]*?)\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
type Record struct {
|
type Record struct {
|
||||||
|
@ -338,6 +338,10 @@ func roleChangeTrigger(oldName string, newName string) error {
|
|||||||
|
|
||||||
for _, role := range roles {
|
for _, role := range roles {
|
||||||
for j, u := range role.Roles {
|
for j, u := range role.Roles {
|
||||||
|
if u == "*" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
owner, name := util.GetOwnerAndNameFromId(u)
|
owner, name := util.GetOwnerAndNameFromId(u)
|
||||||
if name == oldName {
|
if name == oldName {
|
||||||
role.Roles[j] = util.GetId(owner, newName)
|
role.Roles[j] = util.GetId(owner, newName)
|
||||||
@ -358,6 +362,10 @@ func roleChangeTrigger(oldName string, newName string) error {
|
|||||||
for _, permission := range permissions {
|
for _, permission := range permissions {
|
||||||
for j, u := range permission.Roles {
|
for j, u := range permission.Roles {
|
||||||
// u = organization/username
|
// u = organization/username
|
||||||
|
if u == "*" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
owner, name := util.GetOwnerAndNameFromId(u)
|
owner, name := util.GetOwnerAndNameFromId(u)
|
||||||
if name == oldName {
|
if name == oldName {
|
||||||
permission.Roles[j] = util.GetId(owner, newName)
|
permission.Roles[j] = util.GetId(owner, newName)
|
||||||
|
@ -338,6 +338,9 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
|||||||
} else if authnRequest.AssertionConsumerServiceURL == "" {
|
} else if authnRequest.AssertionConsumerServiceURL == "" {
|
||||||
return "", "", "", fmt.Errorf("err: SAML request don't has attribute 'AssertionConsumerServiceURL' in <samlp:AuthnRequest>")
|
return "", "", "", fmt.Errorf("err: SAML request don't has attribute 'AssertionConsumerServiceURL' in <samlp:AuthnRequest>")
|
||||||
}
|
}
|
||||||
|
if authnRequest.ProtocolBinding == "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" {
|
||||||
|
method = "POST"
|
||||||
|
}
|
||||||
|
|
||||||
_, originBackend := getOriginFromHost(host)
|
_, originBackend := getOriginFromHost(host)
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -184,6 +185,15 @@ func StoreCasTokenForProxyTicket(token *CasAuthenticationSuccess, targetService,
|
|||||||
return proxyTicket
|
return proxyTicket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func escapeXMLText(input string) (string, error) {
|
||||||
|
var sb strings.Builder
|
||||||
|
err := xml.EscapeText(&sb, []byte(input))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return sb.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func GenerateCasToken(userId string, service string) (string, error) {
|
func GenerateCasToken(userId string, service string) (string, error) {
|
||||||
user, err := GetUser(userId)
|
user, err := GetUser(userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -225,6 +235,11 @@ func GenerateCasToken(userId string, service string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if value != "" {
|
if value != "" {
|
||||||
|
if escapedValue, err := escapeXMLText(value); err != nil {
|
||||||
|
return "", err
|
||||||
|
} else {
|
||||||
|
value = escapedValue
|
||||||
|
}
|
||||||
authenticationSuccess.Attributes.UserAttributes.Attributes = append(authenticationSuccess.Attributes.UserAttributes.Attributes, &CasNamedAttribute{
|
authenticationSuccess.Attributes.UserAttributes.Attributes = append(authenticationSuccess.Attributes.UserAttributes.Attributes, &CasNamedAttribute{
|
||||||
Name: k,
|
Name: k,
|
||||||
Value: value,
|
Value: value,
|
||||||
|
@ -309,22 +309,29 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var oldTokenScope string
|
||||||
if application.TokenFormat == "JWT-Standard" {
|
if application.TokenFormat == "JWT-Standard" {
|
||||||
_, err = ParseStandardJwtToken(refreshToken, cert)
|
oldToken, err := ParseStandardJwtToken(refreshToken, cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &TokenError{
|
return &TokenError{
|
||||||
Error: InvalidGrant,
|
Error: InvalidGrant,
|
||||||
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
oldTokenScope = oldToken.Scope
|
||||||
} else {
|
} else {
|
||||||
_, err = ParseJwtToken(refreshToken, cert)
|
oldToken, err := ParseJwtToken(refreshToken, cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &TokenError{
|
return &TokenError{
|
||||||
Error: InvalidGrant,
|
Error: InvalidGrant,
|
||||||
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
oldTokenScope = oldToken.Scope
|
||||||
|
}
|
||||||
|
|
||||||
|
if scope == "" {
|
||||||
|
scope = oldTokenScope
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a new token
|
// generate a new token
|
||||||
@ -504,7 +511,7 @@ func GetPasswordToken(application *Application, username string, password string
|
|||||||
}
|
}
|
||||||
|
|
||||||
if user.Ldap != "" {
|
if user.Ldap != "" {
|
||||||
err = checkLdapUserPassword(user, password, "en")
|
err = CheckLdapUserPassword(user, password, "en")
|
||||||
} else {
|
} else {
|
||||||
err = CheckPassword(user, password, "en")
|
err = CheckPassword(user, password, "en")
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,7 @@ type User struct {
|
|||||||
Bilibili string `xorm:"bilibili varchar(100)" json:"bilibili"`
|
Bilibili string `xorm:"bilibili varchar(100)" json:"bilibili"`
|
||||||
Okta string `xorm:"okta varchar(100)" json:"okta"`
|
Okta string `xorm:"okta varchar(100)" json:"okta"`
|
||||||
Douyin string `xorm:"douyin varchar(100)" json:"douyin"`
|
Douyin string `xorm:"douyin varchar(100)" json:"douyin"`
|
||||||
|
Kwai string `xorm:"kwai varchar(100)" json:"kwai"`
|
||||||
Line string `xorm:"line varchar(100)" json:"line"`
|
Line string `xorm:"line varchar(100)" json:"line"`
|
||||||
Amazon string `xorm:"amazon varchar(100)" json:"amazon"`
|
Amazon string `xorm:"amazon varchar(100)" json:"amazon"`
|
||||||
Auth0 string `xorm:"auth0 varchar(100)" json:"auth0"`
|
Auth0 string `xorm:"auth0 varchar(100)" json:"auth0"`
|
||||||
@ -237,6 +238,7 @@ type MfaAccount struct {
|
|||||||
AccountName string `xorm:"varchar(100)" json:"accountName"`
|
AccountName string `xorm:"varchar(100)" json:"accountName"`
|
||||||
Issuer string `xorm:"varchar(100)" json:"issuer"`
|
Issuer string `xorm:"varchar(100)" json:"issuer"`
|
||||||
SecretKey string `xorm:"varchar(100)" json:"secretKey"`
|
SecretKey string `xorm:"varchar(100)" json:"secretKey"`
|
||||||
|
Origin string `xorm:"varchar(100)" json:"origin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FaceId struct {
|
type FaceId struct {
|
||||||
@ -679,6 +681,10 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
|
|||||||
user.Password = oldUser.Password
|
user.Password = oldUser.Password
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if user.Id != oldUser.Id && user.Id == "" {
|
||||||
|
user.Id = oldUser.Id
|
||||||
|
}
|
||||||
|
|
||||||
if user.Avatar != oldUser.Avatar && user.Avatar != "" && user.PermanentAvatar != "*" {
|
if user.Avatar != oldUser.Avatar && user.Avatar != "" && user.PermanentAvatar != "*" {
|
||||||
user.PermanentAvatar, err = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, false)
|
user.PermanentAvatar, err = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -693,7 +699,7 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
|
|||||||
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts", "face_ids", "mfaAccounts",
|
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts", "face_ids", "mfaAccounts",
|
||||||
"signin_wrong_times", "last_change_password_time", "last_signin_wrong_time", "groups", "access_key", "access_secret", "mfa_phone_enabled", "mfa_email_enabled",
|
"signin_wrong_times", "last_change_password_time", "last_signin_wrong_time", "groups", "access_key", "access_secret", "mfa_phone_enabled", "mfa_email_enabled",
|
||||||
"github", "google", "qq", "wechat", "facebook", "dingtalk", "weibo", "gitee", "linkedin", "wecom", "lark", "gitlab", "adfs",
|
"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",
|
"baidu", "alipay", "casdoor", "infoflow", "apple", "azuread", "azureadb2c", "slack", "steam", "bilibili", "okta", "douyin", "kwai", "line", "amazon",
|
||||||
"auth0", "battlenet", "bitbucket", "box", "cloudfoundry", "dailymotion", "deezer", "digitalocean", "discord", "dropbox",
|
"auth0", "battlenet", "bitbucket", "box", "cloudfoundry", "dailymotion", "deezer", "digitalocean", "discord", "dropbox",
|
||||||
"eveonline", "fitbit", "gitea", "heroku", "influxcloud", "instagram", "intercom", "kakao", "lastfm", "mailru", "meetup",
|
"eveonline", "fitbit", "gitea", "heroku", "influxcloud", "instagram", "intercom", "kakao", "lastfm", "mailru", "meetup",
|
||||||
"microsoftonline", "naver", "nextcloud", "onedrive", "oura", "patreon", "paypal", "salesforce", "shopify", "soundcloud",
|
"microsoftonline", "naver", "nextcloud", "onedrive", "oura", "patreon", "paypal", "salesforce", "shopify", "soundcloud",
|
||||||
@ -840,11 +846,14 @@ func AddUser(user *User) (bool, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rankingItem := GetAccountItemByName("Ranking", organization)
|
||||||
|
if rankingItem != nil {
|
||||||
count, err := GetUserCount(user.Owner, "", "", "")
|
count, err := GetUserCount(user.Owner, "", "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
user.Ranking = int(count + 1)
|
user.Ranking = int(count + 1)
|
||||||
|
}
|
||||||
|
|
||||||
if user.Groups != nil && len(user.Groups) > 0 {
|
if user.Groups != nil && len(user.Groups) > 0 {
|
||||||
_, err = userEnforcer.UpdateGroupsForUser(user.GetId(), user.Groups)
|
_, err = userEnforcer.UpdateGroupsForUser(user.GetId(), user.Groups)
|
||||||
|
@ -57,7 +57,7 @@ type VerificationRecord struct {
|
|||||||
Receiver string `xorm:"varchar(100) index notnull" json:"receiver"`
|
Receiver string `xorm:"varchar(100) index notnull" json:"receiver"`
|
||||||
Code string `xorm:"varchar(10) notnull" json:"code"`
|
Code string `xorm:"varchar(10) notnull" json:"code"`
|
||||||
Time int64 `xorm:"notnull" json:"time"`
|
Time int64 `xorm:"notnull" json:"time"`
|
||||||
IsUsed bool
|
IsUsed bool `xorm:"notnull" json:"isUsed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsAllowSend(user *User, remoteAddr, recordType string) error {
|
func IsAllowSend(user *User, remoteAddr, recordType string) error {
|
||||||
|
@ -68,8 +68,10 @@ func handleAccessRequest(w radius.ResponseWriter, r *radius.Request) {
|
|||||||
log.Printf("handleAccessRequest() username=%v, org=%v, password=%v", username, organization, password)
|
log.Printf("handleAccessRequest() username=%v, org=%v, password=%v", username, organization, password)
|
||||||
|
|
||||||
if organization == "" {
|
if organization == "" {
|
||||||
w.Write(r.Response(radius.CodeAccessReject))
|
organization = conf.GetConfigString("radiusDefaultOrganization")
|
||||||
return
|
if organization == "" {
|
||||||
|
organization = "built-in"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var user *object.User
|
var user *object.User
|
||||||
|
@ -133,6 +133,11 @@ func StaticFilter(ctx *context.Context) {
|
|||||||
path += urlPath
|
path += urlPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
organizationThemeCookie, err := appendThemeCookie(ctx, urlPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
if strings.Contains(path, "/../") || !util.FileExist(path) {
|
if strings.Contains(path, "/../") || !util.FileExist(path) {
|
||||||
path = webBuildFolder + "/index.html"
|
path = webBuildFolder + "/index.html"
|
||||||
}
|
}
|
||||||
@ -149,13 +154,13 @@ func StaticFilter(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if oldStaticBaseUrl == newStaticBaseUrl {
|
if oldStaticBaseUrl == newStaticBaseUrl {
|
||||||
makeGzipResponse(ctx.ResponseWriter, ctx.Request, path)
|
makeGzipResponse(ctx.ResponseWriter, ctx.Request, path, organizationThemeCookie)
|
||||||
} else {
|
} else {
|
||||||
serveFileWithReplace(ctx.ResponseWriter, ctx.Request, path)
|
serveFileWithReplace(ctx.ResponseWriter, ctx.Request, path, organizationThemeCookie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveFileWithReplace(w http.ResponseWriter, r *http.Request, name string) {
|
func serveFileWithReplace(w http.ResponseWriter, r *http.Request, name string, organizationThemeCookie *OrganizationThemeCookie) {
|
||||||
f, err := os.Open(filepath.Clean(name))
|
f, err := os.Open(filepath.Clean(name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -168,7 +173,13 @@ func serveFileWithReplace(w http.ResponseWriter, r *http.Request, name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
oldContent := util.ReadStringFromPath(name)
|
oldContent := util.ReadStringFromPath(name)
|
||||||
newContent := strings.ReplaceAll(oldContent, oldStaticBaseUrl, newStaticBaseUrl)
|
newContent := oldContent
|
||||||
|
if organizationThemeCookie != nil {
|
||||||
|
newContent = strings.ReplaceAll(newContent, "https://cdn.casbin.org/img/favicon.png", organizationThemeCookie.Favicon)
|
||||||
|
newContent = strings.ReplaceAll(newContent, "<title>Casdoor</title>", fmt.Sprintf("<title>%s</title>", organizationThemeCookie.DisplayName))
|
||||||
|
}
|
||||||
|
|
||||||
|
newContent = strings.ReplaceAll(newContent, oldStaticBaseUrl, newStaticBaseUrl)
|
||||||
|
|
||||||
http.ServeContent(w, r, d.Name(), d.ModTime(), strings.NewReader(newContent))
|
http.ServeContent(w, r, d.Name(), d.ModTime(), strings.NewReader(newContent))
|
||||||
}
|
}
|
||||||
@ -182,14 +193,14 @@ func (w gzipResponseWriter) Write(b []byte) (int, error) {
|
|||||||
return w.Writer.Write(b)
|
return w.Writer.Write(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeGzipResponse(w http.ResponseWriter, r *http.Request, path string) {
|
func makeGzipResponse(w http.ResponseWriter, r *http.Request, path string, organizationThemeCookie *OrganizationThemeCookie) {
|
||||||
if !enableGzip || !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
|
if !enableGzip || !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
|
||||||
serveFileWithReplace(w, r, path)
|
serveFileWithReplace(w, r, path, organizationThemeCookie)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Encoding", "gzip")
|
w.Header().Set("Content-Encoding", "gzip")
|
||||||
gz := gzip.NewWriter(w)
|
gz := gzip.NewWriter(w)
|
||||||
defer gz.Close()
|
defer gz.Close()
|
||||||
gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
|
gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
|
||||||
serveFileWithReplace(gzw, r, path)
|
serveFileWithReplace(gzw, r, path, organizationThemeCookie)
|
||||||
}
|
}
|
||||||
|
134
routers/theme_filter.go
Normal file
134
routers/theme_filter.go
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package routers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/beego/beego/context"
|
||||||
|
"github.com/casdoor/casdoor/object"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OrganizationThemeCookie struct {
|
||||||
|
ThemeData *object.ThemeData
|
||||||
|
LogoUrl string
|
||||||
|
FooterHtml string
|
||||||
|
Favicon string
|
||||||
|
DisplayName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendThemeCookie(ctx *context.Context, urlPath string) (*OrganizationThemeCookie, error) {
|
||||||
|
if urlPath == "/login" {
|
||||||
|
application, err := object.GetDefaultApplication(fmt.Sprintf("admin/built-in"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
organization := application.OrganizationObj
|
||||||
|
if organization == nil {
|
||||||
|
organization, err = object.GetOrganization(fmt.Sprintf("admin/built-in"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if organization != nil {
|
||||||
|
organizationThemeCookie := &OrganizationThemeCookie{
|
||||||
|
application.ThemeData,
|
||||||
|
application.Logo,
|
||||||
|
application.FooterHtml,
|
||||||
|
organization.Favicon,
|
||||||
|
organization.DisplayName,
|
||||||
|
}
|
||||||
|
|
||||||
|
if application.ThemeData != nil {
|
||||||
|
organizationThemeCookie.ThemeData = organization.ThemeData
|
||||||
|
}
|
||||||
|
return organizationThemeCookie, setThemeDataCookie(ctx, organizationThemeCookie)
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(urlPath, "/login/oauth/authorize") {
|
||||||
|
clientId := ctx.Input.Query("client_id")
|
||||||
|
if clientId == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
application, err := object.GetApplicationByClientId(clientId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if application != nil {
|
||||||
|
organization := application.OrganizationObj
|
||||||
|
if organization == nil {
|
||||||
|
organization, err = object.GetOrganization(fmt.Sprintf("admin/%s", application.Owner))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
organizationThemeCookie := &OrganizationThemeCookie{
|
||||||
|
application.ThemeData,
|
||||||
|
application.Logo,
|
||||||
|
application.FooterHtml,
|
||||||
|
organization.Favicon,
|
||||||
|
organization.DisplayName,
|
||||||
|
}
|
||||||
|
|
||||||
|
if application.ThemeData != nil {
|
||||||
|
organizationThemeCookie.ThemeData = organization.ThemeData
|
||||||
|
}
|
||||||
|
return organizationThemeCookie, setThemeDataCookie(ctx, organizationThemeCookie)
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(urlPath, "/login/") {
|
||||||
|
owner := strings.Replace(urlPath, "/login/", "", -1)
|
||||||
|
if owner != "undefined" && owner != "oauth/undefined" {
|
||||||
|
application, err := object.GetDefaultApplication(fmt.Sprintf("admin/%s", owner))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
organization := application.OrganizationObj
|
||||||
|
if organization == nil {
|
||||||
|
organization, err = object.GetOrganization(fmt.Sprintf("admin/%s", owner))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if organization != nil {
|
||||||
|
organizationThemeCookie := &OrganizationThemeCookie{
|
||||||
|
application.ThemeData,
|
||||||
|
application.Logo,
|
||||||
|
application.FooterHtml,
|
||||||
|
organization.Favicon,
|
||||||
|
organization.DisplayName,
|
||||||
|
}
|
||||||
|
|
||||||
|
if application.ThemeData != nil {
|
||||||
|
organizationThemeCookie.ThemeData = organization.ThemeData
|
||||||
|
}
|
||||||
|
return organizationThemeCookie, setThemeDataCookie(ctx, organizationThemeCookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setThemeDataCookie(ctx *context.Context, organizationThemeCookie *OrganizationThemeCookie) error {
|
||||||
|
themeDataString, err := json.Marshal(organizationThemeCookie.ThemeData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ctx.SetCookie("organizationTheme", string(themeDataString))
|
||||||
|
ctx.SetCookie("organizationLogo", organizationThemeCookie.LogoUrl)
|
||||||
|
ctx.SetCookie("organizationFootHtml", organizationThemeCookie.FooterHtml)
|
||||||
|
return nil
|
||||||
|
}
|
21
storage/cucloud_oss.go
Normal file
21
storage/cucloud_oss.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
awss3 "github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
"github.com/casdoor/oss"
|
||||||
|
"github.com/casdoor/oss/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewCUCloudOssStorageProvider(clientId string, clientSecret string, region string, bucket string, endpoint string) oss.StorageInterface {
|
||||||
|
sp := s3.New(&s3.Config{
|
||||||
|
AccessID: clientId,
|
||||||
|
AccessKey: clientSecret,
|
||||||
|
Region: region,
|
||||||
|
Bucket: bucket,
|
||||||
|
Endpoint: endpoint,
|
||||||
|
S3Endpoint: endpoint,
|
||||||
|
ACL: awss3.BucketCannedACLPublicRead,
|
||||||
|
})
|
||||||
|
|
||||||
|
return sp
|
||||||
|
}
|
@ -23,7 +23,10 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin
|
|||||||
case "AWS S3":
|
case "AWS S3":
|
||||||
return NewAwsS3StorageProvider(clientId, clientSecret, region, bucket, endpoint), nil
|
return NewAwsS3StorageProvider(clientId, clientSecret, region, bucket, endpoint), nil
|
||||||
case "MinIO":
|
case "MinIO":
|
||||||
return NewMinIOS3StorageProvider(clientId, clientSecret, "_", bucket, endpoint), nil
|
if region == "" {
|
||||||
|
region = "_"
|
||||||
|
}
|
||||||
|
return NewMinIOS3StorageProvider(clientId, clientSecret, region, bucket, endpoint), nil
|
||||||
case "Aliyun OSS":
|
case "Aliyun OSS":
|
||||||
return NewAliyunOssStorageProvider(clientId, clientSecret, region, bucket, endpoint), nil
|
return NewAliyunOssStorageProvider(clientId, clientSecret, region, bucket, endpoint), nil
|
||||||
case "Tencent Cloud COS":
|
case "Tencent Cloud COS":
|
||||||
@ -38,6 +41,8 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin
|
|||||||
return NewSynologyNasStorageProvider(clientId, clientSecret, endpoint), nil
|
return NewSynologyNasStorageProvider(clientId, clientSecret, endpoint), nil
|
||||||
case "Casdoor":
|
case "Casdoor":
|
||||||
return NewCasdoorStorageProvider(providerType, clientId, clientSecret, region, bucket, endpoint, cert, content), nil
|
return NewCasdoorStorageProvider(providerType, clientId, clientSecret, region, bucket, endpoint, cert, content), nil
|
||||||
|
case "CUCloud OSS":
|
||||||
|
return NewCUCloudOssStorageProvider(clientId, clientSecret, region, bucket, endpoint), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -7558,6 +7558,9 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64"
|
"format": "int64"
|
||||||
},
|
},
|
||||||
|
"kwai": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -4981,6 +4981,8 @@ definitions:
|
|||||||
karma:
|
karma:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
kwai:
|
||||||
|
type: string
|
||||||
language:
|
language:
|
||||||
type: string
|
type: string
|
||||||
lark:
|
lark:
|
||||||
|
97
util/process.go
Normal file
97
util/process.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getPidByPort(port int) (int, error) {
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
cmd = exec.Command("cmd", "/c", "netstat -ano | findstr :"+strconv.Itoa(port))
|
||||||
|
case "darwin", "linux":
|
||||||
|
cmd = exec.Command("lsof", "-t", "-i", ":"+strconv.Itoa(port))
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("unsupported OS: %s", runtime.GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||||
|
if exitErr.ExitCode() == 1 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(string(output), "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
if len(fields) > 0 {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
if fields[1] == "0.0.0.0:"+strconv.Itoa(port) {
|
||||||
|
pid, err := strconv.Atoi(fields[len(fields)-1])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pid, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pid, err := strconv.Atoi(fields[0])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pid, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopOldInstance(port int) error {
|
||||||
|
pid, err := getPidByPort(port)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if pid == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
process, err := os.FindProcess(pid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = process.Kill()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
fmt.Printf("The old instance with pid: %d has been stopped\n", pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
const CracoLessPlugin = require("craco-less");
|
const CracoLessPlugin = require("craco-less");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
devServer: {
|
devServer: {
|
||||||
@ -55,47 +56,42 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
webpack: {
|
webpack: {
|
||||||
configure: {
|
configure: (webpackConfig, { env, paths }) => {
|
||||||
|
paths.appBuild = path.resolve(__dirname, "build-temp");
|
||||||
|
webpackConfig.output.path = path.resolve(__dirname, "build-temp");
|
||||||
|
|
||||||
// ignore webpack warnings by source-map-loader
|
// ignore webpack warnings by source-map-loader
|
||||||
// https://github.com/facebook/create-react-app/pull/11752#issuecomment-1345231546
|
// https://github.com/facebook/create-react-app/pull/11752#issuecomment-1345231546
|
||||||
ignoreWarnings: [
|
webpackConfig.ignoreWarnings = [
|
||||||
function ignoreSourcemapsloaderWarnings(warning) {
|
function ignoreSourcemapsloaderWarnings(warning) {
|
||||||
return (
|
return (
|
||||||
warning.module &&
|
warning.module &&
|
||||||
warning.module.resource.includes('node_modules') &&
|
warning.module.resource.includes("node_modules") &&
|
||||||
warning.details &&
|
warning.details &&
|
||||||
warning.details.includes('source-map-loader')
|
warning.details.includes("source-map-loader")
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
],
|
];
|
||||||
|
|
||||||
// use polyfill Buffer with Webpack 5
|
// use polyfill Buffer with Webpack 5
|
||||||
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
||||||
// https://craco.js.org/docs/configuration/webpack/
|
// https://craco.js.org/docs/configuration/webpack/
|
||||||
resolve: {
|
webpackConfig.resolve.fallback = {
|
||||||
fallback: {
|
buffer: require.resolve("buffer/"),
|
||||||
// "process": require.resolve('process/browser'),
|
process: false,
|
||||||
// "util": require.resolve("util/"),
|
util: false,
|
||||||
// "url": require.resolve("url/"),
|
url: false,
|
||||||
// "zlib": require.resolve("browserify-zlib"),
|
zlib: false,
|
||||||
// "stream": require.resolve("stream-browserify"),
|
stream: false,
|
||||||
// "http": require.resolve("stream-http"),
|
http: false,
|
||||||
// "https": require.resolve("https-browserify"),
|
https: false,
|
||||||
// "assert": require.resolve("assert/"),
|
assert: false,
|
||||||
"buffer": require.resolve('buffer/'),
|
crypto: false,
|
||||||
"process": false,
|
os: false,
|
||||||
"util": false,
|
fs: false,
|
||||||
"url": false,
|
};
|
||||||
"zlib": false,
|
|
||||||
"stream": false,
|
return webpackConfig;
|
||||||
"http": false,
|
},
|
||||||
"https": false,
|
},
|
||||||
"assert": false,
|
|
||||||
"buffer": false,
|
|
||||||
"crypto": false,
|
|
||||||
"os": false,
|
|
||||||
"fs": false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
21
web/mv.js
Normal file
21
web/mv.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const sourceDir = path.join(__dirname, "build-temp");
|
||||||
|
const targetDir = path.join(__dirname, "build");
|
||||||
|
|
||||||
|
if (!fs.existsSync(sourceDir)) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(`Source directory "${sourceDir}" does not exist.`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync(targetDir)) {
|
||||||
|
fs.rmSync(targetDir, {recursive: true, force: true});
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(`Target directory "${targetDir}" has been deleted successfully.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.renameSync(sourceDir, targetDir);
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(`Renamed "${sourceDir}" to "${targetDir}" successfully.`);
|
@ -57,6 +57,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cross-env PORT=7001 craco start",
|
"start": "cross-env PORT=7001 craco start",
|
||||||
"build": "craco build",
|
"build": "craco build",
|
||||||
|
"postbuild": "node mv.js",
|
||||||
"test": "craco test",
|
"test": "craco test",
|
||||||
"eject": "craco eject",
|
"eject": "craco eject",
|
||||||
"crowdin:sync": "crowdin upload && crowdin download",
|
"crowdin:sync": "crowdin upload && crowdin download",
|
||||||
|
@ -36,6 +36,7 @@ const {Footer, Content} = Layout;
|
|||||||
|
|
||||||
import {setTwoToneColor} from "@ant-design/icons";
|
import {setTwoToneColor} from "@ant-design/icons";
|
||||||
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||||
|
import * as Cookie from "cookie";
|
||||||
|
|
||||||
setTwoToneColor("rgb(87,52,211)");
|
setTwoToneColor("rgb(87,52,211)");
|
||||||
|
|
||||||
@ -269,7 +270,9 @@ class App extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFooter() {
|
renderFooter(logo, footerHtml) {
|
||||||
|
logo = logo ?? this.state.logo;
|
||||||
|
footerHtml = footerHtml ?? this.state.application?.footerHtml;
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<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="CasdoorApplicationName" value={this.state.account.signupApplication} />}
|
||||||
@ -280,14 +283,14 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
{
|
{
|
||||||
this.state.application?.footerHtml && this.state.application.footerHtml !== "" ?
|
footerHtml && footerHtml !== "" ?
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div dangerouslySetInnerHTML={{__html: this.state.application.footerHtml}} />
|
<div dangerouslySetInnerHTML={{__html: footerHtml}} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
: (
|
: (
|
||||||
Conf.CustomFooter !== null ? Conf.CustomFooter : (
|
Conf.CustomFooter !== null ? Conf.CustomFooter : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
Powered by <a target="_blank" href="https://casdoor.org" rel="noreferrer"><img style={{paddingBottom: "3px"}} height={"20px"} alt={"Casdoor"} src={this.state.logo} /></a>
|
Powered by <a target="_blank" href="https://casdoor.org" rel="noreferrer"><img style={{paddingBottom: "3px"}} height={"20px"} alt={"Casdoor"} src={logo} /></a>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -308,7 +311,7 @@ class App extends Component {
|
|||||||
AI Assistant
|
AI Assistant
|
||||||
</a>
|
</a>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<a className="custom-link" style={{float: "right", marginTop: "2px"}} target="_blank" rel="noreferrer" href={"https://ai.casbin.com"}>
|
<a className="custom-link" style={{float: "right", marginTop: "2px"}} target="_blank" rel="noreferrer" href={`${Conf.AiAssistantUrl}`}>
|
||||||
<ShareAltOutlined className="custom-link" style={{fontSize: "20px", color: "rgb(140,140,140)"}} />
|
<ShareAltOutlined className="custom-link" style={{fontSize: "20px", color: "rgb(140,140,140)"}} />
|
||||||
</a>
|
</a>
|
||||||
<a className="custom-link" style={{float: "right", marginRight: "30px", marginTop: "2px"}} target="_blank" rel="noreferrer" href={"https://github.com/casibase/casibase"}>
|
<a className="custom-link" style={{float: "right", marginRight: "30px", marginTop: "2px"}} target="_blank" rel="noreferrer" href={"https://github.com/casibase/casibase"}>
|
||||||
@ -326,7 +329,7 @@ class App extends Component {
|
|||||||
}}
|
}}
|
||||||
visible={this.state.isAiAssistantOpen}
|
visible={this.state.isAiAssistantOpen}
|
||||||
>
|
>
|
||||||
<iframe id="iframeHelper" title={"iframeHelper"} src={"https://ai.casbin.com/?isRaw=1"} width="100%" height="100%" scrolling="no" frameBorder="no" />
|
<iframe id="iframeHelper" title={"iframeHelper"} src={`${Conf.AiAssistantUrl}/?isRaw=1`} width="100%" height="100%" scrolling="no" frameBorder="no" />
|
||||||
</Drawer>
|
</Drawer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -360,11 +363,27 @@ class App extends Component {
|
|||||||
|
|
||||||
renderPage() {
|
renderPage() {
|
||||||
if (this.isDoorPages()) {
|
if (this.isDoorPages()) {
|
||||||
|
let themeData = this.state.themeData;
|
||||||
|
let logo = this.state.logo;
|
||||||
|
let footerHtml = null;
|
||||||
|
if (this.state.organization === undefined) {
|
||||||
|
const curCookie = Cookie.parse(document.cookie);
|
||||||
|
if (curCookie["organizationTheme"] && curCookie["organizationTheme"] !== "null") {
|
||||||
|
themeData = JSON.parse(curCookie["organizationTheme"]);
|
||||||
|
}
|
||||||
|
if (curCookie["organizationLogo"] && curCookie["organizationLogo"] !== "") {
|
||||||
|
logo = curCookie["organizationLogo"];
|
||||||
|
}
|
||||||
|
if (curCookie["organizationFootHtml"] && curCookie["organizationFootHtml"] !== "") {
|
||||||
|
footerHtml = curCookie["organizationFootHtml"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigProvider theme={{
|
<ConfigProvider theme={{
|
||||||
token: {
|
token: {
|
||||||
colorPrimary: this.state.themeData.colorPrimary,
|
colorPrimary: themeData.colorPrimary,
|
||||||
borderRadius: this.state.themeData.borderRadius,
|
borderRadius: themeData.borderRadius,
|
||||||
},
|
},
|
||||||
algorithm: Setting.getAlgorithm(this.state.themeAlgorithm),
|
algorithm: Setting.getAlgorithm(this.state.themeAlgorithm),
|
||||||
}}>
|
}}>
|
||||||
@ -401,7 +420,7 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
</Content>
|
</Content>
|
||||||
{
|
{
|
||||||
this.renderFooter()
|
this.renderFooter(logo, footerHtml)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.renderAiAssistant()
|
this.renderAiAssistant()
|
||||||
|
@ -19,6 +19,7 @@ import "codemirror/mode/properties/properties";
|
|||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import IframeEditor from "./IframeEditor";
|
import IframeEditor from "./IframeEditor";
|
||||||
import {Tabs} from "antd";
|
import {Tabs} from "antd";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
const {TabPane} = Tabs;
|
const {TabPane} = Tabs;
|
||||||
|
|
||||||
@ -68,8 +69,8 @@ const CasbinEditor = ({model, onModelTextChange}) => {
|
|||||||
return (
|
return (
|
||||||
<div style={{height: "100%", width: "100%", display: "flex", flexDirection: "column"}}>
|
<div style={{height: "100%", width: "100%", display: "flex", flexDirection: "column"}}>
|
||||||
<Tabs activeKey={activeKey} onChange={handleTabChange} style={{flex: "0 0 auto", marginTop: "-10px"}}>
|
<Tabs activeKey={activeKey} onChange={handleTabChange} style={{flex: "0 0 auto", marginTop: "-10px"}}>
|
||||||
<TabPane tab="Basic Editor" key="basic" />
|
<TabPane tab={i18next.t("model:Basic Editor")} key="basic" />
|
||||||
<TabPane tab="Advanced Editor" key="advanced" />
|
<TabPane tab={i18next.t("model:Advanced Editor")} key="advanced" />
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<div style={{flex: "1 1 auto", overflow: "hidden"}}>
|
<div style={{flex: "1 1 auto", overflow: "hidden"}}>
|
||||||
{activeKey === "advanced" ? (
|
{activeKey === "advanced" ? (
|
||||||
|
@ -31,3 +31,6 @@ export const ThemeDefault = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CustomFooter = null;
|
export const CustomFooter = null;
|
||||||
|
|
||||||
|
// Blank or null to hide Ai Assistant button
|
||||||
|
export const AiAssistantUrl = "https://ai.casbin.com";
|
||||||
|
@ -111,7 +111,7 @@ class EntryPage extends React.Component {
|
|||||||
<div className={`${isDarkMode ? "loginBackgroundDark" : "loginBackground"}`}
|
<div className={`${isDarkMode ? "loginBackgroundDark" : "loginBackground"}`}
|
||||||
style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${this.state.application?.formBackgroundUrl})`}}>
|
style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${this.state.application?.formBackgroundUrl})`}}>
|
||||||
<Spin size="large" spinning={this.state.application === undefined && this.state.pricing === undefined} tip={i18next.t("login:Loading")}
|
<Spin size="large" spinning={this.state.application === undefined && this.state.pricing === undefined} tip={i18next.t("login:Loading")}
|
||||||
style={{margin: "0 auto"}} />
|
style={{width: "100%", margin: "0 auto", position: "absolute"}} />
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...this.props} application={this.state.application} applicationName={authConfig.appName} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
<Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...this.props} application={this.state.application} applicationName={authConfig.appName} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
||||||
<Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
<Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
||||||
|
@ -17,6 +17,7 @@ import React, {forwardRef, useEffect, useImperativeHandle, useRef, useState} fro
|
|||||||
const IframeEditor = forwardRef(({initialModelText, onModelTextChange}, ref) => {
|
const IframeEditor = forwardRef(({initialModelText, onModelTextChange}, ref) => {
|
||||||
const iframeRef = useRef(null);
|
const iframeRef = useRef(null);
|
||||||
const [iframeReady, setIframeReady] = useState(false);
|
const [iframeReady, setIframeReady] = useState(false);
|
||||||
|
const currentLang = localStorage.getItem("language") || "en";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleMessage = (event) => {
|
const handleMessage = (event) => {
|
||||||
@ -26,24 +27,31 @@ const IframeEditor = forwardRef(({initialModelText, onModelTextChange}, ref) =>
|
|||||||
onModelTextChange(event.data.modelText);
|
onModelTextChange(event.data.modelText);
|
||||||
} else if (event.data.type === "iframeReady") {
|
} else if (event.data.type === "iframeReady") {
|
||||||
setIframeReady(true);
|
setIframeReady(true);
|
||||||
iframeRef.current?.contentWindow.postMessage({
|
if (initialModelText && iframeRef.current?.contentWindow) {
|
||||||
|
iframeRef.current.contentWindow.postMessage({
|
||||||
type: "initializeModel",
|
type: "initializeModel",
|
||||||
modelText: initialModelText,
|
modelText: initialModelText,
|
||||||
|
lang: currentLang,
|
||||||
}, "*");
|
}, "*");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("message", handleMessage);
|
window.addEventListener("message", handleMessage);
|
||||||
return () => window.removeEventListener("message", handleMessage);
|
return () => window.removeEventListener("message", handleMessage);
|
||||||
}, [onModelTextChange, initialModelText]);
|
}, [onModelTextChange, initialModelText, currentLang]);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
getModelText: () => {
|
getModelText: () => {
|
||||||
iframeRef.current?.contentWindow.postMessage({type: "getModelText"}, "*");
|
if (iframeRef.current?.contentWindow) {
|
||||||
|
iframeRef.current.contentWindow.postMessage({
|
||||||
|
type: "getModelText",
|
||||||
|
}, "*");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateModelText: (newModelText) => {
|
updateModelText: (newModelText) => {
|
||||||
if (iframeReady) {
|
if (iframeReady && iframeRef.current?.contentWindow) {
|
||||||
iframeRef.current?.contentWindow.postMessage({
|
iframeRef.current.contentWindow.postMessage({
|
||||||
type: "updateModelText",
|
type: "updateModelText",
|
||||||
modelText: newModelText,
|
modelText: newModelText,
|
||||||
}, "*");
|
}, "*");
|
||||||
@ -54,7 +62,7 @@ const IframeEditor = forwardRef(({initialModelText, onModelTextChange}, ref) =>
|
|||||||
return (
|
return (
|
||||||
<iframe
|
<iframe
|
||||||
ref={iframeRef}
|
ref={iframeRef}
|
||||||
src="https://editor.casbin.org/model-editor"
|
src={`https://editor.casbin.org/model-editor?lang=${currentLang}`}
|
||||||
frameBorder="0"
|
frameBorder="0"
|
||||||
width="100%"
|
width="100%"
|
||||||
height="500px"
|
height="500px"
|
||||||
|
@ -106,6 +106,22 @@ class InvitationEditPage extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copySignupLink() {
|
||||||
|
let defaultApplication;
|
||||||
|
if (this.state.invitation.owner === "built-in") {
|
||||||
|
defaultApplication = "app-built-in";
|
||||||
|
} else {
|
||||||
|
const selectedOrganization = Setting.getArrayItem(this.state.organizations, "name", this.state.invitation.owner);
|
||||||
|
defaultApplication = selectedOrganization.defaultApplication;
|
||||||
|
if (!defaultApplication) {
|
||||||
|
Setting.showMessage("error", i18next.t("invitation:You need to specify a default application for ") + selectedOrganization.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copy(`${window.location.origin}/signup/${defaultApplication}?invitationCode=${this.state.invitation?.defaultCode}`);
|
||||||
|
Setting.showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
||||||
|
}
|
||||||
|
|
||||||
renderInvitation() {
|
renderInvitation() {
|
||||||
const isCreatedByPlan = this.state.invitation.tag === "auto_created_invitation_for_plan";
|
const isCreatedByPlan = this.state.invitation.tag === "auto_created_invitation_for_plan";
|
||||||
return (
|
return (
|
||||||
@ -114,16 +130,7 @@ class InvitationEditPage extends React.Component {
|
|||||||
{this.state.mode === "add" ? i18next.t("invitation:New Invitation") : i18next.t("invitation:Edit Invitation")}
|
{this.state.mode === "add" ? i18next.t("invitation:New Invitation") : i18next.t("invitation:Edit Invitation")}
|
||||||
<Button onClick={() => this.submitInvitationEdit(false)}>{i18next.t("general:Save")}</Button>
|
<Button onClick={() => this.submitInvitationEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||||
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitInvitationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitInvitationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||||
<Button style={{marginLeft: "20px"}} onClick={() => {
|
<Button style={{marginLeft: "20px"}} onClick={_ => this.copySignupLink()}>
|
||||||
let defaultApplication;
|
|
||||||
if (this.state.invitation.owner === "built-in") {
|
|
||||||
defaultApplication = "app-built-in";
|
|
||||||
} else {
|
|
||||||
defaultApplication = Setting.getArrayItem(this.state.organizations, "name", this.state.invitation.owner).defaultApplication;
|
|
||||||
}
|
|
||||||
copy(`${window.location.origin}/signup/${defaultApplication}?invitationCode=${this.state.invitation?.defaultCode}`);
|
|
||||||
Setting.showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
|
||||||
}}>
|
|
||||||
{i18next.t("application:Copy signup page URL")}
|
{i18next.t("application:Copy signup page URL")}
|
||||||
</Button>
|
</Button>
|
||||||
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteInvitation()}>{i18next.t("general:Cancel")}</Button> : null}
|
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteInvitation()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||||
@ -330,16 +337,7 @@ class InvitationEditPage extends React.Component {
|
|||||||
<div style={{marginTop: "20px", marginLeft: "40px"}}>
|
<div style={{marginTop: "20px", marginLeft: "40px"}}>
|
||||||
<Button size="large" onClick={() => this.submitInvitationEdit(false)}>{i18next.t("general:Save")}</Button>
|
<Button size="large" onClick={() => this.submitInvitationEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||||
<Button style={{marginLeft: "20px"}} type="primary" size="large" onClick={() => this.submitInvitationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
<Button style={{marginLeft: "20px"}} type="primary" size="large" onClick={() => this.submitInvitationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||||
<Button style={{marginLeft: "20px"}} size="large" onClick={() => {
|
<Button style={{marginLeft: "20px"}} size="large" onClick={_ => this.copySignupLink()}>
|
||||||
let defaultApplication;
|
|
||||||
if (this.state.invitation.owner === "built-in") {
|
|
||||||
defaultApplication = "app-built-in";
|
|
||||||
} else {
|
|
||||||
defaultApplication = Setting.getArrayItem(this.state.organizations, "name", this.state.invitation.owner).defaultApplication;
|
|
||||||
}
|
|
||||||
copy(`${window.location.origin}/signup/${defaultApplication}?invitationCode=${this.state.invitation?.defaultCode}`);
|
|
||||||
Setting.showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
|
||||||
}}>
|
|
||||||
{i18next.t("application:Copy signup page URL")}
|
{i18next.t("application:Copy signup page URL")}
|
||||||
</Button>
|
</Button>
|
||||||
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} size="large" onClick={() => this.deleteInvitation()}>{i18next.t("general:Cancel")}</Button> : null}
|
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} size="large" onClick={() => this.deleteInvitation()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||||
|
@ -228,6 +228,21 @@ class LdapEditPage extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{lineHeight: "32px", textAlign: "right", paddingRight: "25px"}} span={3}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Password type"), i18next.t("general:Password type - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={21}>
|
||||||
|
<Select virtual={false} style={{width: "100%"}} value={this.state.ldap.passwordType ?? []} onChange={(value => {
|
||||||
|
this.updateLdapField("passwordType", value);
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Option key={"Plain"} value={"Plain"}>{i18next.t("general:Plain")}</Option>
|
||||||
|
<Option key={"SSHA"} value={"SSHA"} >SSHA</Option>
|
||||||
|
<Option key={"MD5"} value={"MD5"} >MD5</Option>
|
||||||
|
</Select>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{lineHeight: "32px", textAlign: "right", paddingRight: "25px"}} span={3}>
|
<Col style={{lineHeight: "32px", textAlign: "right", paddingRight: "25px"}} span={3}>
|
||||||
{Setting.getLabel(i18next.t("ldap:Default group"), i18next.t("ldap:Default group - Tooltip"))} :
|
{Setting.getLabel(i18next.t("ldap:Default group"), i18next.t("ldap:Default group - Tooltip"))} :
|
||||||
|
@ -192,11 +192,15 @@ function ManagementPage(props) {
|
|||||||
themeAlgorithm={props.themeAlgorithm}
|
themeAlgorithm={props.themeAlgorithm}
|
||||||
onChange={props.setLogoAndThemeAlgorithm} />
|
onChange={props.setLogoAndThemeAlgorithm} />
|
||||||
<LanguageSelect languages={props.account.organization.languages} />
|
<LanguageSelect languages={props.account.organization.languages} />
|
||||||
<Tooltip title="Click to open AI assitant">
|
{
|
||||||
|
Conf.AiAssistantUrl?.trim() && (
|
||||||
|
<Tooltip title="Click to open AI assistant">
|
||||||
<div className="select-box" onClick={props.openAiAssistant}>
|
<div className="select-box" onClick={props.openAiAssistant}>
|
||||||
<DeploymentUnitOutlined style={{fontSize: "24px"}} />
|
<DeploymentUnitOutlined style={{fontSize: "24px"}} />
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
)
|
||||||
|
}
|
||||||
<OpenTour />
|
<OpenTour />
|
||||||
{Setting.isAdminUser(props.account) && (props.uri.indexOf("/trees") === -1) &&
|
{Setting.isAdminUser(props.account) && (props.uri.indexOf("/trees") === -1) &&
|
||||||
<OrganizationSelect
|
<OrganizationSelect
|
||||||
|
@ -297,6 +297,8 @@ class ProviderEditPage extends React.Component {
|
|||||||
return Setting.getLabel(i18next.t("provider:Scene"), i18next.t("provider:Scene - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Scene"), i18next.t("provider:Scene - Tooltip"));
|
||||||
} else if (provider.type === "WeChat Pay") {
|
} else if (provider.type === "WeChat Pay") {
|
||||||
return Setting.getLabel(i18next.t("provider:App ID"), i18next.t("provider:App ID - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:App ID"), i18next.t("provider:App ID - Tooltip"));
|
||||||
|
} else if (provider.type === "CUCloud") {
|
||||||
|
return Setting.getLabel(i18next.t("provider:Account ID"), i18next.t("provider:Account ID - Tooltip"));
|
||||||
} else {
|
} else {
|
||||||
return Setting.getLabel(i18next.t("provider:Client ID 2"), i18next.t("provider:Client ID 2 - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Client ID 2"), i18next.t("provider:Client ID 2 - Tooltip"));
|
||||||
}
|
}
|
||||||
@ -393,6 +395,9 @@ class ProviderEditPage extends React.Component {
|
|||||||
} else if (provider.type === "Line" || provider.type === "Matrix" || provider.type === "Rocket Chat") {
|
} else if (provider.type === "Line" || provider.type === "Matrix" || provider.type === "Rocket Chat") {
|
||||||
text = i18next.t("provider:App Key");
|
text = i18next.t("provider:App Key");
|
||||||
tooltip = i18next.t("provider:App Key - Tooltip");
|
tooltip = i18next.t("provider:App Key - Tooltip");
|
||||||
|
} else if (provider.type === "CUCloud") {
|
||||||
|
text = i18next.t("provider:Topic name");
|
||||||
|
tooltip = i18next.t("provider:Topic name - Tooltip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,6 +638,20 @@ class ProviderEditPage extends React.Component {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
this.state.provider.category === "OAuth" ? (
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("provider:Email regex"), i18next.t("provider:Email regex - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22}>
|
||||||
|
<TextArea rows={4} value={this.state.provider.emailRegex} onChange={e => {
|
||||||
|
this.updateProviderField("emailRegex", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
{
|
{
|
||||||
this.state.provider.type === "Custom" ? (
|
this.state.provider.type === "Custom" ? (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
@ -757,7 +776,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.state.provider.category !== "Email" && this.state.provider.type !== "WeChat" && this.state.provider.type !== "Apple" && this.state.provider.type !== "Aliyun Captcha" && this.state.provider.type !== "WeChat Pay" && this.state.provider.type !== "Twitter" && this.state.provider.type !== "Reddit" ? null : (
|
this.state.provider.category !== "Email" && this.state.provider.type !== "WeChat" && this.state.provider.type !== "Apple" && this.state.provider.type !== "Aliyun Captcha" && this.state.provider.type !== "WeChat Pay" && this.state.provider.type !== "Twitter" && this.state.provider.type !== "Reddit" && this.state.provider.type !== "CUCloud" ? null : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
@ -770,7 +789,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{
|
{
|
||||||
(this.state.provider.type === "WeChat Pay") || (this.state.provider.category === "Email" && (this.state.provider.type === "Azure ACS" || this.state.provider.type === "SendGrid")) ? null : (
|
(this.state.provider.type === "WeChat Pay" || this.state.provider.type === "CUCloud") || (this.state.provider.category === "Email" && (this.state.provider.type === "Azure ACS" || this.state.provider.type === "SendGrid")) ? null : (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{this.getClientSecret2Label(this.state.provider)} :
|
{this.getClientSecret2Label(this.state.provider)} :
|
||||||
@ -856,9 +875,9 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{this.state.provider.category === "Storage" || ["Custom HTTP SMS", "Custom HTTP Email"].includes(this.state.provider.type) ? (
|
{this.state.provider.category === "Storage" || ["Custom HTTP SMS", "Custom HTTP Email", "CUCloud"].includes(this.state.provider.type) ? (
|
||||||
<div>
|
<div>
|
||||||
{["Local File System"].includes(this.state.provider.type) ? null : (
|
{["Local File System", "CUCloud"].includes(this.state.provider.type) ? null : (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Endpoint"), i18next.t("provider:Region endpoint for Internet"))} :
|
{Setting.getLabel(i18next.t("provider:Endpoint"), i18next.t("provider:Region endpoint for Internet"))} :
|
||||||
@ -870,7 +889,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
{["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : (
|
{["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology", "Casdoor", "CUCloud"].includes(this.state.provider.type) ? null : (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
||||||
@ -882,7 +901,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
{["Custom HTTP SMS", "Local File System"].includes(this.state.provider.type) ? null : (
|
{["Custom HTTP SMS", "Local File System", "CUCloud"].includes(this.state.provider.type) ? null : (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{["Casdoor"].includes(this.state.provider.type) ?
|
{["Casdoor"].includes(this.state.provider.type) ?
|
||||||
@ -896,7 +915,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
{["Custom HTTP SMS"].includes(this.state.provider.type) ? null : (
|
{["Custom HTTP SMS", "CUCloud"].includes(this.state.provider.type) ? null : (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Path prefix"), i18next.t("provider:Path prefix - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:Path prefix"), i18next.t("provider:Path prefix - Tooltip"))} :
|
||||||
@ -908,7 +927,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
{["Custom HTTP SMS", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : (
|
{["Custom HTTP SMS", "Synology", "Casdoor", "CUCloud"].includes(this.state.provider.type) ? null : (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||||
@ -932,7 +951,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
) : null}
|
) : null}
|
||||||
{["AWS S3", "Tencent Cloud COS", "Qiniu Cloud Kodo", "Casdoor"].includes(this.state.provider.type) ? (
|
{["AWS S3", "Tencent Cloud COS", "Qiniu Cloud Kodo", "Casdoor", "CUCloud OSS", "MinIO", "CUCloud"].includes(this.state.provider.type) ? (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={2}>
|
<Col style={{marginTop: "5px"}} span={2}>
|
||||||
{["Casdoor"].includes(this.state.provider.type) ?
|
{["Casdoor"].includes(this.state.provider.type) ?
|
||||||
@ -971,7 +990,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
) : null}
|
) : null}
|
||||||
{["Custom HTTP"].includes(this.state.provider.type) ? (
|
{["Custom HTTP", "CUCloud"].includes(this.state.provider.type) ? (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Parameter"), i18next.t("provider:Parameter - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:Parameter"), i18next.t("provider:Parameter - Tooltip"))} :
|
||||||
@ -983,7 +1002,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
) : null}
|
) : null}
|
||||||
{["Google Chat"].includes(this.state.provider.type) ? (
|
{["Google Chat", "CUCloud"].includes(this.state.provider.type) ? (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("provider:Metadata"), i18next.t("provider:Metadata - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:Metadata"), i18next.t("provider:Metadata - Tooltip"))} :
|
||||||
|
@ -233,6 +233,10 @@ export const OtherProviderInfo = {
|
|||||||
logo: `${StaticBaseUrl}/img/casdoor.png`,
|
logo: `${StaticBaseUrl}/img/casdoor.png`,
|
||||||
url: "https://casdoor.org/docs/provider/storage/overview",
|
url: "https://casdoor.org/docs/provider/storage/overview",
|
||||||
},
|
},
|
||||||
|
"CUCloud OSS": {
|
||||||
|
logo: `${StaticBaseUrl}/img/social_cucloud.png`,
|
||||||
|
url: "https://www.cucloud.cn/product/oss.html",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
SAML: {
|
SAML: {
|
||||||
"Aliyun IDaaS": {
|
"Aliyun IDaaS": {
|
||||||
@ -401,6 +405,10 @@ export const OtherProviderInfo = {
|
|||||||
logo: `${StaticBaseUrl}/img/social_viber.png`,
|
logo: `${StaticBaseUrl}/img/social_viber.png`,
|
||||||
url: "https://www.viber.com/",
|
url: "https://www.viber.com/",
|
||||||
},
|
},
|
||||||
|
"CUCloud": {
|
||||||
|
logo: `${StaticBaseUrl}/img/cucloud.png`,
|
||||||
|
url: "https://www.cucloud.cn/",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -920,7 +928,7 @@ export function getClickable(text) {
|
|||||||
return (
|
return (
|
||||||
<a onClick={() => {
|
<a onClick={() => {
|
||||||
copy(text);
|
copy(text);
|
||||||
showMessage("success", "Copied to clipboard");
|
showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
||||||
}}>
|
}}>
|
||||||
{text}
|
{text}
|
||||||
</a>
|
</a>
|
||||||
@ -981,6 +989,7 @@ export function getProviderTypeOptions(category) {
|
|||||||
{id: "Bilibili", name: "Bilibili"},
|
{id: "Bilibili", name: "Bilibili"},
|
||||||
{id: "Okta", name: "Okta"},
|
{id: "Okta", name: "Okta"},
|
||||||
{id: "Douyin", name: "Douyin"},
|
{id: "Douyin", name: "Douyin"},
|
||||||
|
{id: "Kwai", name: "Kwai"},
|
||||||
{id: "Line", name: "Line"},
|
{id: "Line", name: "Line"},
|
||||||
{id: "Amazon", name: "Amazon"},
|
{id: "Amazon", name: "Amazon"},
|
||||||
{id: "Auth0", name: "Auth0"},
|
{id: "Auth0", name: "Auth0"},
|
||||||
@ -1078,6 +1087,7 @@ export function getProviderTypeOptions(category) {
|
|||||||
{id: "Google Cloud Storage", name: "Google Cloud Storage"},
|
{id: "Google Cloud Storage", name: "Google Cloud Storage"},
|
||||||
{id: "Synology", name: "Synology"},
|
{id: "Synology", name: "Synology"},
|
||||||
{id: "Casdoor", name: "Casdoor"},
|
{id: "Casdoor", name: "Casdoor"},
|
||||||
|
{id: "CUCloud OSS", name: "CUCloud OSS"},
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
} else if (category === "SAML") {
|
} else if (category === "SAML") {
|
||||||
@ -1131,6 +1141,7 @@ export function getProviderTypeOptions(category) {
|
|||||||
{id: "Reddit", name: "Reddit"},
|
{id: "Reddit", name: "Reddit"},
|
||||||
{id: "Rocket Chat", name: "Rocket Chat"},
|
{id: "Rocket Chat", name: "Rocket Chat"},
|
||||||
{id: "Viber", name: "Viber"},
|
{id: "Viber", name: "Viber"},
|
||||||
|
{id: "CUCloud", name: "CUCloud"},
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
@ -1171,7 +1182,7 @@ export function renderLogo(application) {
|
|||||||
|
|
||||||
function isSigninMethodEnabled(application, signinMethod) {
|
function isSigninMethodEnabled(application, signinMethod) {
|
||||||
if (application && application.signinMethods) {
|
if (application && application.signinMethods) {
|
||||||
return application.signinMethods.filter(item => item.name === signinMethod && item.rule !== "Hide-Password").length > 0;
|
return application.signinMethods.filter(item => item.name === signinMethod && item.rule !== "Hide password").length > 0;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1550,25 +1561,25 @@ export function getDefaultHtmlEmailContent() {
|
|||||||
|
|
||||||
export function getCurrencyText(product) {
|
export function getCurrencyText(product) {
|
||||||
if (product?.currency === "USD") {
|
if (product?.currency === "USD") {
|
||||||
return i18next.t("product:USD");
|
return i18next.t("currency:USD");
|
||||||
} else if (product?.currency === "CNY") {
|
} else if (product?.currency === "CNY") {
|
||||||
return i18next.t("product:CNY");
|
return i18next.t("currency:CNY");
|
||||||
} else if (product?.currency === "EUR") {
|
} else if (product?.currency === "EUR") {
|
||||||
return i18next.t("product:EUR");
|
return i18next.t("currency:EUR");
|
||||||
} else if (product?.currency === "JPY") {
|
} else if (product?.currency === "JPY") {
|
||||||
return i18next.t("product:JPY");
|
return i18next.t("currency:JPY");
|
||||||
} else if (product?.currency === "GBP") {
|
} else if (product?.currency === "GBP") {
|
||||||
return i18next.t("product:GBP");
|
return i18next.t("currency:GBP");
|
||||||
} else if (product?.currency === "AUD") {
|
} else if (product?.currency === "AUD") {
|
||||||
return i18next.t("product:AUD");
|
return i18next.t("currency:AUD");
|
||||||
} else if (product?.currency === "CAD") {
|
} else if (product?.currency === "CAD") {
|
||||||
return i18next.t("product:CAD");
|
return i18next.t("currency:CAD");
|
||||||
} else if (product?.currency === "CHF") {
|
} else if (product?.currency === "CHF") {
|
||||||
return i18next.t("product:CHF");
|
return i18next.t("currency:CHF");
|
||||||
} else if (product?.currency === "HKD") {
|
} else if (product?.currency === "HKD") {
|
||||||
return i18next.t("product:HKD");
|
return i18next.t("currency:HKD");
|
||||||
} else if (product?.currency === "SGD") {
|
} else if (product?.currency === "SGD") {
|
||||||
return i18next.t("product:SGD");
|
return i18next.t("currency:SGD");
|
||||||
} else {
|
} else {
|
||||||
return "(Unknown currency)";
|
return "(Unknown currency)";
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ class AuthCallback extends React.Component {
|
|||||||
}
|
}
|
||||||
const SAMLResponse = res.data;
|
const SAMLResponse = res.data;
|
||||||
const redirectUri = res.data2.redirectUrl;
|
const redirectUri = res.data2.redirectUrl;
|
||||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
Setting.goToLink(`${redirectUri}${redirectUri.includes("?") ? "&" : "?"}SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
31
web/src/auth/KwaiLoginButton.js
Normal file
31
web/src/auth/KwaiLoginButton.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// 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 {createButton} from "react-social-login-buttons";
|
||||||
|
import {StaticBaseUrl} from "../Setting";
|
||||||
|
|
||||||
|
function Icon({width = 24, height = 24}) {
|
||||||
|
return <img src={`${StaticBaseUrl}/buttons/kwai.svg`} alt="Sign in with Kwai" style={{width: width, height: height}} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
text: "Sign in with Kwai",
|
||||||
|
icon: Icon,
|
||||||
|
style: {background: "#ffffff", color: "#000000"},
|
||||||
|
activeStyle: {background: "#ededee"},
|
||||||
|
};
|
||||||
|
|
||||||
|
const KwaiLoginButton = createButton(config);
|
||||||
|
|
||||||
|
export default KwaiLoginButton;
|
@ -37,6 +37,7 @@ import RedirectForm from "../common/RedirectForm";
|
|||||||
import {MfaAuthVerifyForm, NextMfa, RequiredMfa} from "./mfa/MfaAuthVerifyForm";
|
import {MfaAuthVerifyForm, NextMfa, RequiredMfa} from "./mfa/MfaAuthVerifyForm";
|
||||||
import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
|
import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
|
||||||
import * as ProviderButton from "./ProviderButton";
|
import * as ProviderButton from "./ProviderButton";
|
||||||
|
import {EmailMfaType, SmsMfaType, TotpMfaType} from "./MfaSetupPage";
|
||||||
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
|
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
|
||||||
|
|
||||||
class LoginPage extends React.Component {
|
class LoginPage extends React.Component {
|
||||||
@ -440,19 +441,12 @@ class LoginPage extends React.Component {
|
|||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
if (res.data === NextMfa) {
|
if (res.data === NextMfa) {
|
||||||
this.setState({
|
this.setState({
|
||||||
getVerifyTotp: () => {
|
mfaProps: res.data2,
|
||||||
return (
|
selectedMfaProp: this.getPreferredMfaProp(res.data2),
|
||||||
<MfaAuthVerifyForm
|
}, () => {
|
||||||
mfaProps={res.data2}
|
this.setState({
|
||||||
formValues={values}
|
getVerifyTotp: () => this.renderMfaAuthVerifyForm(values, casParams, loginHandler),
|
||||||
authParams={casParams}
|
});
|
||||||
application={this.getApplicationObj()}
|
|
||||||
onFail={(errorMessage) => {
|
|
||||||
Setting.showMessage("error", errorMessage);
|
|
||||||
}}
|
|
||||||
onSuccess={(res) => loginHandler(res)}
|
|
||||||
/>);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
loginHandler(res);
|
loginHandler(res);
|
||||||
@ -505,7 +499,7 @@ class LoginPage extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
const SAMLResponse = res.data;
|
const SAMLResponse = res.data;
|
||||||
const redirectUri = res.data2.redirectUrl;
|
const redirectUri = res.data2.redirectUrl;
|
||||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
Setting.goToLink(`${redirectUri}${redirectUri.includes("?") ? "&" : "?"}SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -513,19 +507,12 @@ class LoginPage extends React.Component {
|
|||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
if (res.data === NextMfa) {
|
if (res.data === NextMfa) {
|
||||||
this.setState({
|
this.setState({
|
||||||
getVerifyTotp: () => {
|
mfaProps: res.data2,
|
||||||
return (
|
selectedMfaProp: this.getPreferredMfaProp(res.data2),
|
||||||
<MfaAuthVerifyForm
|
}, () => {
|
||||||
mfaProps={res.data2}
|
this.setState({
|
||||||
formValues={values}
|
getVerifyTotp: () => this.renderMfaAuthVerifyForm(values, oAuthParams, loginHandler),
|
||||||
authParams={oAuthParams}
|
});
|
||||||
application={this.getApplicationObj()}
|
|
||||||
onFail={(errorMessage) => {
|
|
||||||
Setting.showMessage("error", errorMessage);
|
|
||||||
}}
|
|
||||||
onSuccess={(res) => loginHandler(res)}
|
|
||||||
/>);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
} else if (res.data === "SelectPlan") {
|
} else if (res.data === "SelectPlan") {
|
||||||
// paid-user does not have active or pending subscription, go to application default pricing page to select-plan
|
// paid-user does not have active or pending subscription, go to application default pricing page to select-plan
|
||||||
@ -545,6 +532,49 @@ class LoginPage extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderMfaAuthVerifyForm(values, authParams, onSuccess) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<MfaAuthVerifyForm
|
||||||
|
mfaProps={this.state.selectedMfaProp}
|
||||||
|
formValues={values}
|
||||||
|
authParams={authParams}
|
||||||
|
application={this.getApplicationObj()}
|
||||||
|
onFail={(errorMessage) => {
|
||||||
|
Setting.showMessage("error", errorMessage);
|
||||||
|
}}
|
||||||
|
onSuccess={(res) => onSuccess(res)}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
this.state.mfaProps.map((mfa) => {
|
||||||
|
if (this.state.selectedMfaProp.mfaType === mfa.mfaType) {return null;}
|
||||||
|
let mfaI18n = "";
|
||||||
|
switch (mfa.mfaType) {
|
||||||
|
case SmsMfaType: mfaI18n = i18next.t("mfa:Use SMS"); break;
|
||||||
|
case TotpMfaType: mfaI18n = i18next.t("mfa:Use Authenticator App"); break ;
|
||||||
|
case EmailMfaType: mfaI18n = i18next.t("mfa:Use Email") ;break;
|
||||||
|
}
|
||||||
|
return <div key={mfa.mfaType}><Button type={"link"} onClick={() => {
|
||||||
|
this.setState({
|
||||||
|
selectedMfaProp: mfa,
|
||||||
|
});
|
||||||
|
}}>{mfaI18n}</Button></div>;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPreferredMfaProp(mfaProps) {
|
||||||
|
for (const i in mfaProps) {
|
||||||
|
if (mfaProps[i].isPreffered) {
|
||||||
|
return mfaProps[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mfaProps[0];
|
||||||
|
}
|
||||||
|
|
||||||
isProviderVisible(providerItem) {
|
isProviderVisible(providerItem) {
|
||||||
if (this.state.mode === "signup") {
|
if (this.state.mode === "signup") {
|
||||||
return Setting.isProviderVisibleForSignUp(providerItem);
|
return Setting.isProviderVisibleForSignUp(providerItem);
|
||||||
@ -1150,7 +1180,7 @@ class LoginPage extends React.Component {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
application?.signinMethods?.forEach((signinMethod) => {
|
application?.signinMethods?.forEach((signinMethod) => {
|
||||||
if (signinMethod.rule === "Hide-Password") {
|
if (signinMethod.rule === "Hide password") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const item = itemsMap.get(generateItemKey(signinMethod.name, signinMethod.rule));
|
const item = itemsMap.get(generateItemKey(signinMethod.name, signinMethod.rule));
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import CryptoJS from "crypto-js";
|
import CryptoJS from "crypto-js";
|
||||||
import i18next from "i18next";
|
|
||||||
import {Buffer} from "buffer";
|
import {Buffer} from "buffer";
|
||||||
|
|
||||||
export function getRandomKeyForObfuscator(obfuscatorType) {
|
export function getRandomKeyForObfuscator(obfuscatorType) {
|
||||||
@ -46,17 +45,17 @@ function encrypt(cipher, key, iv, password) {
|
|||||||
|
|
||||||
export function checkPasswordObfuscator(passwordObfuscatorType, passwordObfuscatorKey) {
|
export function checkPasswordObfuscator(passwordObfuscatorType, passwordObfuscatorKey) {
|
||||||
if (passwordObfuscatorType === undefined) {
|
if (passwordObfuscatorType === undefined) {
|
||||||
return i18next.t("organization:failed to get password obfuscator");
|
return "passwordObfuscatorType should not be undefined";
|
||||||
} else if (passwordObfuscatorType === "Plain" || passwordObfuscatorType === "") {
|
} else if (passwordObfuscatorType === "Plain" || passwordObfuscatorType === "") {
|
||||||
return "";
|
return "";
|
||||||
} else if (passwordObfuscatorType === "AES" || passwordObfuscatorType === "DES") {
|
} else if (passwordObfuscatorType === "AES" || passwordObfuscatorType === "DES") {
|
||||||
if (passwordObfuscatorKeyRegexes[passwordObfuscatorType].test(passwordObfuscatorKey)) {
|
if (passwordObfuscatorKeyRegexes[passwordObfuscatorType].test(passwordObfuscatorKey)) {
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
return `${i18next.t("organization:The password obfuscator key doesn't match the regex")}: ${passwordObfuscatorKeyRegexes[passwordObfuscatorType].source}`;
|
return `The password obfuscator key doesn't match the regex: ${passwordObfuscatorKeyRegexes[passwordObfuscatorType].source}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return `${i18next.t("organization:unsupported password obfuscator type")}: ${passwordObfuscatorType}`;
|
return `unsupported password obfuscator type: ${passwordObfuscatorType}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,10 @@ const authInfo = {
|
|||||||
scope: "user_info",
|
scope: "user_info",
|
||||||
endpoint: "https://open.douyin.com/platform/oauth/connect",
|
endpoint: "https://open.douyin.com/platform/oauth/connect",
|
||||||
},
|
},
|
||||||
|
Kwai: {
|
||||||
|
scope: "user_info",
|
||||||
|
endpoint: "https://open.kuaishou.com/oauth2/connect",
|
||||||
|
},
|
||||||
Custom: {
|
Custom: {
|
||||||
endpoint: "https://example.com/",
|
endpoint: "https://example.com/",
|
||||||
},
|
},
|
||||||
@ -470,6 +474,8 @@ export function getAuthUrl(application, provider, method, code) {
|
|||||||
return `${provider.domain}/v1/authorize?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
return `${provider.domain}/v1/authorize?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||||
} else if (provider.type === "Douyin" || provider.type === "TikTok") {
|
} else if (provider.type === "Douyin" || provider.type === "TikTok") {
|
||||||
return `${endpoint}?client_key=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
return `${endpoint}?client_key=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||||
|
} else if (provider.type === "Kwai") {
|
||||||
|
return `${endpoint}?app_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||||
} else if (provider.type === "Custom") {
|
} else if (provider.type === "Custom") {
|
||||||
return `${provider.customAuthUrl}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${provider.scopes}&response_type=code&state=${state}`;
|
return `${provider.customAuthUrl}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${provider.scopes}&response_type=code&state=${state}`;
|
||||||
} else if (provider.type === "Bilibili") {
|
} else if (provider.type === "Bilibili") {
|
||||||
|
@ -40,6 +40,7 @@ import SteamLoginButton from "./SteamLoginButton";
|
|||||||
import BilibiliLoginButton from "./BilibiliLoginButton";
|
import BilibiliLoginButton from "./BilibiliLoginButton";
|
||||||
import OktaLoginButton from "./OktaLoginButton";
|
import OktaLoginButton from "./OktaLoginButton";
|
||||||
import DouyinLoginButton from "./DouyinLoginButton";
|
import DouyinLoginButton from "./DouyinLoginButton";
|
||||||
|
import KwaiLoginButton from "./KwaiLoginButton";
|
||||||
import LoginButton from "./LoginButton";
|
import LoginButton from "./LoginButton";
|
||||||
import * as AuthBackend from "./AuthBackend";
|
import * as AuthBackend from "./AuthBackend";
|
||||||
import {WechatOfficialAccountModal} from "./Util";
|
import {WechatOfficialAccountModal} from "./Util";
|
||||||
@ -96,6 +97,8 @@ function getSigninButton(provider) {
|
|||||||
return <OktaLoginButton text={text} align={"center"} />;
|
return <OktaLoginButton text={text} align={"center"} />;
|
||||||
} else if (provider.type === "Douyin") {
|
} else if (provider.type === "Douyin") {
|
||||||
return <DouyinLoginButton text={text} align={"center"} />;
|
return <DouyinLoginButton text={text} align={"center"} />;
|
||||||
|
} else if (provider.type === "Kwai") {
|
||||||
|
return <KwaiLoginButton text={text} align={"center"} />;
|
||||||
} else {
|
} else {
|
||||||
return <LoginButton key={provider.type} type={provider.type} logoUrl={getProviderLogoURL(provider)} />;
|
return <LoginButton key={provider.type} type={provider.type} logoUrl={getProviderLogoURL(provider)} />;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,8 @@ export function MfaAuthVerifyForm({formValues, authParams, mfaProps, application
|
|||||||
|
|
||||||
const verify = ({passcode}) => {
|
const verify = ({passcode}) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const values = {...formValues, passcode, mfaType};
|
const values = {...formValues, passcode};
|
||||||
|
values["mfaType"] = mfaProps.mfaType;
|
||||||
const loginFunction = formValues.type === "cas" ? AuthBackend.loginCas : AuthBackend.login;
|
const loginFunction = formValues.type === "cas" ? AuthBackend.loginCas : AuthBackend.login;
|
||||||
loginFunction(values, authParams).then((res) => {
|
loginFunction(values, authParams).then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
@ -71,7 +72,7 @@ export function MfaAuthVerifyForm({formValues, authParams, mfaProps, application
|
|||||||
<div style={{marginBottom: 24, textAlign: "center", fontSize: "24px"}}>
|
<div style={{marginBottom: 24, textAlign: "center", fontSize: "24px"}}>
|
||||||
{i18next.t("mfa:Multi-factor authentication")}
|
{i18next.t("mfa:Multi-factor authentication")}
|
||||||
</div>
|
</div>
|
||||||
{mfaType === SmsMfaType || mfaType === EmailMfaType ? (
|
{mfaProps.mfaType === SmsMfaType || mfaProps.mfaType === EmailMfaType ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div style={{marginBottom: 24}}>
|
<div style={{marginBottom: 24}}>
|
||||||
{i18next.t("mfa:You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue")}
|
{i18next.t("mfa:You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue")}
|
||||||
|
@ -9,11 +9,11 @@ export function MfaEnableForm({user, mfaType, secret, recoveryCodes, dest, count
|
|||||||
const data = {
|
const data = {
|
||||||
mfaType,
|
mfaType,
|
||||||
secret,
|
secret,
|
||||||
recoveryCodes,
|
|
||||||
dest,
|
dest,
|
||||||
countryCode,
|
countryCode,
|
||||||
...user,
|
...user,
|
||||||
};
|
};
|
||||||
|
data["recoveryCodes"] = recoveryCodes[0];
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
MfaBackend.MfaSetupEnable(data).then(res => {
|
MfaBackend.MfaSetupEnable(data).then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
|
@ -141,6 +141,9 @@ const Dashboard = (props) => {
|
|||||||
i18next.t("general:Certs"),
|
i18next.t("general:Certs"),
|
||||||
i18next.t("general:Permissions"),
|
i18next.t("general:Permissions"),
|
||||||
i18next.t("general:Transactions"),
|
i18next.t("general:Transactions"),
|
||||||
|
i18next.t("general:Models"),
|
||||||
|
i18next.t("general:Adapters"),
|
||||||
|
i18next.t("general:Enforcers"),
|
||||||
], top: "10%"},
|
], top: "10%"},
|
||||||
grid: {left: "3%", right: "4%", bottom: "0", top: "25%", containLabel: true},
|
grid: {left: "3%", right: "4%", bottom: "0", top: "25%", containLabel: true},
|
||||||
xAxis: {type: "category", boundaryGap: false, data: dateArray},
|
xAxis: {type: "category", boundaryGap: false, data: dateArray},
|
||||||
@ -157,6 +160,9 @@ const Dashboard = (props) => {
|
|||||||
{name: i18next.t("general:Certs"), type: "line", data: dashboardData.certCounts},
|
{name: i18next.t("general:Certs"), type: "line", data: dashboardData.certCounts},
|
||||||
{name: i18next.t("general:Permissions"), type: "line", data: dashboardData.permissionCounts},
|
{name: i18next.t("general:Permissions"), type: "line", data: dashboardData.permissionCounts},
|
||||||
{name: i18next.t("general:Transactions"), type: "line", data: dashboardData.transactionCounts},
|
{name: i18next.t("general:Transactions"), type: "line", data: dashboardData.transactionCounts},
|
||||||
|
{name: i18next.t("general:Models"), type: "line", data: dashboardData.modelCounts},
|
||||||
|
{name: i18next.t("general:Adapters"), type: "line", data: dashboardData.adapterCounts},
|
||||||
|
{name: i18next.t("general:Enforcers"), type: "line", data: dashboardData.enforcerCounts},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
myChart.setOption(option);
|
myChart.setOption(option);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Alert, Button, QRCode} from "antd";
|
import {Alert, Button, QRCode} from "antd";
|
||||||
|
import copy from "copy-to-clipboard";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
@ -62,12 +63,8 @@ export const CasdoorAppUrl = ({accessToken}) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
copy(qrUrl);
|
||||||
await navigator.clipboard.writeText(qrUrl);
|
Setting.showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
||||||
Setting.showMessage("success", i18next.t("general:Copied to clipboard"));
|
|
||||||
} catch (err) {
|
|
||||||
Setting.showMessage("error", i18next.t("general:Failed to copy"));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -82,14 +79,9 @@ export const CasdoorAppUrl = ({accessToken}) => {
|
|||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginBottom: "10px",
|
marginBottom: "10px",
|
||||||
}}>
|
}}>
|
||||||
<span>{i18next.t("general:URL String")}</span>
|
|
||||||
{window.isSecureContext && (
|
{window.isSecureContext && (
|
||||||
<Button
|
<Button size="small" type="primary" onClick={handleCopyUrl} style={{marginLeft: "10px"}}>
|
||||||
size="small"
|
{i18next.t("resource:Copy Link")}
|
||||||
onClick={handleCopyUrl}
|
|
||||||
style={{marginLeft: "10px"}}
|
|
||||||
>
|
|
||||||
{i18next.t("general:Copy URL")}
|
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -105,7 +105,7 @@ export const PasswordModal = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasOldPassword = user.password !== "";
|
const hasOldPassword = (user.password !== "" || user.ldap !== "");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Odesílání",
|
"Sending": "Odesílání",
|
||||||
"Submit and complete": "Odeslat a dokončit"
|
"Submit and complete": "Odeslat a dokončit"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Upravit Enforcer",
|
"Edit Enforcer": "Upravit Enforcer",
|
||||||
"New Enforcer": "Nový Enforcer"
|
"New Enforcer": "Nový Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Přejít na zapisovatelnou demo stránku?",
|
"Go to writable demo site?": "Přejít na zapisovatelnou demo stránku?",
|
||||||
"Groups": "Skupiny",
|
"Groups": "Skupiny",
|
||||||
"Groups - Tooltip": "Skupiny - Tooltip",
|
"Groups - Tooltip": "Skupiny - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Domů",
|
"Home": "Domů",
|
||||||
"Home - Tooltip": "Domovská stránka aplikace",
|
"Home - Tooltip": "Domovská stránka aplikace",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unikátní náhodný řetězec",
|
"ID - Tooltip": "Unikátní náhodný řetězec",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identita",
|
"Identity": "Identita",
|
||||||
"Invitations": "Pozvánky",
|
"Invitations": "Pozvánky",
|
||||||
"Is enabled": "Je povoleno",
|
"Is enabled": "Je povoleno",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Ujistěte se, že heslo je správné",
|
"Password - Tooltip": "Ujistěte se, že heslo je správné",
|
||||||
"Password complexity options": "Možnosti složitosti hesla",
|
"Password complexity options": "Možnosti složitosti hesla",
|
||||||
"Password complexity options - Tooltip": "Různé kombinace možností složitosti hesla",
|
"Password complexity options - Tooltip": "Různé kombinace možností složitosti hesla",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Heslová sůl",
|
"Password salt": "Heslová sůl",
|
||||||
"Password salt - Tooltip": "Náhodný parametr použitý pro šifrování hesla",
|
"Password salt - Tooltip": "Náhodný parametr použitý pro šifrování hesla",
|
||||||
"Password type": "Typ hesla",
|
"Password type": "Typ hesla",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Použít SMS",
|
"Use SMS": "Použít SMS",
|
||||||
"Use SMS verification code": "Použít ověřovací kód SMS",
|
"Use SMS verification code": "Použít ověřovací kód SMS",
|
||||||
"Use a recovery code": "Použít obnovovací kód",
|
"Use a recovery code": "Použít obnovovací kód",
|
||||||
"Verification failed": "Ověření selhalo",
|
|
||||||
"Verify Code": "Ověřit kód",
|
"Verify Code": "Ověřit kód",
|
||||||
"Verify Password": "Ověřit heslo",
|
"Verify Password": "Ověřit heslo",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Pokročilý editor",
|
||||||
|
"Basic Editor": "Základní editor",
|
||||||
"Edit Model": "Upravit model",
|
"Edit Model": "Upravit model",
|
||||||
"Model text": "Text modelu",
|
"Model text": "Text modelu",
|
||||||
"Model text - Tooltip": "Casbin model řízení přístupu, včetně vestavěných modelů jako ACL, RBAC, ABAC, RESTful, atd. Můžete také vytvářet vlastní modely. Pro více informací navštivte webové stránky Casbin",
|
"Model text - Tooltip": "Casbin model řízení přístupu, včetně vestavěných modelů jako ACL, RBAC, ABAC, RESTful, atd. Můžete také vytvářet vlastní modely. Pro více informací navštivte webové stránky Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Upravit pravidlo",
|
"Modify rule": "Upravit pravidlo",
|
||||||
"New Organization": "Nová organizace",
|
"New Organization": "Nová organizace",
|
||||||
"Optional": "Volitelný",
|
"Optional": "Volitelný",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Výzva",
|
"Prompt": "Výzva",
|
||||||
"Required": "Povinné",
|
"Required": "Povinné",
|
||||||
"Soft deletion": "Měkké smazání",
|
"Soft deletion": "Měkké smazání",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Koupit",
|
"Buy": "Koupit",
|
||||||
"Buy Product": "Koupit produkt",
|
"Buy Product": "Koupit produkt",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail produktu",
|
"Detail - Tooltip": "Detail produktu",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Testovací stránka nákupu..",
|
"Test buy page..": "Testovací stránka nákupu..",
|
||||||
"There is no payment channel for this product.": "Pro tento produkt neexistuje žádný platební kanál.",
|
"There is no payment channel for this product.": "Pro tento produkt neexistuje žádný platební kanál.",
|
||||||
"This product is currently not in sale.": "Tento produkt není momentálně v prodeji.",
|
"This product is currently not in sale.": "Tento produkt není momentálně v prodeji.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Upravit HTML pro registraci",
|
"Signup HTML - Edit": "Upravit HTML pro registraci",
|
||||||
"Signup HTML - Tooltip": "Vlastní HTML pro nahrazení výchozího stylu registrační stránky",
|
"Signup HTML - Tooltip": "Vlastní HTML pro nahrazení výchozího stylu registrační stránky",
|
||||||
"Signup group": "Skupina pro registraci",
|
"Signup group": "Skupina pro registraci",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Tiché",
|
"Silent": "Tiché",
|
||||||
"Site key": "Klíč stránky",
|
"Site key": "Klíč stránky",
|
||||||
"Site key - Tooltip": "Nápověda ke klíči stránky",
|
"Site key - Tooltip": "Nápověda ke klíči stránky",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Klíče",
|
"Keys": "Klíče",
|
||||||
"Language": "Jazyk",
|
"Language": "Jazyk",
|
||||||
"Language - Tooltip": "Jazyk - Nápověda",
|
"Language - Tooltip": "Jazyk - Nápověda",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Odkaz",
|
"Link": "Odkaz",
|
||||||
"Location": "Místo",
|
"Location": "Místo",
|
||||||
"Location - Tooltip": "Město bydliště",
|
"Location - Tooltip": "Město bydliště",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sendet",
|
"Sending": "Sendet",
|
||||||
"Submit and complete": "Einreichen und abschließen"
|
"Submit and complete": "Einreichen und abschließen"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Gehe zur beschreibbaren Demo-Website?",
|
"Go to writable demo site?": "Gehe zur beschreibbaren Demo-Website?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Zuhause",
|
"Home": "Zuhause",
|
||||||
"Home - Tooltip": "Homepage der Anwendung",
|
"Home - Tooltip": "Homepage der Anwendung",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Einzigartiger Zufallsstring",
|
"ID - Tooltip": "Einzigartiger Zufallsstring",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Ist aktiviert",
|
"Is enabled": "Ist aktiviert",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Stellen Sie sicher, dass das Passwort korrekt ist",
|
"Password - Tooltip": "Stellen Sie sicher, dass das Passwort korrekt ist",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Passwort-Salt",
|
"Password salt": "Passwort-Salt",
|
||||||
"Password salt - Tooltip": "Zufälliger Parameter, der für die Verschlüsselung von Passwörtern verwendet wird",
|
"Password salt - Tooltip": "Zufälliger Parameter, der für die Verschlüsselung von Passwörtern verwendet wird",
|
||||||
"Password type": "Passworttyp",
|
"Password type": "Passworttyp",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Erweiterter Editor",
|
||||||
|
"Basic Editor": "Basis-Editor",
|
||||||
"Edit Model": "Modell bearbeiten",
|
"Edit Model": "Modell bearbeiten",
|
||||||
"Model text": "Modelltext",
|
"Model text": "Modelltext",
|
||||||
"Model text - Tooltip": "Casbin Zugriffskontrollmodell inklusive integrierter Modelle wie ACL, RBAC, ABAC, RESTful, usw. Sie können auch benutzerdefinierte Modelle erstellen. Weitere Informationen finden Sie auf der Casbin-Website",
|
"Model text - Tooltip": "Casbin Zugriffskontrollmodell inklusive integrierter Modelle wie ACL, RBAC, ABAC, RESTful, usw. Sie können auch benutzerdefinierte Modelle erstellen. Weitere Informationen finden Sie auf der Casbin-Website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Regel ändern",
|
"Modify rule": "Regel ändern",
|
||||||
"New Organization": "Neue Organisation",
|
"New Organization": "Neue Organisation",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Softe Löschung",
|
"Soft deletion": "Softe Löschung",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Kaufen",
|
"Buy": "Kaufen",
|
||||||
"Buy Product": "Produkt kaufen",
|
"Buy Product": "Produkt kaufen",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail des Produkts",
|
"Detail - Tooltip": "Detail des Produkts",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Testkaufseite.",
|
"Test buy page..": "Testkaufseite.",
|
||||||
"There is no payment channel for this product.": "Es gibt keinen Zahlungskanal für dieses Produkt.",
|
"There is no payment channel for this product.": "Es gibt keinen Zahlungskanal für dieses Produkt.",
|
||||||
"This product is currently not in sale.": "Dieses Produkt steht derzeit nicht zum Verkauf.",
|
"This product is currently not in sale.": "Dieses Produkt steht derzeit nicht zum Verkauf.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Registrierung HTML - Bearbeiten",
|
"Signup HTML - Edit": "Registrierung HTML - Bearbeiten",
|
||||||
"Signup HTML - Tooltip": "Benutzerdefiniertes HTML zur Ersetzung des Standard-Registrierungs-Seitenstils",
|
"Signup HTML - Tooltip": "Benutzerdefiniertes HTML zur Ersetzung des Standard-Registrierungs-Seitenstils",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site-Key",
|
"Site key": "Site-Key",
|
||||||
"Site key - Tooltip": "Seitenschlüssel",
|
"Site key - Tooltip": "Seitenschlüssel",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Schlüssel",
|
"Keys": "Schlüssel",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Ort",
|
"Location": "Ort",
|
||||||
"Location - Tooltip": "Stadt des Wohnsitzes",
|
"Location - Tooltip": "Stadt des Wohnsitzes",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,16 +761,7 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
"WeChat Pay": "WeChat Pay"
|
||||||
"WeChat Pay": "WeChat Pay",
|
|
||||||
"EUR": "EUR",
|
|
||||||
"JPY": "JPY",
|
|
||||||
"GBP": "GBP",
|
|
||||||
"AUD": "AUD",
|
|
||||||
"CAD": "CAD",
|
|
||||||
"CHF": "CHF",
|
|
||||||
"HKD": "HKD",
|
|
||||||
"SGD": "SGD"
|
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
"Access key": "Access key",
|
"Access key": "Access key",
|
||||||
@ -901,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1165,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Envío",
|
"Sending": "Envío",
|
||||||
"Submit and complete": "Enviar y completar"
|
"Submit and complete": "Enviar y completar"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "¿Ir al sitio demo editable?",
|
"Go to writable demo site?": "¿Ir al sitio demo editable?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Hogar",
|
"Home": "Hogar",
|
||||||
"Home - Tooltip": "Página de inicio de la aplicación",
|
"Home - Tooltip": "Página de inicio de la aplicación",
|
||||||
"ID": "identificación",
|
"ID": "identificación",
|
||||||
"ID - Tooltip": "Cadena aleatoria única",
|
"ID - Tooltip": "Cadena aleatoria única",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Está habilitado",
|
"Is enabled": "Está habilitado",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Asegúrate de que la contraseña sea correcta",
|
"Password - Tooltip": "Asegúrate de que la contraseña sea correcta",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Sal de contraseña",
|
"Password salt": "Sal de contraseña",
|
||||||
"Password salt - Tooltip": "Parámetro aleatorio utilizado para la encriptación de contraseñas",
|
"Password salt - Tooltip": "Parámetro aleatorio utilizado para la encriptación de contraseñas",
|
||||||
"Password type": "Tipo de contraseña",
|
"Password type": "Tipo de contraseña",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Editor avanzado",
|
||||||
|
"Basic Editor": "Editor básico",
|
||||||
"Edit Model": "Editar modelo",
|
"Edit Model": "Editar modelo",
|
||||||
"Model text": "Texto modelo",
|
"Model text": "Texto modelo",
|
||||||
"Model text - Tooltip": "Modelo de control de acceso Casbin, incluyendo modelos integrados como ACL, RBAC, ABAC, RESTful, etc. También puede crear modelos personalizados. Para obtener más información, visite el sitio web de Casbin",
|
"Model text - Tooltip": "Modelo de control de acceso Casbin, incluyendo modelos integrados como ACL, RBAC, ABAC, RESTful, etc. También puede crear modelos personalizados. Para obtener más información, visite el sitio web de Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modificar regla",
|
"Modify rule": "Modificar regla",
|
||||||
"New Organization": "Nueva organización",
|
"New Organization": "Nueva organización",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Eliminación suave",
|
"Soft deletion": "Eliminación suave",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Comprar",
|
"Buy": "Comprar",
|
||||||
"Buy Product": "Comprar producto",
|
"Buy Product": "Comprar producto",
|
||||||
"CNY": "Año Nuevo Chino (ANC)",
|
|
||||||
"Detail": "Detalle",
|
"Detail": "Detalle",
|
||||||
"Detail - Tooltip": "Detalle del producto",
|
"Detail - Tooltip": "Detalle del producto",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Página de compra de prueba.",
|
"Test buy page..": "Página de compra de prueba.",
|
||||||
"There is no payment channel for this product.": "No hay canal de pago para este producto.",
|
"There is no payment channel for this product.": "No hay canal de pago para este producto.",
|
||||||
"This product is currently not in sale.": "Este producto actualmente no está a la venta.",
|
"This product is currently not in sale.": "Este producto actualmente no está a la venta.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Registro HTML - Editar",
|
"Signup HTML - Edit": "Registro HTML - Editar",
|
||||||
"Signup HTML - Tooltip": "HTML personalizado para reemplazar el estilo predeterminado de la página de registro",
|
"Signup HTML - Tooltip": "HTML personalizado para reemplazar el estilo predeterminado de la página de registro",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Clave del sitio",
|
"Site key": "Clave del sitio",
|
||||||
"Site key - Tooltip": "Clave del sitio",
|
"Site key - Tooltip": "Clave del sitio",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Claves",
|
"Keys": "Claves",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Enlace",
|
"Link": "Enlace",
|
||||||
"Location": "Ubicación",
|
"Location": "Ubicación",
|
||||||
"Location - Tooltip": "Ciudad de residencia",
|
"Location - Tooltip": "Ciudad de residencia",
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
"Only signup": "فقط ثبتنام",
|
"Only signup": "فقط ثبتنام",
|
||||||
"Org choice mode": "حالت انتخاب سازمان",
|
"Org choice mode": "حالت انتخاب سازمان",
|
||||||
"Org choice mode - Tooltip": "حالت انتخاب سازمان - راهنمای ابزار",
|
"Org choice mode - Tooltip": "حالت انتخاب سازمان - راهنمای ابزار",
|
||||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "لطفاً قبل از فعالسازی \"ورود خودکار\"، ابتدا \"جلسه ورود\" را فعال کنید",
|
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
|
||||||
"Please input your application!": "لطفاً برنامه خود را وارد کنید!",
|
"Please input your application!": "لطفاً برنامه خود را وارد کنید!",
|
||||||
"Please input your organization!": "لطفاً سازمان خود را وارد کنید!",
|
"Please input your organization!": "لطفاً سازمان خود را وارد کنید!",
|
||||||
"Please select a HTML file": "لطفاً یک فایل HTML انتخاب کنید",
|
"Please select a HTML file": "لطفاً یک فایل HTML انتخاب کنید",
|
||||||
@ -161,6 +161,18 @@
|
|||||||
"Sending": "در حال ارسال",
|
"Sending": "در حال ارسال",
|
||||||
"Submit and complete": "ارسال و تکمیل"
|
"Submit and complete": "ارسال و تکمیل"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "ویرایش Enforcer",
|
"Edit Enforcer": "ویرایش Enforcer",
|
||||||
"New Enforcer": "Enforcer جدید"
|
"New Enforcer": "Enforcer جدید"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "به سایت دمو قابل نوشتن بروید؟",
|
"Go to writable demo site?": "به سایت دمو قابل نوشتن بروید؟",
|
||||||
"Groups": "گروهها",
|
"Groups": "گروهها",
|
||||||
"Groups - Tooltip": "گروهها - راهنمای ابزار",
|
"Groups - Tooltip": "گروهها - راهنمای ابزار",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "خانه",
|
"Home": "خانه",
|
||||||
"Home - Tooltip": "صفحه اصلی برنامه",
|
"Home - Tooltip": "صفحه اصلی برنامه",
|
||||||
"ID": "شناسه",
|
"ID": "شناسه",
|
||||||
"ID - Tooltip": "رشته تصادفی منحصربهفرد",
|
"ID - Tooltip": "رشته تصادفی منحصربهفرد",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "هویت",
|
"Identity": "هویت",
|
||||||
"Invitations": "دعوتها",
|
"Invitations": "دعوتها",
|
||||||
"Is enabled": "فعال است",
|
"Is enabled": "فعال است",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "مطمئن شوید که رمز عبور صحیح است",
|
"Password - Tooltip": "مطمئن شوید که رمز عبور صحیح است",
|
||||||
"Password complexity options": "گزینههای پیچیدگی رمز عبور",
|
"Password complexity options": "گزینههای پیچیدگی رمز عبور",
|
||||||
"Password complexity options - Tooltip": "ترکیبات مختلف گزینههای پیچیدگی رمز عبور",
|
"Password complexity options - Tooltip": "ترکیبات مختلف گزینههای پیچیدگی رمز عبور",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "نمک رمز عبور",
|
"Password salt": "نمک رمز عبور",
|
||||||
"Password salt - Tooltip": "پارامتر تصادفی مورد استفاده برای رمزگذاری رمز عبور",
|
"Password salt - Tooltip": "پارامتر تصادفی مورد استفاده برای رمزگذاری رمز عبور",
|
||||||
"Password type": "نوع رمز عبور",
|
"Password type": "نوع رمز عبور",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "استفاده از پیامک",
|
"Use SMS": "استفاده از پیامک",
|
||||||
"Use SMS verification code": "استفاده از کد تأیید پیامک",
|
"Use SMS verification code": "استفاده از کد تأیید پیامک",
|
||||||
"Use a recovery code": "استفاده از کد بازیابی",
|
"Use a recovery code": "استفاده از کد بازیابی",
|
||||||
"Verification failed": "تأیید ناموفق بود",
|
|
||||||
"Verify Code": "تأیید کد",
|
"Verify Code": "تأیید کد",
|
||||||
"Verify Password": "تأیید رمز عبور",
|
"Verify Password": "تأیید رمز عبور",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "شما احراز هویت چندعاملی را فعال کردهاید، لطفاً برای ادامه روی 'ارسال کد' کلیک کنید",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "شما احراز هویت چندعاملی را فعال کردهاید، لطفاً برای ادامه روی 'ارسال کد' کلیک کنید",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "کلید مخفی"
|
"Secret Key": "کلید مخفی"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "ویرایشگر پیشرفته",
|
||||||
|
"Basic Editor": "ویرایشگر ابتدایی",
|
||||||
"Edit Model": "ویرایش مدل",
|
"Edit Model": "ویرایش مدل",
|
||||||
"Model text": "متن مدل",
|
"Model text": "متن مدل",
|
||||||
"Model text - Tooltip": "مدل کنترل دسترسی Casbin، شامل مدلهای داخلی مانند ACL، RBAC، ABAC، RESTful و غیره. همچنین میتوانید مدلهای سفارشی ایجاد کنید. برای اطلاعات بیشتر، لطفاً به وبسایت Casbin مراجعه کنید",
|
"Model text - Tooltip": "مدل کنترل دسترسی Casbin، شامل مدلهای داخلی مانند ACL، RBAC، ABAC، RESTful و غیره. همچنین میتوانید مدلهای سفارشی ایجاد کنید. برای اطلاعات بیشتر، لطفاً به وبسایت Casbin مراجعه کنید",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "قانون اصلاح",
|
"Modify rule": "قانون اصلاح",
|
||||||
"New Organization": "سازمان جدید",
|
"New Organization": "سازمان جدید",
|
||||||
"Optional": "اختیاری",
|
"Optional": "اختیاری",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "اعلان",
|
"Prompt": "اعلان",
|
||||||
"Required": "الزامی",
|
"Required": "الزامی",
|
||||||
"Soft deletion": "حذف نرم",
|
"Soft deletion": "حذف نرم",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "خرید",
|
"Buy": "خرید",
|
||||||
"Buy Product": "خرید محصول",
|
"Buy Product": "خرید محصول",
|
||||||
"CNY": "یوان چین",
|
|
||||||
"Detail": "جزئیات",
|
"Detail": "جزئیات",
|
||||||
"Detail - Tooltip": "جزئیات محصول",
|
"Detail - Tooltip": "جزئیات محصول",
|
||||||
"Dummy": "فرضی",
|
"Dummy": "فرضی",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "صفحه تست خرید..",
|
"Test buy page..": "صفحه تست خرید..",
|
||||||
"There is no payment channel for this product.": "برای این محصول کانال پرداختی وجود ندارد.",
|
"There is no payment channel for this product.": "برای این محصول کانال پرداختی وجود ندارد.",
|
||||||
"This product is currently not in sale.": "این محصول در حال حاضر در فروش نیست.",
|
"This product is currently not in sale.": "این محصول در حال حاضر در فروش نیست.",
|
||||||
"USD": "دلار آمریکا",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "ویرایش HTML ثبتنام",
|
"Signup HTML - Edit": "ویرایش HTML ثبتنام",
|
||||||
"Signup HTML - Tooltip": "HTML سفارشی برای جایگزینی سبک صفحه ثبتنام پیشفرض",
|
"Signup HTML - Tooltip": "HTML سفارشی برای جایگزینی سبک صفحه ثبتنام پیشفرض",
|
||||||
"Signup group": "گروه ثبتنام",
|
"Signup group": "گروه ثبتنام",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "بیصدا",
|
"Silent": "بیصدا",
|
||||||
"Site key": "کلید سایت",
|
"Site key": "کلید سایت",
|
||||||
"Site key - Tooltip": "کلید سایت",
|
"Site key - Tooltip": "کلید سایت",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "کلیدها",
|
"Keys": "کلیدها",
|
||||||
"Language": "زبان",
|
"Language": "زبان",
|
||||||
"Language - Tooltip": "زبان - راهنمای ابزار",
|
"Language - Tooltip": "زبان - راهنمای ابزار",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "اتصال",
|
"Link": "اتصال",
|
||||||
"Location": "مکان",
|
"Location": "مکان",
|
||||||
"Location - Tooltip": "شهر محل سکونت",
|
"Location - Tooltip": "شهر محل سکونت",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Envoi en cours",
|
"Sending": "Envoi en cours",
|
||||||
"Submit and complete": "Soumettre et compléter"
|
"Submit and complete": "Soumettre et compléter"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Éditer l'exécuteur",
|
"Edit Enforcer": "Éditer l'exécuteur",
|
||||||
"New Enforcer": "Ajouter un exécuteur"
|
"New Enforcer": "Ajouter un exécuteur"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Allez sur le site de démonstration modifiable ?",
|
"Go to writable demo site?": "Allez sur le site de démonstration modifiable ?",
|
||||||
"Groups": "Groupes",
|
"Groups": "Groupes",
|
||||||
"Groups - Tooltip": "Groupes - infobulle",
|
"Groups - Tooltip": "Groupes - infobulle",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Accueil",
|
"Home": "Accueil",
|
||||||
"Home - Tooltip": "Page d'accueil de l'application",
|
"Home - Tooltip": "Page d'accueil de l'application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Chaîne unique aléatoire",
|
"ID - Tooltip": "Chaîne unique aléatoire",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identité",
|
"Identity": "Identité",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Est activé",
|
"Is enabled": "Est activé",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Assurez-vous que le mot de passe soit correct",
|
"Password - Tooltip": "Assurez-vous que le mot de passe soit correct",
|
||||||
"Password complexity options": "Options de complexité du mot de passe",
|
"Password complexity options": "Options de complexité du mot de passe",
|
||||||
"Password complexity options - Tooltip": "Différentes combinaisons d'options de complexité de mot de passe",
|
"Password complexity options - Tooltip": "Différentes combinaisons d'options de complexité de mot de passe",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Sel de mot de passe",
|
"Password salt": "Sel de mot de passe",
|
||||||
"Password salt - Tooltip": "Paramètre aléatoire utilisé pour le chiffrement des mots de passe",
|
"Password salt - Tooltip": "Paramètre aléatoire utilisé pour le chiffrement des mots de passe",
|
||||||
"Password type": "Type de mot de passe",
|
"Password type": "Type de mot de passe",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Utiliser les SMS",
|
"Use SMS": "Utiliser les SMS",
|
||||||
"Use SMS verification code": "Utiliser la vérification par code SMS",
|
"Use SMS verification code": "Utiliser la vérification par code SMS",
|
||||||
"Use a recovery code": "Utiliser un code de récupération",
|
"Use a recovery code": "Utiliser un code de récupération",
|
||||||
"Verification failed": "Échec de la vérification",
|
|
||||||
"Verify Code": "Vérifier le code",
|
"Verify Code": "Vérifier le code",
|
||||||
"Verify Password": "Confirmez le mot de passe",
|
"Verify Password": "Confirmez le mot de passe",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Éditeur avancé",
|
||||||
|
"Basic Editor": "Éditeur de base",
|
||||||
"Edit Model": "Modifier le modèle",
|
"Edit Model": "Modifier le modèle",
|
||||||
"Model text": "Définition du modèle",
|
"Model text": "Définition du modèle",
|
||||||
"Model text - Tooltip": "Modèle de contrôle d'accès Casbin, comprenant des modèles intégrés tels que ACL, RBAC, ABAC, RESTful, etc. Vous pouvez également créer des modèles personnalisés. Pour plus d'informations, veuillez visiter le site web de Casbin",
|
"Model text - Tooltip": "Modèle de contrôle d'accès Casbin, comprenant des modèles intégrés tels que ACL, RBAC, ABAC, RESTful, etc. Vous pouvez également créer des modèles personnalisés. Pour plus d'informations, veuillez visiter le site web de Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Règle de modification",
|
"Modify rule": "Règle de modification",
|
||||||
"New Organization": "Nouvelle organisation",
|
"New Organization": "Nouvelle organisation",
|
||||||
"Optional": "Optionnel",
|
"Optional": "Optionnel",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Requis",
|
"Required": "Requis",
|
||||||
"Soft deletion": "Suppression douce",
|
"Soft deletion": "Suppression douce",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Acheter",
|
"Buy": "Acheter",
|
||||||
"Buy Product": "Acheter un produit",
|
"Buy Product": "Acheter un produit",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Détail",
|
"Detail": "Détail",
|
||||||
"Detail - Tooltip": "Détail du produit",
|
"Detail - Tooltip": "Détail du produit",
|
||||||
"Dummy": "Exemple",
|
"Dummy": "Exemple",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Page d'achat de test.",
|
"Test buy page..": "Page d'achat de test.",
|
||||||
"There is no payment channel for this product.": "Il n'y a aucun canal de paiement pour ce produit.",
|
"There is no payment channel for this product.": "Il n'y a aucun canal de paiement pour ce produit.",
|
||||||
"This product is currently not in sale.": "Ce produit n'est actuellement pas en vente.",
|
"This product is currently not in sale.": "Ce produit n'est actuellement pas en vente.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "HTML de la page d'inscription - Modifier",
|
"Signup HTML - Edit": "HTML de la page d'inscription - Modifier",
|
||||||
"Signup HTML - Tooltip": "HTML personnalisé pour remplacer le style par défaut de la page d'inscription",
|
"Signup HTML - Tooltip": "HTML personnalisé pour remplacer le style par défaut de la page d'inscription",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silencieux",
|
"Silent": "Silencieux",
|
||||||
"Site key": "Clé de site",
|
"Site key": "Clé de site",
|
||||||
"Site key - Tooltip": "Clé de site",
|
"Site key - Tooltip": "Clé de site",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Clés",
|
"Keys": "Clés",
|
||||||
"Language": "Langue",
|
"Language": "Langue",
|
||||||
"Language - Tooltip": "Langue - Infobulle",
|
"Language - Tooltip": "Langue - Infobulle",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Lier",
|
"Link": "Lier",
|
||||||
"Location": "Localisation",
|
"Location": "Localisation",
|
||||||
"Location - Tooltip": "Ville de résidence",
|
"Location - Tooltip": "Ville de résidence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Mengirimkan",
|
"Sending": "Mengirimkan",
|
||||||
"Submit and complete": "Kirim dan selesaikan"
|
"Submit and complete": "Kirim dan selesaikan"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Pergi ke situs demo yang dapat ditulis?",
|
"Go to writable demo site?": "Pergi ke situs demo yang dapat ditulis?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Rumah",
|
"Home": "Rumah",
|
||||||
"Home - Tooltip": "Halaman utama aplikasi",
|
"Home - Tooltip": "Halaman utama aplikasi",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Karakter acak unik",
|
"ID - Tooltip": "Karakter acak unik",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Diaktifkan",
|
"Is enabled": "Diaktifkan",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Pastikan kata sandi yang benar",
|
"Password - Tooltip": "Pastikan kata sandi yang benar",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Garam sandi",
|
"Password salt": "Garam sandi",
|
||||||
"Password salt - Tooltip": "Parameter acak yang digunakan untuk enkripsi kata sandi",
|
"Password salt - Tooltip": "Parameter acak yang digunakan untuk enkripsi kata sandi",
|
||||||
"Password type": "Jenis kata sandi",
|
"Password type": "Jenis kata sandi",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Editor lanjutan",
|
||||||
|
"Basic Editor": "Editor dasar",
|
||||||
"Edit Model": "Mengedit Model",
|
"Edit Model": "Mengedit Model",
|
||||||
"Model text": "Teks Model",
|
"Model text": "Teks Model",
|
||||||
"Model text - Tooltip": "Model kontrol akses Casbin, termasuk model bawaan seperti ACL, RBAC, ABAC, RESTful, dll. Anda juga dapat membuat model kustom. Untuk informasi lebih lanjut, silakan kunjungi situs web Casbin",
|
"Model text - Tooltip": "Model kontrol akses Casbin, termasuk model bawaan seperti ACL, RBAC, ABAC, RESTful, dll. Anda juga dapat membuat model kustom. Untuk informasi lebih lanjut, silakan kunjungi situs web Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Mengubah aturan",
|
"Modify rule": "Mengubah aturan",
|
||||||
"New Organization": "Organisasi baru",
|
"New Organization": "Organisasi baru",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Penghapusan lunak",
|
"Soft deletion": "Penghapusan lunak",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Beli",
|
"Buy": "Beli",
|
||||||
"Buy Product": "Beli Produk",
|
"Buy Product": "Beli Produk",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Rincian",
|
"Detail": "Rincian",
|
||||||
"Detail - Tooltip": "Detail produk",
|
"Detail - Tooltip": "Detail produk",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Halaman pembelian uji coba.",
|
"Test buy page..": "Halaman pembelian uji coba.",
|
||||||
"There is no payment channel for this product.": "Tidak ada saluran pembayaran untuk produk ini.",
|
"There is no payment channel for this product.": "Tidak ada saluran pembayaran untuk produk ini.",
|
||||||
"This product is currently not in sale.": "Produk ini saat ini tidak dijual.",
|
"This product is currently not in sale.": "Produk ini saat ini tidak dijual.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Pendaftaran HTML - Sunting",
|
"Signup HTML - Edit": "Pendaftaran HTML - Sunting",
|
||||||
"Signup HTML - Tooltip": "HTML khusus untuk mengganti gaya halaman pendaftaran bawaan",
|
"Signup HTML - Tooltip": "HTML khusus untuk mengganti gaya halaman pendaftaran bawaan",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Kunci situs",
|
"Site key": "Kunci situs",
|
||||||
"Site key - Tooltip": "Kunci situs atau kunci halaman web",
|
"Site key - Tooltip": "Kunci situs atau kunci halaman web",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Kunci",
|
"Keys": "Kunci",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Tautan",
|
"Link": "Tautan",
|
||||||
"Location": "Lokasi",
|
"Location": "Lokasi",
|
||||||
"Location - Tooltip": "Kota tempat tinggal",
|
"Location - Tooltip": "Kota tempat tinggal",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "送信",
|
"Sending": "送信",
|
||||||
"Submit and complete": "提出して完了してください"
|
"Submit and complete": "提出して完了してください"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "書き込み可能なデモサイトに移動しますか?",
|
"Go to writable demo site?": "書き込み可能なデモサイトに移動しますか?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "ホーム",
|
"Home": "ホーム",
|
||||||
"Home - Tooltip": "アプリケーションのホームページ",
|
"Home - Tooltip": "アプリケーションのホームページ",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "ユニークなランダム文字列",
|
"ID - Tooltip": "ユニークなランダム文字列",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "可能になっています",
|
"Is enabled": "可能になっています",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "パスワードが正しいことを確認してください",
|
"Password - Tooltip": "パスワードが正しいことを確認してください",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "パスワードのソルト",
|
"Password salt": "パスワードのソルト",
|
||||||
"Password salt - Tooltip": "ランダムパラメーターは、パスワードの暗号化に使用されます",
|
"Password salt - Tooltip": "ランダムパラメーターは、パスワードの暗号化に使用されます",
|
||||||
"Password type": "パスワードタイプ",
|
"Password type": "パスワードタイプ",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "編集モデル",
|
"Edit Model": "編集モデル",
|
||||||
"Model text": "モデルテキスト",
|
"Model text": "モデルテキスト",
|
||||||
"Model text - Tooltip": "Casbinのアクセス制御モデルには、ACL、RBAC、ABAC、RESTfulなどの組み込みモデルが含まれています。カスタムモデルも作成できます。詳細については、Casbinのウェブサイトをご覧ください",
|
"Model text - Tooltip": "Casbinのアクセス制御モデルには、ACL、RBAC、ABAC、RESTfulなどの組み込みモデルが含まれています。カスタムモデルも作成できます。詳細については、Casbinのウェブサイトをご覧ください",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "ルールを変更する",
|
"Modify rule": "ルールを変更する",
|
||||||
"New Organization": "新しい組織",
|
"New Organization": "新しい組織",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "ソフト削除",
|
"Soft deletion": "ソフト削除",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "購入",
|
"Buy": "購入",
|
||||||
"Buy Product": "製品を購入する",
|
"Buy Product": "製品を購入する",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "詳細",
|
"Detail": "詳細",
|
||||||
"Detail - Tooltip": "製品の詳細",
|
"Detail - Tooltip": "製品の詳細",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "テスト購入ページ。",
|
"Test buy page..": "テスト購入ページ。",
|
||||||
"There is no payment channel for this product.": "この製品には支払いチャネルがありません。",
|
"There is no payment channel for this product.": "この製品には支払いチャネルがありません。",
|
||||||
"This product is currently not in sale.": "この製品は現在販売されていません。",
|
"This product is currently not in sale.": "この製品は現在販売されていません。",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "サインアップ HTML - 編集",
|
"Signup HTML - Edit": "サインアップ HTML - 編集",
|
||||||
"Signup HTML - Tooltip": "デフォルトのサインアップページスタイルを置き換えるためのカスタムHTML",
|
"Signup HTML - Tooltip": "デフォルトのサインアップページスタイルを置き換えるためのカスタムHTML",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "サイトキー",
|
"Site key": "サイトキー",
|
||||||
"Site key - Tooltip": "サイトキー",
|
"Site key - Tooltip": "サイトキー",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "鍵",
|
"Keys": "鍵",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "リンク",
|
"Link": "リンク",
|
||||||
"Location": "場所",
|
"Location": "場所",
|
||||||
"Location - Tooltip": "居住都市",
|
"Location - Tooltip": "居住都市",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "전송하기",
|
"Sending": "전송하기",
|
||||||
"Submit and complete": "제출하고 완료하십시오"
|
"Submit and complete": "제출하고 완료하십시오"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "쓰기 가능한 데모 사이트로 이동하시겠습니까?",
|
"Go to writable demo site?": "쓰기 가능한 데모 사이트로 이동하시겠습니까?",
|
||||||
"Groups": "그룹",
|
"Groups": "그룹",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "집",
|
"Home": "집",
|
||||||
"Home - Tooltip": "어플리케이션 홈 페이지",
|
"Home - Tooltip": "어플리케이션 홈 페이지",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "유일한 랜덤 문자열",
|
"ID - Tooltip": "유일한 랜덤 문자열",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "활성화됩니다",
|
"Is enabled": "활성화됩니다",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "비밀번호가 올바른지 확인하세요",
|
"Password - Tooltip": "비밀번호가 올바른지 확인하세요",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "비밀번호 솔트",
|
"Password salt": "비밀번호 솔트",
|
||||||
"Password salt - Tooltip": "암호화에 사용되는 임의 매개변수",
|
"Password salt - Tooltip": "암호화에 사용되는 임의 매개변수",
|
||||||
"Password type": "암호 유형",
|
"Password type": "암호 유형",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "고급 편집기",
|
||||||
|
"Basic Editor": "기본 편집기",
|
||||||
"Edit Model": "편집 형태 모델",
|
"Edit Model": "편집 형태 모델",
|
||||||
"Model text": "모델 텍스트",
|
"Model text": "모델 텍스트",
|
||||||
"Model text - Tooltip": "Casbin 액세스 제어 모델은 ACL, RBAC, ABAC, RESTful 등의 내장된 모델을 포함하며 사용자 정의 모델도 만들 수 있습니다. 자세한 정보는 Casbin 웹 사이트를 방문하십시오",
|
"Model text - Tooltip": "Casbin 액세스 제어 모델은 ACL, RBAC, ABAC, RESTful 등의 내장된 모델을 포함하며 사용자 정의 모델도 만들 수 있습니다. 자세한 정보는 Casbin 웹 사이트를 방문하십시오",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "규칙 수정",
|
"Modify rule": "규칙 수정",
|
||||||
"New Organization": "새로운 조직",
|
"New Organization": "새로운 조직",
|
||||||
"Optional": "선택사항",
|
"Optional": "선택사항",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "소프트 삭제",
|
"Soft deletion": "소프트 삭제",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "구매하다",
|
"Buy": "구매하다",
|
||||||
"Buy Product": "제품을 구입하세요",
|
"Buy Product": "제품을 구입하세요",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "세부사항",
|
"Detail": "세부사항",
|
||||||
"Detail - Tooltip": "제품의 세부사항",
|
"Detail - Tooltip": "제품의 세부사항",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "시험 구매 페이지.",
|
"Test buy page..": "시험 구매 페이지.",
|
||||||
"There is no payment channel for this product.": "이 제품에 대한 결제 채널이 없습니다.",
|
"There is no payment channel for this product.": "이 제품에 대한 결제 채널이 없습니다.",
|
||||||
"This product is currently not in sale.": "이 제품은 현재 판매되지 않고 있습니다.",
|
"This product is currently not in sale.": "이 제품은 현재 판매되지 않고 있습니다.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "가입 HTML - 수정",
|
"Signup HTML - Edit": "가입 HTML - 수정",
|
||||||
"Signup HTML - Tooltip": "기본 가입 페이지 스타일을 바꾸기 위한 사용자 지정 HTML",
|
"Signup HTML - Tooltip": "기본 가입 페이지 스타일을 바꾸기 위한 사용자 지정 HTML",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "사이트 키",
|
"Site key": "사이트 키",
|
||||||
"Site key - Tooltip": "사이트 키",
|
"Site key - Tooltip": "사이트 키",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "열쇠",
|
"Keys": "열쇠",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "링크",
|
"Link": "링크",
|
||||||
"Location": "장소",
|
"Location": "장소",
|
||||||
"Location - Tooltip": "거주 도시",
|
"Location - Tooltip": "거주 도시",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Enviando",
|
"Sending": "Enviando",
|
||||||
"Submit and complete": "Enviar e concluir"
|
"Submit and complete": "Enviar e concluir"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Editar Executor",
|
"Edit Enforcer": "Editar Executor",
|
||||||
"New Enforcer": "Novo Executor"
|
"New Enforcer": "Novo Executor"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Acessar o site de demonstração gravável?",
|
"Go to writable demo site?": "Acessar o site de demonstração gravável?",
|
||||||
"Groups": "Grupos",
|
"Groups": "Grupos",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Página Inicial",
|
"Home": "Página Inicial",
|
||||||
"Home - Tooltip": "Página inicial do aplicativo",
|
"Home - Tooltip": "Página inicial do aplicativo",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "String única aleatória",
|
"ID - Tooltip": "String única aleatória",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identidade",
|
"Identity": "Identidade",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Está habilitado",
|
"Is enabled": "Está habilitado",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Certifique-se de que a senha está correta",
|
"Password - Tooltip": "Certifique-se de que a senha está correta",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Salt de senha",
|
"Password salt": "Salt de senha",
|
||||||
"Password salt - Tooltip": "Parâmetro aleatório usado para criptografia de senha",
|
"Password salt - Tooltip": "Parâmetro aleatório usado para criptografia de senha",
|
||||||
"Password type": "Tipo de senha",
|
"Password type": "Tipo de senha",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Editor Avançado",
|
||||||
|
"Basic Editor": "Editor Básico",
|
||||||
"Edit Model": "Editar Modelo",
|
"Edit Model": "Editar Modelo",
|
||||||
"Model text": "Texto do Modelo",
|
"Model text": "Texto do Modelo",
|
||||||
"Model text - Tooltip": "Modelo de controle de acesso Casbin, incluindo modelos incorporados como ACL, RBAC, ABAC, RESTful, etc. Você também pode criar modelos personalizados. Para obter mais informações, visite o site do Casbin",
|
"Model text - Tooltip": "Modelo de controle de acesso Casbin, incluindo modelos incorporados como ACL, RBAC, ABAC, RESTful, etc. Você também pode criar modelos personalizados. Para obter mais informações, visite o site do Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modificar regra",
|
"Modify rule": "Modificar regra",
|
||||||
"New Organization": "Nova Organização",
|
"New Organization": "Nova Organização",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Exclusão suave",
|
"Soft deletion": "Exclusão suave",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Comprar",
|
"Buy": "Comprar",
|
||||||
"Buy Product": "Comprar Produto",
|
"Buy Product": "Comprar Produto",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detalhe",
|
"Detail": "Detalhe",
|
||||||
"Detail - Tooltip": "Detalhes do produto",
|
"Detail - Tooltip": "Detalhes do produto",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Página de teste de compra...",
|
"Test buy page..": "Página de teste de compra...",
|
||||||
"There is no payment channel for this product.": "Não há canal de pagamento disponível para este produto.",
|
"There is no payment channel for this product.": "Não há canal de pagamento disponível para este produto.",
|
||||||
"This product is currently not in sale.": "Este produto não está disponível para venda no momento.",
|
"This product is currently not in sale.": "Este produto não está disponível para venda no momento.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Editar HTML de inscrição",
|
"Signup HTML - Edit": "Editar HTML de inscrição",
|
||||||
"Signup HTML - Tooltip": "HTML personalizado para substituir o estilo padrão da página de inscrição",
|
"Signup HTML - Tooltip": "HTML personalizado para substituir o estilo padrão da página de inscrição",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silencioso",
|
"Silent": "Silencioso",
|
||||||
"Site key": "Chave do site",
|
"Site key": "Chave do site",
|
||||||
"Site key - Tooltip": "Chave do site",
|
"Site key - Tooltip": "Chave do site",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Chaves",
|
"Keys": "Chaves",
|
||||||
"Language": "Idioma",
|
"Language": "Idioma",
|
||||||
"Language - Tooltip": "Idioma - Tooltip",
|
"Language - Tooltip": "Idioma - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Localização",
|
"Location": "Localização",
|
||||||
"Location - Tooltip": "Cidade de residência",
|
"Location - Tooltip": "Cidade de residência",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Отправка",
|
"Sending": "Отправка",
|
||||||
"Submit and complete": "Отправить и завершить"
|
"Submit and complete": "Отправить и завершить"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Редактировать контролёра доступа",
|
"Edit Enforcer": "Редактировать контролёра доступа",
|
||||||
"New Enforcer": "Новый контролёр доступа"
|
"New Enforcer": "Новый контролёр доступа"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Перейти на демонстрационный сайт для записи данных?",
|
"Go to writable demo site?": "Перейти на демонстрационный сайт для записи данных?",
|
||||||
"Groups": "Группы",
|
"Groups": "Группы",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Дом",
|
"Home": "Дом",
|
||||||
"Home - Tooltip": "Главная страница приложения",
|
"Home - Tooltip": "Главная страница приложения",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Уникальная случайная строка",
|
"ID - Tooltip": "Уникальная случайная строка",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Включен",
|
"Is enabled": "Включен",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Убедитесь, что пароль правильный",
|
"Password - Tooltip": "Убедитесь, что пароль правильный",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Соль пароля",
|
"Password salt": "Соль пароля",
|
||||||
"Password salt - Tooltip": "Случайный параметр, используемый для шифрования пароля",
|
"Password salt - Tooltip": "Случайный параметр, используемый для шифрования пароля",
|
||||||
"Password type": "Тип пароля",
|
"Password type": "Тип пароля",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Использовать SMS",
|
"Use SMS": "Использовать SMS",
|
||||||
"Use SMS verification code": "Использовать SMS код для проверки",
|
"Use SMS verification code": "Использовать SMS код для проверки",
|
||||||
"Use a recovery code": "Использовать код восстановления",
|
"Use a recovery code": "Использовать код восстановления",
|
||||||
"Verification failed": "Проверка не удалась",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Расширенный редактор",
|
||||||
|
"Basic Editor": "Базовый редактор",
|
||||||
"Edit Model": "Редактировать модель",
|
"Edit Model": "Редактировать модель",
|
||||||
"Model text": "Модельный текст",
|
"Model text": "Модельный текст",
|
||||||
"Model text - Tooltip": "Модель контроля доступа Casbin, включая встроенные модели, такие как ACL, RBAC, ABAC, RESTful и т. д. Вы также можете создавать свои собственные модели. Для получения дополнительной информации, пожалуйста, посетите веб-сайт Casbin",
|
"Model text - Tooltip": "Модель контроля доступа Casbin, включая встроенные модели, такие как ACL, RBAC, ABAC, RESTful и т. д. Вы также можете создавать свои собственные модели. Для получения дополнительной информации, пожалуйста, посетите веб-сайт Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Изменить правило",
|
"Modify rule": "Изменить правило",
|
||||||
"New Organization": "Новая организация",
|
"New Organization": "Новая организация",
|
||||||
"Optional": "Опционально",
|
"Optional": "Опционально",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Мягкое удаление",
|
"Soft deletion": "Мягкое удаление",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Купить",
|
"Buy": "Купить",
|
||||||
"Buy Product": "Купить продукт",
|
"Buy Product": "Купить продукт",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Деталь",
|
"Detail": "Деталь",
|
||||||
"Detail - Tooltip": "Деталь продукта",
|
"Detail - Tooltip": "Деталь продукта",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Страница для тестовой покупки.",
|
"Test buy page..": "Страница для тестовой покупки.",
|
||||||
"There is no payment channel for this product.": "Для этого продукта нет канала оплаты.",
|
"There is no payment channel for this product.": "Для этого продукта нет канала оплаты.",
|
||||||
"This product is currently not in sale.": "Этот продукт в настоящее время не продается.",
|
"This product is currently not in sale.": "Этот продукт в настоящее время не продается.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Регистрационная форма HTML - Редактировать",
|
"Signup HTML - Edit": "Регистрационная форма HTML - Редактировать",
|
||||||
"Signup HTML - Tooltip": "Пользовательский HTML для замены стиля стандартной страницы регистрации",
|
"Signup HTML - Tooltip": "Пользовательский HTML для замены стиля стандартной страницы регистрации",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Ключ сайта",
|
"Site key": "Ключ сайта",
|
||||||
"Site key - Tooltip": "Ключ сайта",
|
"Site key - Tooltip": "Ключ сайта",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Ключи",
|
"Keys": "Ключи",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Ссылка",
|
"Link": "Ссылка",
|
||||||
"Location": "Местоположение",
|
"Location": "Местоположение",
|
||||||
"Location - Tooltip": "Город проживания",
|
"Location - Tooltip": "Город проживания",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Odosielanie",
|
"Sending": "Odosielanie",
|
||||||
"Submit and complete": "Odoslať a dokončiť"
|
"Submit and complete": "Odoslať a dokončiť"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Upraviť vynútiteľa",
|
"Edit Enforcer": "Upraviť vynútiteľa",
|
||||||
"New Enforcer": "Nový vynútiteľ"
|
"New Enforcer": "Nový vynútiteľ"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Prejsť na zapisovateľnú demo stránku?",
|
"Go to writable demo site?": "Prejsť na zapisovateľnú demo stránku?",
|
||||||
"Groups": "Skupiny",
|
"Groups": "Skupiny",
|
||||||
"Groups - Tooltip": "Skupiny",
|
"Groups - Tooltip": "Skupiny",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Domov",
|
"Home": "Domov",
|
||||||
"Home - Tooltip": "Domovská stránka aplikácie",
|
"Home - Tooltip": "Domovská stránka aplikácie",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Jedinečný náhodný reťazec",
|
"ID - Tooltip": "Jedinečný náhodný reťazec",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identita",
|
"Identity": "Identita",
|
||||||
"Invitations": "Pozvánky",
|
"Invitations": "Pozvánky",
|
||||||
"Is enabled": "Je povolené",
|
"Is enabled": "Je povolené",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Uistite sa, že heslo je správne",
|
"Password - Tooltip": "Uistite sa, že heslo je správne",
|
||||||
"Password complexity options": "Možnosti zložitosti hesla",
|
"Password complexity options": "Možnosti zložitosti hesla",
|
||||||
"Password complexity options - Tooltip": "Rôzne kombinácie možností zložitosti hesla",
|
"Password complexity options - Tooltip": "Rôzne kombinácie možností zložitosti hesla",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Soľ hesla",
|
"Password salt": "Soľ hesla",
|
||||||
"Password salt - Tooltip": "Náhodný parameter používaný na šifrovanie hesla",
|
"Password salt - Tooltip": "Náhodný parameter používaný na šifrovanie hesla",
|
||||||
"Password type": "Typ hesla",
|
"Password type": "Typ hesla",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Použiť SMS",
|
"Use SMS": "Použiť SMS",
|
||||||
"Use SMS verification code": "Použiť overovací kód SMS",
|
"Use SMS verification code": "Použiť overovací kód SMS",
|
||||||
"Use a recovery code": "Použiť obnovovací kód",
|
"Use a recovery code": "Použiť obnovovací kód",
|
||||||
"Verification failed": "Overenie zlyhalo",
|
|
||||||
"Verify Code": "Overiť kód",
|
"Verify Code": "Overiť kód",
|
||||||
"Verify Password": "Overiť heslo",
|
"Verify Password": "Overiť heslo",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Rozšírený editor",
|
||||||
|
"Basic Editor": "Základný editor",
|
||||||
"Edit Model": "Upraviť model",
|
"Edit Model": "Upraviť model",
|
||||||
"Model text": "Text modelu",
|
"Model text": "Text modelu",
|
||||||
"Model text - Tooltip": "Model prístupu Casbin, vrátane vstavaných modelov ako ACL, RBAC, ABAC, RESTful, atď. Môžete tiež vytvoriť vlastné modely. Pre viac informácií navštívte web Casbin",
|
"Model text - Tooltip": "Model prístupu Casbin, vrátane vstavaných modelov ako ACL, RBAC, ABAC, RESTful, atď. Môžete tiež vytvoriť vlastné modely. Pre viac informácií navštívte web Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Upraviť pravidlo",
|
"Modify rule": "Upraviť pravidlo",
|
||||||
"New Organization": "Nová organizácia",
|
"New Organization": "Nová organizácia",
|
||||||
"Optional": "Voliteľné",
|
"Optional": "Voliteľné",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Výzva",
|
"Prompt": "Výzva",
|
||||||
"Required": "Povinné",
|
"Required": "Povinné",
|
||||||
"Soft deletion": "Mäkké vymazanie",
|
"Soft deletion": "Mäkké vymazanie",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Kúpiť",
|
"Buy": "Kúpiť",
|
||||||
"Buy Product": "Kúpiť produkt",
|
"Buy Product": "Kúpiť produkt",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail produktu",
|
"Detail - Tooltip": "Detail produktu",
|
||||||
"Dummy": "Vzorkový",
|
"Dummy": "Vzorkový",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Testovať stránku nákupu..",
|
"Test buy page..": "Testovať stránku nákupu..",
|
||||||
"There is no payment channel for this product.": "Pre tento produkt neexistuje platobný kanál.",
|
"There is no payment channel for this product.": "Pre tento produkt neexistuje platobný kanál.",
|
||||||
"This product is currently not in sale.": "Tento produkt momentálne nie je v predaji.",
|
"This product is currently not in sale.": "Tento produkt momentálne nie je v predaji.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Upraviť HTML registrácie",
|
"Signup HTML - Edit": "Upraviť HTML registrácie",
|
||||||
"Signup HTML - Tooltip": "Vlastné HTML na nahradenie predvoleného štýlu registračnej stránky",
|
"Signup HTML - Tooltip": "Vlastné HTML na nahradenie predvoleného štýlu registračnej stránky",
|
||||||
"Signup group": "Skupina registrácie",
|
"Signup group": "Skupina registrácie",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Tichý",
|
"Silent": "Tichý",
|
||||||
"Site key": "Kľúč stránky",
|
"Site key": "Kľúč stránky",
|
||||||
"Site key - Tooltip": "Kľúč stránky",
|
"Site key - Tooltip": "Kľúč stránky",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Kľúče",
|
"Keys": "Kľúče",
|
||||||
"Language": "Jazyk",
|
"Language": "Jazyk",
|
||||||
"Language - Tooltip": "Jazyk - Tooltip",
|
"Language - Tooltip": "Jazyk - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Odkaz",
|
"Link": "Odkaz",
|
||||||
"Location": "Miesto",
|
"Location": "Miesto",
|
||||||
"Location - Tooltip": "Mesto bydliska",
|
"Location - Tooltip": "Mesto bydliska",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Sending",
|
"Sending": "Sending",
|
||||||
"Submit and complete": "Submit and complete"
|
"Submit and complete": "Submit and complete"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Is enabled",
|
"Is enabled": "Is enabled",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Make sure the password is correct",
|
"Password - Tooltip": "Make sure the password is correct",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Edit Model",
|
"Edit Model": "Edit Model",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Gönderiliyor",
|
"Sending": "Gönderiliyor",
|
||||||
"Submit and complete": "Gönder ve Tamamla"
|
"Submit and complete": "Gönder ve Tamamla"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Go to writable demo site?",
|
"Go to writable demo site?": "Go to writable demo site?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Ana sayfa",
|
"Home": "Ana sayfa",
|
||||||
"Home - Tooltip": "Home page of the application",
|
"Home - Tooltip": "Home page of the application",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Unique random string",
|
"ID - Tooltip": "Unique random string",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Davetler",
|
"Invitations": "Davetler",
|
||||||
"Is enabled": "Aktif Mi?",
|
"Is enabled": "Aktif Mi?",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Şifrenizin doğru olduğundan emin olun",
|
"Password - Tooltip": "Şifrenizin doğru olduğundan emin olun",
|
||||||
"Password complexity options": "Şifre karmaşıklık seçenekleri",
|
"Password complexity options": "Şifre karmaşıklık seçenekleri",
|
||||||
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
"Password complexity options - Tooltip": "Different combinations of password complexity options",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Password salt",
|
"Password salt": "Password salt",
|
||||||
"Password salt - Tooltip": "Random parameter used for password encryption",
|
"Password salt - Tooltip": "Random parameter used for password encryption",
|
||||||
"Password type": "Password type",
|
"Password type": "Password type",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "SMS kullan",
|
"Use SMS": "SMS kullan",
|
||||||
"Use SMS verification code": "SMS doğrulama kodunu kullan",
|
"Use SMS verification code": "SMS doğrulama kodunu kullan",
|
||||||
"Use a recovery code": "Kurtarma kodu kullan",
|
"Use a recovery code": "Kurtarma kodu kullan",
|
||||||
"Verification failed": "Doğrulama başarısız",
|
|
||||||
"Verify Code": "Kodu doğrula",
|
"Verify Code": "Kodu doğrula",
|
||||||
"Verify Password": "Parolayı Doğrula",
|
"Verify Password": "Parolayı Doğrula",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Advanced Editor",
|
||||||
|
"Basic Editor": "Basic Editor",
|
||||||
"Edit Model": "Modeli Düzenle",
|
"Edit Model": "Modeli Düzenle",
|
||||||
"Model text": "Model text",
|
"Model text": "Model text",
|
||||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Modify rule",
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "New Organization",
|
"New Organization": "New Organization",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Gerekli",
|
"Required": "Gerekli",
|
||||||
"Soft deletion": "Soft deletion",
|
"Soft deletion": "Soft deletion",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Buy",
|
"Buy": "Buy",
|
||||||
"Buy Product": "Buy Product",
|
"Buy Product": "Buy Product",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Detail",
|
"Detail": "Detail",
|
||||||
"Detail - Tooltip": "Detail of product",
|
"Detail - Tooltip": "Detail of product",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Test buy page..",
|
"Test buy page..": "Test buy page..",
|
||||||
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
"There is no payment channel for this product.": "There is no payment channel for this product.",
|
||||||
"This product is currently not in sale.": "This product is currently not in sale.",
|
"This product is currently not in sale.": "This product is currently not in sale.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Signup HTML - Edit",
|
"Signup HTML - Edit": "Signup HTML - Edit",
|
||||||
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Silent",
|
"Silent": "Silent",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "Site key",
|
"Site key - Tooltip": "Site key",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Keys",
|
"Keys": "Keys",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "City of residence",
|
"Location - Tooltip": "City of residence",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Відправка",
|
"Sending": "Відправка",
|
||||||
"Submit and complete": "Надішліть і заповніть"
|
"Submit and complete": "Надішліть і заповніть"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Редагувати Enforcer",
|
"Edit Enforcer": "Редагувати Enforcer",
|
||||||
"New Enforcer": "Новий Enforcer"
|
"New Enforcer": "Новий Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Перейти на демонстраційний сайт для запису?",
|
"Go to writable demo site?": "Перейти на демонстраційний сайт для запису?",
|
||||||
"Groups": "Групи",
|
"Groups": "Групи",
|
||||||
"Groups - Tooltip": "Групи – підказка",
|
"Groups - Tooltip": "Групи – підказка",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "додому",
|
"Home": "додому",
|
||||||
"Home - Tooltip": "Домашня сторінка програми",
|
"Home - Tooltip": "Домашня сторінка програми",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Унікальний випадковий рядок",
|
"ID - Tooltip": "Унікальний випадковий рядок",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Ідентичність",
|
"Identity": "Ідентичність",
|
||||||
"Invitations": "Запрошення",
|
"Invitations": "Запрошення",
|
||||||
"Is enabled": "Увімкнено",
|
"Is enabled": "Увімкнено",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Переконайтеся, що пароль правильний",
|
"Password - Tooltip": "Переконайтеся, що пароль правильний",
|
||||||
"Password complexity options": "Параметри складності пароля",
|
"Password complexity options": "Параметри складності пароля",
|
||||||
"Password complexity options - Tooltip": "Різні комбінації параметрів складності пароля",
|
"Password complexity options - Tooltip": "Різні комбінації параметрів складності пароля",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Сіль пароля",
|
"Password salt": "Сіль пароля",
|
||||||
"Password salt - Tooltip": "Випадковий параметр, який використовується для шифрування пароля",
|
"Password salt - Tooltip": "Випадковий параметр, який використовується для шифрування пароля",
|
||||||
"Password type": "Тип пароля",
|
"Password type": "Тип пароля",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Використовуйте SMS",
|
"Use SMS": "Використовуйте SMS",
|
||||||
"Use SMS verification code": "Використовуйте код підтвердження SMS",
|
"Use SMS verification code": "Використовуйте код підтвердження SMS",
|
||||||
"Use a recovery code": "Використовуйте код відновлення",
|
"Use a recovery code": "Використовуйте код відновлення",
|
||||||
"Verification failed": "Не вдалося перевірити",
|
|
||||||
"Verify Code": "Підтвердити код",
|
"Verify Code": "Підтвердити код",
|
||||||
"Verify Password": "Підтвердіть пароль",
|
"Verify Password": "Підтвердіть пароль",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Розширений редактор",
|
||||||
|
"Basic Editor": "Базовий редактор",
|
||||||
"Edit Model": "Редагувати модель",
|
"Edit Model": "Редагувати модель",
|
||||||
"Model text": "Текст моделі",
|
"Model text": "Текст моделі",
|
||||||
"Model text - Tooltip": "Модель контролю доступу Casbin, включаючи такі вбудовані моделі, як ACL, RBAC, ABAC, RESTful тощо. Ви також можете створювати власні моделі. ",
|
"Model text - Tooltip": "Модель контролю доступу Casbin, включаючи такі вбудовані моделі, як ACL, RBAC, ABAC, RESTful тощо. Ви також можете створювати власні моделі. ",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Змінити правило",
|
"Modify rule": "Змінити правило",
|
||||||
"New Organization": "Нова організація",
|
"New Organization": "Нова організація",
|
||||||
"Optional": "Додатково",
|
"Optional": "Додатково",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Підкажіть",
|
"Prompt": "Підкажіть",
|
||||||
"Required": "вимагається",
|
"Required": "вимагається",
|
||||||
"Soft deletion": "М'яке видалення",
|
"Soft deletion": "М'яке видалення",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "купити",
|
"Buy": "купити",
|
||||||
"Buy Product": "Купити товар",
|
"Buy Product": "Купити товар",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Деталь",
|
"Detail": "Деталь",
|
||||||
"Detail - Tooltip": "Деталь продукту",
|
"Detail - Tooltip": "Деталь продукту",
|
||||||
"Dummy": "манекен",
|
"Dummy": "манекен",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Сторінка тестової покупки..",
|
"Test buy page..": "Сторінка тестової покупки..",
|
||||||
"There is no payment channel for this product.": "Для цього продукту немає платіжного каналу.",
|
"There is no payment channel for this product.": "Для цього продукту немає платіжного каналу.",
|
||||||
"This product is currently not in sale.": "Цей товар наразі відсутній у продажу.",
|
"This product is currently not in sale.": "Цей товар наразі відсутній у продажу.",
|
||||||
"USD": "доларів США",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Реєстраційний HTML - Редагувати",
|
"Signup HTML - Edit": "Реєстраційний HTML - Редагувати",
|
||||||
"Signup HTML - Tooltip": "Спеціальний HTML для заміни стилю сторінки реєстрації за умовчанням",
|
"Signup HTML - Tooltip": "Спеціальний HTML для заміни стилю сторінки реєстрації за умовчанням",
|
||||||
"Signup group": "Група реєстрації",
|
"Signup group": "Група реєстрації",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Мовчазний",
|
"Silent": "Мовчазний",
|
||||||
"Site key": "Ключ сайту",
|
"Site key": "Ключ сайту",
|
||||||
"Site key - Tooltip": "Ключ сайту",
|
"Site key - Tooltip": "Ключ сайту",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Ключі",
|
"Keys": "Ключі",
|
||||||
"Language": "Мова",
|
"Language": "Мова",
|
||||||
"Language - Tooltip": "Мова – підказка",
|
"Language - Tooltip": "Мова – підказка",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Посилання",
|
"Link": "Посилання",
|
||||||
"Location": "Місцезнаходження",
|
"Location": "Місцезнаходження",
|
||||||
"Location - Tooltip": "Місто проживання",
|
"Location - Tooltip": "Місто проживання",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "Gửi",
|
"Sending": "Gửi",
|
||||||
"Submit and complete": "Nộp và hoàn thành"
|
"Submit and complete": "Nộp và hoàn thành"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "Edit Enforcer",
|
"Edit Enforcer": "Edit Enforcer",
|
||||||
"New Enforcer": "New Enforcer"
|
"New Enforcer": "New Enforcer"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "Bạn có muốn đi đến trang demo có thể viết được không?",
|
"Go to writable demo site?": "Bạn có muốn đi đến trang demo có thể viết được không?",
|
||||||
"Groups": "Groups",
|
"Groups": "Groups",
|
||||||
"Groups - Tooltip": "Groups - Tooltip",
|
"Groups - Tooltip": "Groups - Tooltip",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "Nhà",
|
"Home": "Nhà",
|
||||||
"Home - Tooltip": "Trang chủ của ứng dụng",
|
"Home - Tooltip": "Trang chủ của ứng dụng",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "Chuỗi ngẫu nhiên độc nhất",
|
"ID - Tooltip": "Chuỗi ngẫu nhiên độc nhất",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "Identity",
|
"Identity": "Identity",
|
||||||
"Invitations": "Invitations",
|
"Invitations": "Invitations",
|
||||||
"Is enabled": "Đã được kích hoạt",
|
"Is enabled": "Đã được kích hoạt",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "Hãy đảm bảo rằng mật khẩu là chính xác",
|
"Password - Tooltip": "Hãy đảm bảo rằng mật khẩu là chính xác",
|
||||||
"Password complexity options": "Password complexity options",
|
"Password complexity options": "Password complexity options",
|
||||||
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
"Password complexity options - Tooltip": "Password complexity options - Tooltip",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "Muối mật khẩu",
|
"Password salt": "Muối mật khẩu",
|
||||||
"Password salt - Tooltip": "Tham số ngẫu nhiên được sử dụng để mã hóa mật khẩu",
|
"Password salt - Tooltip": "Tham số ngẫu nhiên được sử dụng để mã hóa mật khẩu",
|
||||||
"Password type": "Loại mật khẩu",
|
"Password type": "Loại mật khẩu",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "Use SMS",
|
"Use SMS": "Use SMS",
|
||||||
"Use SMS verification code": "Use SMS verification code",
|
"Use SMS verification code": "Use SMS verification code",
|
||||||
"Use a recovery code": "Use a recovery code",
|
"Use a recovery code": "Use a recovery code",
|
||||||
"Verification failed": "Verification failed",
|
|
||||||
"Verify Code": "Verify Code",
|
"Verify Code": "Verify Code",
|
||||||
"Verify Password": "Verify Password",
|
"Verify Password": "Verify Password",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "Secret Key"
|
"Secret Key": "Secret Key"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "Editor nâng cao",
|
||||||
|
"Basic Editor": "Editor cơ bản",
|
||||||
"Edit Model": "Sửa mô hình",
|
"Edit Model": "Sửa mô hình",
|
||||||
"Model text": "Văn bản mẫu",
|
"Model text": "Văn bản mẫu",
|
||||||
"Model text - Tooltip": "Mô hình kiểm soát truy cập Casbin, bao gồm các mô hình tích hợp như ACL, RBAC, ABAC, RESTful, v.v. Bạn cũng có thể tạo các mô hình tùy chỉnh. Để biết thêm thông tin, vui lòng truy cập trang web Casbin",
|
"Model text - Tooltip": "Mô hình kiểm soát truy cập Casbin, bao gồm các mô hình tích hợp như ACL, RBAC, ABAC, RESTful, v.v. Bạn cũng có thể tạo các mô hình tùy chỉnh. Để biết thêm thông tin, vui lòng truy cập trang web Casbin",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "Sửa đổi quy tắc",
|
"Modify rule": "Sửa đổi quy tắc",
|
||||||
"New Organization": "Tổ chức mới",
|
"New Organization": "Tổ chức mới",
|
||||||
"Optional": "Optional",
|
"Optional": "Optional",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "Prompt",
|
"Prompt": "Prompt",
|
||||||
"Required": "Required",
|
"Required": "Required",
|
||||||
"Soft deletion": "Xóa mềm",
|
"Soft deletion": "Xóa mềm",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
"Buy": "Mua",
|
"Buy": "Mua",
|
||||||
"Buy Product": "Mua sản phẩm",
|
"Buy Product": "Mua sản phẩm",
|
||||||
"CNY": "CNY",
|
|
||||||
"Detail": "Chi tiết",
|
"Detail": "Chi tiết",
|
||||||
"Detail - Tooltip": "Chi tiết sản phẩm",
|
"Detail - Tooltip": "Chi tiết sản phẩm",
|
||||||
"Dummy": "Dummy",
|
"Dummy": "Dummy",
|
||||||
@ -740,7 +761,6 @@
|
|||||||
"Test buy page..": "Trang mua thử.",
|
"Test buy page..": "Trang mua thử.",
|
||||||
"There is no payment channel for this product.": "Không có kênh thanh toán cho sản phẩm này.",
|
"There is no payment channel for this product.": "Không có kênh thanh toán cho sản phẩm này.",
|
||||||
"This product is currently not in sale.": "Sản phẩm này hiện không được bán.",
|
"This product is currently not in sale.": "Sản phẩm này hiện không được bán.",
|
||||||
"USD": "USD",
|
|
||||||
"WeChat Pay": "WeChat Pay"
|
"WeChat Pay": "WeChat Pay"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
@ -893,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "Đăng ký HTML - Chỉnh sửa",
|
"Signup HTML - Edit": "Đăng ký HTML - Chỉnh sửa",
|
||||||
"Signup HTML - Tooltip": "Trang HTML tùy chỉnh để thay thế phong cách trang đăng ký mặc định",
|
"Signup HTML - Tooltip": "Trang HTML tùy chỉnh để thay thế phong cách trang đăng ký mặc định",
|
||||||
"Signup group": "Signup group",
|
"Signup group": "Signup group",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "Im lặng",
|
"Silent": "Im lặng",
|
||||||
"Site key": "Khóa trang web",
|
"Site key": "Khóa trang web",
|
||||||
"Site key - Tooltip": "Khóa trang web",
|
"Site key - Tooltip": "Khóa trang web",
|
||||||
@ -1157,6 +1178,7 @@
|
|||||||
"Keys": "Chìa khóa",
|
"Keys": "Chìa khóa",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Language - Tooltip": "Language - Tooltip",
|
"Language - Tooltip": "Language - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "Liên kết",
|
"Link": "Liên kết",
|
||||||
"Location": "Vị trí",
|
"Location": "Vị trí",
|
||||||
"Location - Tooltip": "Thành phố cư trú",
|
"Location - Tooltip": "Thành phố cư trú",
|
||||||
|
@ -161,6 +161,18 @@
|
|||||||
"Sending": "发送中",
|
"Sending": "发送中",
|
||||||
"Submit and complete": "完成提交"
|
"Submit and complete": "完成提交"
|
||||||
},
|
},
|
||||||
|
"currency": {
|
||||||
|
"AUD": "AUD",
|
||||||
|
"CAD": "CAD",
|
||||||
|
"CHF": "CHF",
|
||||||
|
"CNY": "CNY",
|
||||||
|
"EUR": "EUR",
|
||||||
|
"GBP": "GBP",
|
||||||
|
"HKD": "HKD",
|
||||||
|
"JPY": "JPY",
|
||||||
|
"SGD": "SGD",
|
||||||
|
"USD": "USD"
|
||||||
|
},
|
||||||
"enforcer": {
|
"enforcer": {
|
||||||
"Edit Enforcer": "编辑Casbin执行器",
|
"Edit Enforcer": "编辑Casbin执行器",
|
||||||
"New Enforcer": "新建Casbin执行器"
|
"New Enforcer": "新建Casbin执行器"
|
||||||
@ -266,10 +278,13 @@
|
|||||||
"Go to writable demo site?": "跳转至可写演示站点?",
|
"Go to writable demo site?": "跳转至可写演示站点?",
|
||||||
"Groups": "群组",
|
"Groups": "群组",
|
||||||
"Groups - Tooltip": "组",
|
"Groups - Tooltip": "组",
|
||||||
|
"Hide password": "Hide password",
|
||||||
"Home": "首页",
|
"Home": "首页",
|
||||||
"Home - Tooltip": "应用的首页",
|
"Home - Tooltip": "应用的首页",
|
||||||
"ID": "ID",
|
"ID": "ID",
|
||||||
"ID - Tooltip": "唯一的随机字符串",
|
"ID - Tooltip": "唯一的随机字符串",
|
||||||
|
"IP whitelist": "IP whitelist",
|
||||||
|
"IP whitelist - Tooltip": "IP whitelist - Tooltip",
|
||||||
"Identity": "身份认证",
|
"Identity": "身份认证",
|
||||||
"Invitations": "邀请码",
|
"Invitations": "邀请码",
|
||||||
"Is enabled": "已启用",
|
"Is enabled": "已启用",
|
||||||
@ -312,6 +327,10 @@
|
|||||||
"Password - Tooltip": "请确认密码正确",
|
"Password - Tooltip": "请确认密码正确",
|
||||||
"Password complexity options": "密码复杂度选项",
|
"Password complexity options": "密码复杂度选项",
|
||||||
"Password complexity options - Tooltip": "密码复杂度组合,登录密码复杂度必须符合该规范",
|
"Password complexity options - Tooltip": "密码复杂度组合,登录密码复杂度必须符合该规范",
|
||||||
|
"Password obf key": "Password obf key",
|
||||||
|
"Password obf key - Tooltip": "Password obf key - Tooltip",
|
||||||
|
"Password obfuscator": "Password obfuscator",
|
||||||
|
"Password obfuscator - Tooltip": "Password obfuscator - Tooltip",
|
||||||
"Password salt": "密码Salt值",
|
"Password salt": "密码Salt值",
|
||||||
"Password salt - Tooltip": "用于密码加密的随机参数",
|
"Password salt - Tooltip": "用于密码加密的随机参数",
|
||||||
"Password type": "密码类型",
|
"Password type": "密码类型",
|
||||||
@ -559,7 +578,6 @@
|
|||||||
"Use SMS": "使用短信",
|
"Use SMS": "使用短信",
|
||||||
"Use SMS verification code": "使用手机或电子邮件发送验证码认证",
|
"Use SMS verification code": "使用手机或电子邮件发送验证码认证",
|
||||||
"Use a recovery code": "使用恢复代码",
|
"Use a recovery code": "使用恢复代码",
|
||||||
"Verification failed": "验证失败",
|
|
||||||
"Verify Code": "验证码",
|
"Verify Code": "验证码",
|
||||||
"Verify Password": "验证密码",
|
"Verify Password": "验证密码",
|
||||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "您已经启用多因素认证, 请点击 '发送验证码' 继续",
|
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "您已经启用多因素认证, 请点击 '发送验证码' 继续",
|
||||||
@ -574,6 +592,8 @@
|
|||||||
"Secret Key": "密钥"
|
"Secret Key": "密钥"
|
||||||
},
|
},
|
||||||
"model": {
|
"model": {
|
||||||
|
"Advanced Editor": "高级编辑器",
|
||||||
|
"Basic Editor": "基础编辑器",
|
||||||
"Edit Model": "编辑模型",
|
"Edit Model": "编辑模型",
|
||||||
"Model text": "模型文本",
|
"Model text": "模型文本",
|
||||||
"Model text - Tooltip": "Casbin访问控制模型,支持ACL、RBAC、ABAC、RESTful等内置模型,也可以自定义模型,具体请查看Casbin官网",
|
"Model text - Tooltip": "Casbin访问控制模型,支持ACL、RBAC、ABAC、RESTful等内置模型,也可以自定义模型,具体请查看Casbin官网",
|
||||||
@ -592,6 +612,8 @@
|
|||||||
"Modify rule": "修改规则",
|
"Modify rule": "修改规则",
|
||||||
"New Organization": "添加组织",
|
"New Organization": "添加组织",
|
||||||
"Optional": "可选",
|
"Optional": "可选",
|
||||||
|
"Password expire days": "Password expire days",
|
||||||
|
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||||
"Prompt": "提示",
|
"Prompt": "提示",
|
||||||
"Required": "必须",
|
"Required": "必须",
|
||||||
"Soft deletion": "软删除",
|
"Soft deletion": "软删除",
|
||||||
@ -709,7 +731,6 @@
|
|||||||
"Alipay": "支付宝",
|
"Alipay": "支付宝",
|
||||||
"Buy": "购买",
|
"Buy": "购买",
|
||||||
"Buy Product": "购买商品",
|
"Buy Product": "购买商品",
|
||||||
"CNY": "人民币",
|
|
||||||
"Detail": "详情",
|
"Detail": "详情",
|
||||||
"Detail - Tooltip": "商品详情",
|
"Detail - Tooltip": "商品详情",
|
||||||
"Dummy": "虚拟",
|
"Dummy": "虚拟",
|
||||||
@ -740,16 +761,7 @@
|
|||||||
"Test buy page..": "测试购买页面..",
|
"Test buy page..": "测试购买页面..",
|
||||||
"There is no payment channel for this product.": "该商品没有付款方式。",
|
"There is no payment channel for this product.": "该商品没有付款方式。",
|
||||||
"This product is currently not in sale.": "该商品目前未在售。",
|
"This product is currently not in sale.": "该商品目前未在售。",
|
||||||
"USD": "美元",
|
"WeChat Pay": "微信支付"
|
||||||
"WeChat Pay": "微信支付",
|
|
||||||
"EUR": "欧元",
|
|
||||||
"JPY": "日元",
|
|
||||||
"GBP": "英镑",
|
|
||||||
"AUD": "澳元",
|
|
||||||
"CAD": "加元",
|
|
||||||
"CHF": "瑞士法郎",
|
|
||||||
"HKD": "港币",
|
|
||||||
"SGD": "新加坡元"
|
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
"Access key": "访问密钥",
|
"Access key": "访问密钥",
|
||||||
@ -901,6 +913,7 @@
|
|||||||
"Signup HTML - Edit": "注册页面HTML - 编辑",
|
"Signup HTML - Edit": "注册页面HTML - 编辑",
|
||||||
"Signup HTML - Tooltip": "自定义HTML,用于替换默认的注册页面样式",
|
"Signup HTML - Tooltip": "自定义HTML,用于替换默认的注册页面样式",
|
||||||
"Signup group": "注册后的群组",
|
"Signup group": "注册后的群组",
|
||||||
|
"Signup group - Tooltip": "Signup group - Tooltip",
|
||||||
"Silent": "静默",
|
"Silent": "静默",
|
||||||
"Site key": "Site key",
|
"Site key": "Site key",
|
||||||
"Site key - Tooltip": "站点密钥",
|
"Site key - Tooltip": "站点密钥",
|
||||||
@ -1165,6 +1178,7 @@
|
|||||||
"Keys": "键",
|
"Keys": "键",
|
||||||
"Language": "语言",
|
"Language": "语言",
|
||||||
"Language - Tooltip": "语言 - Tooltip",
|
"Language - Tooltip": "语言 - Tooltip",
|
||||||
|
"Last change password time": "Last change password time",
|
||||||
"Link": "绑定",
|
"Link": "绑定",
|
||||||
"Location": "城市",
|
"Location": "城市",
|
||||||
"Location - Tooltip": "居住地址所在的城市",
|
"Location - Tooltip": "居住地址所在的城市",
|
||||||
|
@ -105,6 +105,18 @@ class MfaAccountTable extends React.Component {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("mfaAccount:Origin"),
|
||||||
|
dataIndex: "origin",
|
||||||
|
key: "origin",
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return (
|
||||||
|
<Input value={text} onChange={e => {
|
||||||
|
this.updateField(table, index, "origin", e.target.value);
|
||||||
|
}} />
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("mfaAccount:Secret Key"),
|
title: i18next.t("mfaAccount:Secret Key"),
|
||||||
dataIndex: "secretKey",
|
dataIndex: "secretKey",
|
||||||
@ -176,7 +188,7 @@ class MfaAccountTable extends React.Component {
|
|||||||
content={<CasdoorAppUrl accessToken={this.props.accessToken} />}
|
content={<CasdoorAppUrl accessToken={this.props.accessToken} />}
|
||||||
>
|
>
|
||||||
<Button type="primary" size="small">
|
<Button type="primary" size="small">
|
||||||
{i18next.t("general:Show URL")}
|
{i18next.t("general:URL")}
|
||||||
</Button>
|
</Button>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
@ -136,7 +136,7 @@ class SigninMethodTable extends React.Component {
|
|||||||
options = [
|
options = [
|
||||||
{id: "All", name: i18next.t("general:All")},
|
{id: "All", name: i18next.t("general:All")},
|
||||||
{id: "Non-LDAP", name: i18next.t("general:Non-LDAP")},
|
{id: "Non-LDAP", name: i18next.t("general:Non-LDAP")},
|
||||||
{id: "Hide-Password", name: i18next.t("general:Hide-Password")},
|
{id: "Hide password", name: i18next.t("general:Hide password")},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user