mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-08 09:01:00 +08:00
Compare commits
24 Commits
revert-310
...
v1.682.0
Author | SHA1 | Date | |
---|---|---|---|
c08f2b1f3f | |||
62bb257c6d | |||
230a77e3e3 | |||
dce0a96dea | |||
65563fa0cd | |||
f2a94f671a | |||
1460a0498f | |||
adc63ea726 | |||
0b8be016c5 | |||
986dcbbda1 | |||
7d3920fb1f | |||
b794ef87ee | |||
a0d6f2125e | |||
85cbb7d074 | |||
fdc1be9452 | |||
2bd7dabd33 | |||
9b9a58e7ac | |||
38e389e8c8 | |||
ab5fcf848e | |||
b4e51b4631 | |||
45e25acc80 | |||
97dcf24a91 | |||
4c0fff66ff | |||
e7230700e0 |
@ -21,6 +21,7 @@ originFrontend =
|
||||
staticBaseUrl = "https://cdn.casbin.org"
|
||||
isDemoMode = false
|
||||
batchSize = 100
|
||||
enableErrorMask = false
|
||||
enableGzip = true
|
||||
ldapServerPort = 389
|
||||
radiusServerPort = 1812
|
||||
|
@ -60,7 +60,6 @@ func (c *ApiController) Unlink() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if application == nil {
|
||||
c.ResponseError(c.T("link:You can't unlink yourself, you are not a member of any application"))
|
||||
return
|
||||
|
@ -257,7 +257,7 @@ func (c *ApiController) UploadResource() {
|
||||
fileType, _ = util.GetOwnerAndNameFromIdNoCheck(mimeType + "/")
|
||||
}
|
||||
|
||||
fullFilePath = object.GetTruncatedPath(provider, fullFilePath, 175)
|
||||
fullFilePath = object.GetTruncatedPath(provider, fullFilePath, 450)
|
||||
if tag != "avatar" && tag != "termsOfUse" && !strings.HasPrefix(tag, "idCard") {
|
||||
ext := filepath.Ext(filepath.Base(fullFilePath))
|
||||
index := len(fullFilePath) - len(ext)
|
||||
|
@ -289,6 +289,16 @@ func (c *ApiController) UpdateUser() {
|
||||
}
|
||||
}
|
||||
|
||||
if user.MfaEmailEnabled && user.Email == "" {
|
||||
c.ResponseError(c.T("user:MFA email is enabled but email is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
if user.MfaPhoneEnabled && user.Phone == "" {
|
||||
c.ResponseError(c.T("user:MFA phone is enabled but phone number is empty"))
|
||||
return
|
||||
}
|
||||
|
||||
if msg := object.CheckUpdateUser(oldUser, &user, c.GetAcceptLanguage()); msg != "" {
|
||||
c.ResponseError(msg)
|
||||
return
|
||||
|
@ -45,6 +45,13 @@ func (c *ApiController) ResponseOk(data ...interface{}) {
|
||||
|
||||
// ResponseError ...
|
||||
func (c *ApiController) ResponseError(error string, data ...interface{}) {
|
||||
enableErrorMask := conf.GetConfigBool("enableErrorMask")
|
||||
if enableErrorMask {
|
||||
if strings.HasPrefix(error, "The user: ") && strings.HasSuffix(error, " doesn't exist") || strings.HasPrefix(error, "用户: ") && strings.HasSuffix(error, "不存在") {
|
||||
error = c.T("check:password or code is incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
resp := &Response{Status: "error", Msg: error}
|
||||
c.ResponseJsonData(resp, data...)
|
||||
}
|
||||
|
@ -27,7 +27,18 @@ import (
|
||||
)
|
||||
|
||||
func deployStaticFiles(provider *object.Provider) {
|
||||
storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, provider.Endpoint)
|
||||
certificate := ""
|
||||
if provider.Category == "Storage" && provider.Type == "Casdoor" {
|
||||
cert, err := object.GetCert(util.GetId(provider.Owner, provider.Cert))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if cert == nil {
|
||||
panic(err)
|
||||
}
|
||||
certificate = cert.Certificate
|
||||
}
|
||||
storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, provider.Endpoint, certificate, provider.Content)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
6
go.mod
6
go.mod
@ -6,13 +6,13 @@ require (
|
||||
github.com/Masterminds/squirrel v1.5.3
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
|
||||
github.com/aws/aws-sdk-go v1.45.5
|
||||
github.com/beego/beego v1.12.13
|
||||
github.com/beego/beego v1.12.12
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/casbin/casbin/v2 v2.77.2
|
||||
github.com/casdoor/go-sms-sender v0.24.0
|
||||
github.com/casdoor/gomail/v2 v2.0.1
|
||||
github.com/casdoor/notify v0.45.0
|
||||
github.com/casdoor/oss v1.6.0
|
||||
github.com/casdoor/oss v1.8.0
|
||||
github.com/casdoor/xorm-adapter/v3 v3.1.0
|
||||
github.com/casvisor/casvisor-go-sdk v1.4.0
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
@ -30,7 +30,7 @@ require (
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||
github.com/go-webauthn/webauthn v0.6.0
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/google/uuid v1.4.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/lestrrat-go/jwx v1.2.29
|
||||
github.com/lib/pq v1.10.9
|
||||
|
13
go.sum
13
go.sum
@ -1052,8 +1052,8 @@ github.com/baidubce/bce-sdk-go v0.9.156 h1:f++WfptxGmSp5acsjl4kUxHpWDDccoFqkIrQK
|
||||
github.com/baidubce/bce-sdk-go v0.9.156/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/beego/beego v1.12.13 h1:g39O1LGLTiPejWVqQKK/TFGrroW9BCZQz6/pf4S8IRM=
|
||||
github.com/beego/beego v1.12.13/go.mod h1:QURFL1HldOcCZAxnc1cZ7wrplsYR5dKPHFjmk6WkLAs=
|
||||
github.com/beego/beego v1.12.12 h1:ARY1sNVSS23N0mEQIhSqRDTyyDlx95JY0V3GogBbZbQ=
|
||||
github.com/beego/beego v1.12.12/go.mod h1:QURFL1HldOcCZAxnc1cZ7wrplsYR5dKPHFjmk6WkLAs=
|
||||
github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
|
||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||
@ -1083,6 +1083,8 @@ github.com/casbin/casbin/v2 v2.28.3/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRt
|
||||
github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/casbin/casbin/v2 v2.77.2 h1:yQinn/w9x8AswiwqwtrXz93VU48R1aYTXdHEx4RI3jM=
|
||||
github.com/casbin/casbin/v2 v2.77.2/go.mod h1:mzGx0hYW9/ksOSpw3wNjk3NRAroq5VMFYUQ6G43iGPk=
|
||||
github.com/casdoor/casdoor-go-sdk v0.50.0 h1:bUYbz/MzJuWfLKJbJM0+U0YpYewAur+THp5TKnufWZM=
|
||||
github.com/casdoor/casdoor-go-sdk v0.50.0/go.mod h1:cMnkCQJgMYpgAlgEx8reSt1AVaDIQLcJ1zk5pzBaz+4=
|
||||
github.com/casdoor/go-reddit/v2 v2.1.0 h1:kIbfdJ7AA7H0uTQ8s0q4GGZqSS5V9wVE74RrXyD9XPs=
|
||||
github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc=
|
||||
github.com/casdoor/go-sms-sender v0.24.0 h1:LNLsce3EG/87I3JS6UiajF3LlQmdIiCgebEu0IE4wSM=
|
||||
@ -1091,8 +1093,8 @@ github.com/casdoor/gomail/v2 v2.0.1 h1:J+FG6x80s9e5lBHUn8Sv0Y56mud34KiWih5YdmudR
|
||||
github.com/casdoor/gomail/v2 v2.0.1/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q=
|
||||
github.com/casdoor/notify v0.45.0 h1:OlaFvcQFjGOgA4mRx07M8AH1gvb5xNo21mcqrVGlLgk=
|
||||
github.com/casdoor/notify v0.45.0/go.mod h1:wNHQu0tiDROMBIvz0j3Om3Lhd5yZ+AIfnFb8MYb8OLQ=
|
||||
github.com/casdoor/oss v1.6.0 h1:IOWrGLJ+VO82qS796eaRnzFPPA1Sn3cotYTi7O/VIlQ=
|
||||
github.com/casdoor/oss v1.6.0/go.mod h1:rJAWA0hLhtu94t6IRpotLUkXO1NWMASirywQYaGizJE=
|
||||
github.com/casdoor/oss v1.8.0 h1:uuyKhDIp7ydOtV4lpqhAY23Ban2Ln8La8+QT36CwylM=
|
||||
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/go.mod h1:4WTcUw+bTgBylGHeGHzTtBvuTXRS23dtwzFLl9tsgFM=
|
||||
github.com/casvisor/casvisor-go-sdk v1.4.0 h1:hbZEGGJ1cwdHFAxeXrMoNw6yha6Oyg2F0qQhBNCN/dg=
|
||||
@ -1460,8 +1462,9 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
|
||||
|
@ -91,6 +91,7 @@ type Application struct {
|
||||
CertPublicKey string `xorm:"-" json:"certPublicKey"`
|
||||
Tags []string `xorm:"mediumtext" json:"tags"`
|
||||
SamlAttributes []*SamlItem `xorm:"varchar(1000)" json:"samlAttributes"`
|
||||
IsShared bool `json:"isShared"`
|
||||
|
||||
ClientId string `xorm:"varchar(100)" json:"clientId"`
|
||||
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
|
||||
@ -123,9 +124,9 @@ func GetApplicationCount(owner, field, value string) (int64, error) {
|
||||
return session.Count(&Application{})
|
||||
}
|
||||
|
||||
func GetOrganizationApplicationCount(owner, Organization, field, value string) (int64, error) {
|
||||
func GetOrganizationApplicationCount(owner, organization, field, value string) (int64, error) {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
return session.Count(&Application{Organization: Organization})
|
||||
return session.Where("organization = ? or is_shared = ? ", organization, true).Count(&Application{})
|
||||
}
|
||||
|
||||
func GetApplications(owner string) ([]*Application, error) {
|
||||
@ -140,7 +141,7 @@ func GetApplications(owner string) ([]*Application, error) {
|
||||
|
||||
func GetOrganizationApplications(owner string, organization string) ([]*Application, error) {
|
||||
applications := []*Application{}
|
||||
err := ormer.Engine.Desc("created_time").Find(&applications, &Application{Organization: organization})
|
||||
err := ormer.Engine.Desc("created_time").Where("organization = ? or is_shared = ? ", organization, true).Find(&applications, &Application{})
|
||||
if err != nil {
|
||||
return applications, err
|
||||
}
|
||||
@ -162,7 +163,7 @@ func GetPaginationApplications(owner string, offset, limit int, field, value, so
|
||||
func GetPaginationOrganizationApplications(owner, organization string, offset, limit int, field, value, sortField, sortOrder string) ([]*Application, error) {
|
||||
applications := []*Application{}
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&applications, &Application{Organization: organization})
|
||||
err := session.Where("organization = ? or is_shared = ? ", organization, true).Find(&applications, &Application{})
|
||||
if err != nil {
|
||||
return applications, err
|
||||
}
|
||||
@ -337,12 +338,18 @@ func getApplication(owner string, name string) (*Application, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
application := Application{Owner: owner, Name: name}
|
||||
realApplicationName, sharedOrg := util.GetSharedOrgFromApp(name)
|
||||
|
||||
application := Application{Owner: owner, Name: realApplicationName}
|
||||
existed, err := ormer.Engine.Get(&application)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if application.IsShared && sharedOrg != "" {
|
||||
application.Organization = sharedOrg
|
||||
}
|
||||
|
||||
if existed {
|
||||
err = extendApplicationWithProviders(&application)
|
||||
if err != nil {
|
||||
@ -428,11 +435,18 @@ func GetApplicationByUserId(userId string) (application *Application, err error)
|
||||
|
||||
func GetApplicationByClientId(clientId string) (*Application, error) {
|
||||
application := Application{}
|
||||
existed, err := ormer.Engine.Where("client_id=?", clientId).Get(&application)
|
||||
|
||||
realClientId, sharedOrg := util.GetSharedOrgFromApp(clientId)
|
||||
|
||||
existed, err := ormer.Engine.Where("client_id=?", realClientId).Get(&application)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if application.IsShared && sharedOrg != "" {
|
||||
application.Organization = sharedOrg
|
||||
}
|
||||
|
||||
if existed {
|
||||
err = extendApplicationWithProviders(&application)
|
||||
if err != nil {
|
||||
@ -626,6 +640,10 @@ func UpdateApplication(id string, application *Application) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if application.IsShared == true && application.Organization != "built-in" {
|
||||
return false, fmt.Errorf("only applications belonging to built-in organization can be shared")
|
||||
}
|
||||
|
||||
for _, providerItem := range application.Providers {
|
||||
providerItem.Provider = nil
|
||||
}
|
||||
|
@ -52,6 +52,9 @@ func GetFailedSigninConfigByUser(user *User) (int, int, error) {
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if application == nil {
|
||||
return 0, 0, fmt.Errorf("the application for user %s is not found", user.GetId())
|
||||
}
|
||||
|
||||
failedSigninLimit := application.FailedSigninLimit
|
||||
if failedSigninLimit == 0 {
|
||||
|
@ -32,6 +32,7 @@ type Ldap struct {
|
||||
BaseDn string `xorm:"varchar(100)" json:"baseDn"`
|
||||
Filter string `xorm:"varchar(200)" json:"filter"`
|
||||
FilterFields []string `xorm:"varchar(100)" json:"filterFields"`
|
||||
DefaultGroup string `xorm:"varchar(100)" json:"defaultGroup"`
|
||||
|
||||
AutoSync int `json:"autoSync"`
|
||||
LastSync string `xorm:"varchar(100)" json:"lastSync"`
|
||||
@ -148,7 +149,7 @@ func UpdateLdap(ldap *Ldap) (bool, error) {
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.ID(ldap.Id).Cols("owner", "server_name", "host",
|
||||
"port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync").Update(ldap)
|
||||
"port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync", "default_group").Update(ldap)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
@ -339,6 +339,10 @@ func SyncLdapUsers(owner string, syncUsers []LdapUser, ldapId string) (existUser
|
||||
Ldap: syncUser.Uuid,
|
||||
}
|
||||
|
||||
if ldap.DefaultGroup != "" {
|
||||
newUser.Groups = []string{ldap.DefaultGroup}
|
||||
}
|
||||
|
||||
affected, err := AddUser(newUser)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -319,6 +319,7 @@ func GetDefaultApplication(id string) (*Application, error) {
|
||||
if defaultApplication == nil {
|
||||
return nil, fmt.Errorf("The default application: %s does not exist", organization.DefaultApplication)
|
||||
} else {
|
||||
defaultApplication.Organization = organization.Name
|
||||
return defaultApplication, nil
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ type Resource struct {
|
||||
FileType string `xorm:"varchar(100)" json:"fileType"`
|
||||
FileFormat string `xorm:"varchar(100)" json:"fileFormat"`
|
||||
FileSize int `json:"fileSize"`
|
||||
Url string `xorm:"varchar(255)" json:"url"`
|
||||
Url string `xorm:"varchar(500)" json:"url"`
|
||||
Description string `xorm:"varchar(255)" json:"description"`
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,13 @@ import (
|
||||
|
||||
var isCloudIntranet bool
|
||||
|
||||
const (
|
||||
ProviderTypeGoogleCloudStorage = "Google Cloud Storage"
|
||||
ProviderTypeTencentCloudCOS = "Tencent Cloud COS"
|
||||
ProviderTypeAzureBlob = "Azure Blob"
|
||||
ProviderTypeLocalFileSystem = "Local File System"
|
||||
)
|
||||
|
||||
func init() {
|
||||
isCloudIntranet = conf.GetConfigBool("isCloudIntranet")
|
||||
}
|
||||
@ -80,27 +87,28 @@ func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool
|
||||
objectKey := util.UrlJoin(util.GetUrlPath(provider.Domain), escapedPath)
|
||||
|
||||
host := ""
|
||||
if provider.Type != "Local File System" {
|
||||
if provider.Type != ProviderTypeLocalFileSystem {
|
||||
// provider.Domain = "https://cdn.casbin.com/casdoor/"
|
||||
host = util.GetUrlHost(provider.Domain)
|
||||
} else {
|
||||
// provider.Domain = "http://localhost:8000" or "https://door.casdoor.com"
|
||||
host = util.UrlJoin(provider.Domain, "/files")
|
||||
}
|
||||
if provider.Type == "Azure Blob" {
|
||||
if provider.Type == ProviderTypeAzureBlob || provider.Type == ProviderTypeGoogleCloudStorage {
|
||||
host = util.UrlJoin(host, provider.Bucket)
|
||||
}
|
||||
|
||||
fileUrl := ""
|
||||
if host != "" {
|
||||
fileUrl = util.UrlJoin(host, escapePath(objectKey))
|
||||
// fileUrl = util.UrlJoin(host, escapePath(objectKey))
|
||||
fileUrl = util.UrlJoin(host, objectKey)
|
||||
}
|
||||
|
||||
if fileUrl != "" && hasTimestamp {
|
||||
fileUrl = fmt.Sprintf("%s?t=%s", fileUrl, util.GetCurrentUnixTime())
|
||||
}
|
||||
// if fileUrl != "" && hasTimestamp {
|
||||
// fileUrl = fmt.Sprintf("%s?t=%s", fileUrl, util.GetCurrentUnixTime())
|
||||
// }
|
||||
|
||||
if provider.Type == "Tencent Cloud COS" {
|
||||
if provider.Type == ProviderTypeTencentCloudCOS {
|
||||
objectKey = escapePath(objectKey)
|
||||
}
|
||||
|
||||
@ -109,7 +117,18 @@ func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool
|
||||
|
||||
func getStorageProvider(provider *Provider, lang string) (oss.StorageInterface, error) {
|
||||
endpoint := getProviderEndpoint(provider)
|
||||
storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
|
||||
certificate := ""
|
||||
if provider.Category == "Storage" && provider.Type == "Casdoor" {
|
||||
cert, err := GetCert(util.GetId(provider.Owner, provider.Cert))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cert == nil {
|
||||
return nil, fmt.Errorf("no cert for %s", provider.Cert)
|
||||
}
|
||||
certificate = cert.Certificate
|
||||
}
|
||||
storageProvider, err := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint, certificate, provider.Content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -135,17 +154,17 @@ func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffe
|
||||
}
|
||||
|
||||
fileUrl, objectKey := GetUploadFileUrl(provider, fullFilePath, true)
|
||||
objectKeyRefined := refineObjectKey(provider, objectKey)
|
||||
|
||||
objectKeyRefined := objectKey
|
||||
if provider.Type == "Google Cloud Storage" {
|
||||
objectKeyRefined = strings.TrimPrefix(objectKeyRefined, "/")
|
||||
}
|
||||
|
||||
_, err = storageProvider.Put(objectKeyRefined, fileBuffer)
|
||||
object, err := storageProvider.Put(objectKeyRefined, fileBuffer)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if provider.Type == "Casdoor" {
|
||||
fileUrl = object.Path
|
||||
}
|
||||
|
||||
return fileUrl, objectKey, nil
|
||||
}
|
||||
|
||||
@ -184,5 +203,13 @@ func DeleteFile(provider *Provider, objectKey string, lang string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return storageProvider.Delete(objectKey)
|
||||
objectKeyRefined := refineObjectKey(provider, objectKey)
|
||||
return storageProvider.Delete(objectKeyRefined)
|
||||
}
|
||||
|
||||
func refineObjectKey(provider *Provider, objectKey string) string {
|
||||
if provider.Type == ProviderTypeGoogleCloudStorage {
|
||||
return strings.TrimPrefix(objectKey, "/")
|
||||
}
|
||||
return objectKey
|
||||
}
|
||||
|
@ -277,7 +277,6 @@ func GetValidationBySaml(samlRequest string, host string) (string, string, error
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if application == nil {
|
||||
return "", "", fmt.Errorf("the application for user %s is not found", userId)
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ type UserWithoutThirdIdp struct {
|
||||
LastSigninWrongTime string `xorm:"varchar(100)" json:"lastSigninWrongTime"`
|
||||
SigninWrongTimes int `json:"signinWrongTimes"`
|
||||
|
||||
// ManagedAccounts []ManagedAccount `xorm:"managedAccounts blob" json:"managedAccounts"`
|
||||
ManagedAccounts []ManagedAccount `xorm:"managedAccounts blob" json:"managedAccounts"`
|
||||
}
|
||||
|
||||
type ClaimsShort struct {
|
||||
@ -254,6 +254,8 @@ func getUserWithoutThirdIdp(user *User) *UserWithoutThirdIdp {
|
||||
|
||||
LastSigninWrongTime: user.LastSigninWrongTime,
|
||||
SigninWrongTimes: user.SigninWrongTimes,
|
||||
|
||||
ManagedAccounts: user.ManagedAccounts,
|
||||
}
|
||||
|
||||
return res
|
||||
@ -365,6 +367,10 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
||||
},
|
||||
}
|
||||
|
||||
if application.IsShared {
|
||||
claims.Audience = []string{application.ClientId + "-org-" + user.Owner}
|
||||
}
|
||||
|
||||
var token *jwt.Token
|
||||
var refreshToken *jwt.Token
|
||||
|
||||
|
@ -428,22 +428,26 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
if token == nil {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "authorization code is invalid",
|
||||
ErrorDescription: fmt.Sprintf("authorization code: [%s] is invalid", code),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if token.CodeIsUsed {
|
||||
// anti replay attacks
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "authorization code has been used",
|
||||
ErrorDescription: fmt.Sprintf("authorization code has been used for token: [%s]", token.GetId()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if token.CodeChallenge != "" && pkceChallenge(verifier) != token.CodeChallenge {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "verifier is invalid",
|
||||
}, nil
|
||||
if token.CodeChallenge != "" {
|
||||
challengeAnswer := pkceChallenge(verifier)
|
||||
if challengeAnswer != token.CodeChallenge {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: fmt.Sprintf("verifier is invalid, challengeAnswer: [%s], token.CodeChallenge: [%s]", challengeAnswer, token.CodeChallenge),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if application.ClientSecret != clientSecret {
|
||||
@ -452,13 +456,13 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
if token.CodeChallenge == "" {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_secret is invalid",
|
||||
ErrorDescription: fmt.Sprintf("client_secret is invalid for application: [%s], token.CodeChallenge: empty", application.GetId()),
|
||||
}, nil
|
||||
} else {
|
||||
if clientSecret != "" {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_secret is invalid",
|
||||
ErrorDescription: fmt.Sprintf("client_secret is invalid for application: [%s], token.CodeChallenge: [%s]", application.GetId(), token.CodeChallenge),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
@ -467,15 +471,16 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
if application.Name != token.Application {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the token is for wrong application (client_id)",
|
||||
ErrorDescription: fmt.Sprintf("the token is for wrong application (client_id), application.Name: [%s], token.Application: [%s]", application.Name, token.Application),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if time.Now().Unix() > token.CodeExpireIn {
|
||||
nowUnix := time.Now().Unix()
|
||||
if nowUnix > token.CodeExpireIn {
|
||||
// code must be used within 5 minutes
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "authorization code has expired",
|
||||
ErrorDescription: fmt.Sprintf("authorization code has expired, nowUnix: [%s], token.CodeExpireIn: [%s]", time.Unix(nowUnix, 0).Format(time.RFC3339), time.Unix(token.CodeExpireIn, 0).Format(time.RFC3339)),
|
||||
}, nil
|
||||
}
|
||||
return token, nil, nil
|
||||
|
@ -1138,7 +1138,7 @@ func (user *User) IsApplicationAdmin(application *Application) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return (user.Owner == application.Organization && user.IsAdmin) || user.IsGlobalAdmin()
|
||||
return (user.Owner == application.Organization && user.IsAdmin) || user.IsGlobalAdmin() || (user.IsAdmin && application.IsShared)
|
||||
}
|
||||
|
||||
func (user *User) IsGlobalAdmin() bool {
|
||||
|
@ -56,7 +56,7 @@ func getSubject(ctx *context.Context) (string, string) {
|
||||
return util.GetOwnerAndNameFromId(username)
|
||||
}
|
||||
|
||||
func getObject(ctx *context.Context) (string, string) {
|
||||
func getObject(ctx *context.Context) (string, string, error) {
|
||||
method := ctx.Request.Method
|
||||
path := ctx.Request.URL.Path
|
||||
|
||||
@ -65,13 +65,13 @@ func getObject(ctx *context.Context) (string, string) {
|
||||
if ctx.Input.Query("id") == "/" {
|
||||
adapterId := ctx.Input.Query("adapterId")
|
||||
if adapterId != "" {
|
||||
return util.GetOwnerAndNameFromIdNoCheck(adapterId)
|
||||
return util.GetOwnerAndNameFromIdWithError(adapterId)
|
||||
}
|
||||
} else {
|
||||
// query == "?id=built-in/admin"
|
||||
id := ctx.Input.Query("id")
|
||||
if id != "" {
|
||||
return util.GetOwnerAndNameFromIdNoCheck(id)
|
||||
return util.GetOwnerAndNameFromIdWithError(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,34 +80,34 @@ func getObject(ctx *context.Context) (string, string) {
|
||||
// query == "?id=built-in/admin"
|
||||
id := ctx.Input.Query("id")
|
||||
if id != "" {
|
||||
return util.GetOwnerAndNameFromIdNoCheck(id)
|
||||
return util.GetOwnerAndNameFromIdWithError(id)
|
||||
}
|
||||
}
|
||||
|
||||
owner := ctx.Input.Query("owner")
|
||||
if owner != "" {
|
||||
return owner, ""
|
||||
return owner, "", nil
|
||||
}
|
||||
|
||||
return "", ""
|
||||
return "", "", nil
|
||||
} else {
|
||||
if path == "/api/add-policy" || path == "/api/remove-policy" || path == "/api/update-policy" {
|
||||
id := ctx.Input.Query("id")
|
||||
if id != "" {
|
||||
return util.GetOwnerAndNameFromIdNoCheck(id)
|
||||
return util.GetOwnerAndNameFromIdWithError(id)
|
||||
}
|
||||
}
|
||||
|
||||
body := ctx.Input.RequestBody
|
||||
if len(body) == 0 {
|
||||
return ctx.Request.Form.Get("owner"), ctx.Request.Form.Get("name")
|
||||
return ctx.Request.Form.Get("owner"), ctx.Request.Form.Get("name"), nil
|
||||
}
|
||||
|
||||
var obj Object
|
||||
err := json.Unmarshal(body, &obj)
|
||||
if err != nil {
|
||||
// panic(err)
|
||||
return "", ""
|
||||
// this is not error
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
if path == "/api/delete-resource" {
|
||||
@ -117,7 +117,7 @@ func getObject(ctx *context.Context) (string, string) {
|
||||
}
|
||||
}
|
||||
|
||||
return obj.Owner, obj.Name
|
||||
return obj.Owner, obj.Name, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,7 +183,12 @@ func ApiFilter(ctx *context.Context) {
|
||||
|
||||
objOwner, objName := "", ""
|
||||
if urlPath != "/api/get-app-login" && urlPath != "/api/get-resource" {
|
||||
objOwner, objName = getObject(ctx)
|
||||
var err error
|
||||
objOwner, objName, err = getObject(ctx)
|
||||
if err != nil {
|
||||
responseError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(urlPath, "/api/notify-payment") {
|
||||
|
@ -67,6 +67,17 @@ func AutoSigninFilter(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
accessKey := ctx.Input.Query("accessKey")
|
||||
accessSecret := ctx.Input.Query("accessSecret")
|
||||
if accessKey != "" && accessSecret != "" {
|
||||
userId, err := getUsernameByKeys(ctx)
|
||||
if err != nil {
|
||||
responseError(ctx, err.Error())
|
||||
}
|
||||
|
||||
setSessionUser(ctx, userId)
|
||||
}
|
||||
|
||||
// "/page?clientId=123&clientSecret=456"
|
||||
userId, err := getUsernameByClientIdSecret(ctx)
|
||||
if err != nil {
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego/context"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/i18n"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@ -126,7 +125,7 @@ func setSessionUser(ctx *context.Context, user string) {
|
||||
}
|
||||
|
||||
// https://github.com/beego/beego/issues/3445#issuecomment-455411915
|
||||
ctx.Input.CruSession.SessionReleaseIfPresent(ctx.ResponseWriter)
|
||||
ctx.Input.CruSession.SessionRelease(ctx.ResponseWriter)
|
||||
}
|
||||
|
||||
func setSessionExpire(ctx *context.Context, ExpireTime int64) {
|
||||
@ -135,7 +134,7 @@ func setSessionExpire(ctx *context.Context, ExpireTime int64) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ctx.Input.CruSession.SessionReleaseIfPresent(ctx.ResponseWriter)
|
||||
ctx.Input.CruSession.SessionRelease(ctx.ResponseWriter)
|
||||
}
|
||||
|
||||
func setSessionOidc(ctx *context.Context, scope string, aud string) {
|
||||
@ -147,7 +146,7 @@ func setSessionOidc(ctx *context.Context, scope string, aud string) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ctx.Input.CruSession.SessionReleaseIfPresent(ctx.ResponseWriter)
|
||||
ctx.Input.CruSession.SessionRelease(ctx.ResponseWriter)
|
||||
}
|
||||
|
||||
func parseBearerToken(ctx *context.Context) string {
|
||||
|
19
storage/casdoor.go
Normal file
19
storage/casdoor.go
Normal file
@ -0,0 +1,19 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"github.com/casdoor/oss"
|
||||
"github.com/casdoor/oss/casdoor"
|
||||
)
|
||||
|
||||
func NewCasdoorStorageProvider(providerType string, clientId string, clientSecret string, region string, bucket string, endpoint string, cert string, content string) oss.StorageInterface {
|
||||
sp := casdoor.New(&casdoor.Config{
|
||||
clientId,
|
||||
clientSecret,
|
||||
endpoint,
|
||||
cert,
|
||||
region,
|
||||
content,
|
||||
bucket,
|
||||
})
|
||||
return sp
|
||||
}
|
@ -16,7 +16,7 @@ package storage
|
||||
|
||||
import "github.com/casdoor/oss"
|
||||
|
||||
func GetStorageProvider(providerType string, clientId string, clientSecret string, region string, bucket string, endpoint string) (oss.StorageInterface, error) {
|
||||
func GetStorageProvider(providerType string, clientId string, clientSecret string, region string, bucket string, endpoint string, cert string, content string) (oss.StorageInterface, error) {
|
||||
switch providerType {
|
||||
case "Local File System":
|
||||
return NewLocalFileSystemStorageProvider(), nil
|
||||
@ -36,6 +36,8 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin
|
||||
return NewGoogleCloudStorageProvider(clientSecret, bucket, endpoint), nil
|
||||
case "Synology":
|
||||
return NewSynologyNasStorageProvider(clientId, clientSecret, endpoint), nil
|
||||
case "Casdoor":
|
||||
return NewCasdoorStorageProvider(providerType, clientId, clientSecret, region, bucket, endpoint, cert, content), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
@ -131,6 +131,15 @@ func GetOwnerAndNameFromId(id string) (string, string) {
|
||||
return tokens[0], tokens[1]
|
||||
}
|
||||
|
||||
func GetOwnerAndNameFromIdWithError(id string) (string, string, error) {
|
||||
tokens := strings.Split(id, "/")
|
||||
if len(tokens) != 2 {
|
||||
return "", "", errors.New("GetOwnerAndNameFromId() error, wrong token count for ID: " + id)
|
||||
}
|
||||
|
||||
return tokens[0], tokens[1], nil
|
||||
}
|
||||
|
||||
func GetOwnerFromId(id string) string {
|
||||
tokens := strings.Split(id, "/")
|
||||
if len(tokens) != 2 {
|
||||
@ -154,6 +163,16 @@ func GetOwnerAndNameAndOtherFromId(id string) (string, string, string) {
|
||||
return tokens[0], tokens[1], tokens[2]
|
||||
}
|
||||
|
||||
func GetSharedOrgFromApp(rawName string) (name string, organization string) {
|
||||
name = rawName
|
||||
splitName := strings.Split(rawName, "-org-")
|
||||
if len(splitName) >= 2 {
|
||||
organization = splitName[len(splitName)-1]
|
||||
name = splitName[0]
|
||||
}
|
||||
return name, organization
|
||||
}
|
||||
|
||||
func GenerateId() string {
|
||||
return uuid.NewString()
|
||||
}
|
||||
|
@ -56,9 +56,11 @@ class AdapterListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -344,7 +344,8 @@ class App extends Component {
|
||||
window.location.pathname.startsWith("/cas") ||
|
||||
window.location.pathname.startsWith("/select-plan") ||
|
||||
window.location.pathname.startsWith("/buy-plan") ||
|
||||
window.location.pathname.startsWith("/qrcode") ;
|
||||
window.location.pathname.startsWith("/qrcode") ||
|
||||
window.location.pathname.startsWith("/captcha");
|
||||
}
|
||||
|
||||
onClick = ({key}) => {
|
||||
|
@ -116,7 +116,6 @@ class ApplicationEditPage extends React.Component {
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getApplication();
|
||||
this.getOrganizations();
|
||||
this.getProviders();
|
||||
}
|
||||
|
||||
getApplication() {
|
||||
@ -145,7 +144,9 @@ class ApplicationEditPage extends React.Component {
|
||||
application: application,
|
||||
});
|
||||
|
||||
this.getCerts(application.organization);
|
||||
this.getProviders(application);
|
||||
|
||||
this.getCerts(application);
|
||||
|
||||
this.getSamlMetadata(application.enableSamlPostBinding);
|
||||
});
|
||||
@ -166,7 +167,11 @@ class ApplicationEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getCerts(owner) {
|
||||
getCerts(application) {
|
||||
let owner = application.organization;
|
||||
if (application.isShared) {
|
||||
owner = this.props.owner;
|
||||
}
|
||||
CertBackend.getCerts(owner)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
@ -175,8 +180,12 @@ class ApplicationEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getProviders() {
|
||||
ProviderBackend.getProviders(this.state.owner)
|
||||
getProviders(application) {
|
||||
let owner = application.organization;
|
||||
if (application.isShared) {
|
||||
owner = this.props.account.owner;
|
||||
}
|
||||
ProviderBackend.getProviders(owner)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
@ -263,6 +272,16 @@ class ApplicationEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Is shared"), i18next.t("general:Is shared - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Switch disabled={Setting.isAdminUser()} checked={this.state.application.isShared} onChange={checked => {
|
||||
this.updateApplicationField("isShared", checked);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Logo"), i18next.t("general:Logo - Tooltip"))} :
|
||||
@ -989,7 +1008,11 @@ class ApplicationEditPage extends React.Component {
|
||||
redirectUri = "\"ERROR: You must specify at least one Redirect URL in 'Redirect URLs'\"";
|
||||
}
|
||||
|
||||
const signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${redirectUri}&scope=read&state=casdoor`;
|
||||
let clientId = this.state.application.clientId;
|
||||
if (this.state.application.isShared) {
|
||||
clientId += `-org-${this.props.account.owner}`;
|
||||
}
|
||||
const signInUrl = `/login/oauth/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&scope=read&state=casdoor`;
|
||||
const maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "97%", width: "100%", background: "rgba(0,0,0,0.4)"};
|
||||
if (!Setting.isPasswordEnabled(this.state.application)) {
|
||||
signUpUrl = signInUrl.replace("/login/oauth/authorize", "/signup/oauth/authorize");
|
||||
|
@ -97,9 +97,11 @@ class ApplicationListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
@ -123,7 +125,7 @@ class ApplicationListPage extends BaseListPage {
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Link to={`/applications/${record.organization}/${text}`}>
|
||||
{text}
|
||||
{Setting.getApplicationDisplayName(record)}
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
|
116
web/src/CaptchaPage.js
Normal file
116
web/src/CaptchaPage.js
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {CaptchaModal} from "./common/modal/CaptchaModal";
|
||||
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||
import * as Setting from "./Setting";
|
||||
|
||||
class CaptchaPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const params = new URLSearchParams(this.props.location.search);
|
||||
this.state = {
|
||||
owner: "admin",
|
||||
application: null,
|
||||
clientId: params.get("client_id"),
|
||||
applicationName: params.get("state"),
|
||||
redirectUri: params.get("redirect_uri"),
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getApplication();
|
||||
}
|
||||
|
||||
onUpdateApplication(application) {
|
||||
this.setState({
|
||||
application: application,
|
||||
});
|
||||
}
|
||||
|
||||
getApplication() {
|
||||
if (this.state.applicationName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ApplicationBackend.getApplication(this.state.owner, this.state.applicationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
this.onUpdateApplication(null);
|
||||
this.setState({
|
||||
msg: res.msg,
|
||||
});
|
||||
return ;
|
||||
}
|
||||
this.onUpdateApplication(res.data);
|
||||
});
|
||||
}
|
||||
|
||||
getCaptchaProviderItems(application) {
|
||||
const providers = application?.providers;
|
||||
|
||||
if (providers === undefined || providers === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return providers.filter(providerItem => {
|
||||
if (providerItem.provider === undefined || providerItem.provider === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return providerItem.provider.category === "Captcha";
|
||||
});
|
||||
}
|
||||
|
||||
callback(values) {
|
||||
Setting.goToLink(`${this.state.redirectUri}?code=${values.captchaToken}&type=${values.captchaType}&secret=${values.clientSecret}&applicationId=${values.applicationId}`);
|
||||
}
|
||||
|
||||
renderCaptchaModal(application) {
|
||||
const captchaProviderItems = this.getCaptchaProviderItems(application);
|
||||
if (captchaProviderItems === null) {
|
||||
return null;
|
||||
}
|
||||
const alwaysProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Always");
|
||||
const dynamicProviderItems = captchaProviderItems.filter(providerItem => providerItem.rule === "Dynamic");
|
||||
const provider = alwaysProviderItems.length > 0
|
||||
? alwaysProviderItems[0].provider
|
||||
: dynamicProviderItems[0].provider;
|
||||
|
||||
return <CaptchaModal
|
||||
owner={provider.owner}
|
||||
name={provider.name}
|
||||
visible={true}
|
||||
onOk={(captchaType, captchaToken, clientSecret) => {
|
||||
const values = {
|
||||
captchaType: captchaType,
|
||||
captchaToken: captchaToken,
|
||||
clientSecret: clientSecret,
|
||||
applicationId: `${provider.owner}/${provider.name}`,
|
||||
};
|
||||
this.callback(values);
|
||||
}}
|
||||
onCancel={() => this.callback({captchaType: "none", captchaToken: "", clientSecret: ""})}
|
||||
isCurrentProvider={true}
|
||||
/>;
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
this.renderCaptchaModal(this.state.application)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CaptchaPage;
|
@ -73,9 +73,11 @@ class CertListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -55,9 +55,11 @@ class EnforcerListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -32,6 +32,7 @@ import {authConfig} from "./auth/Auth";
|
||||
import ProductBuyPage from "./ProductBuyPage";
|
||||
import PaymentResultPage from "./PaymentResultPage";
|
||||
import QrCodePage from "./QrCodePage";
|
||||
import CaptchaPage from "./CaptchaPage";
|
||||
import CustomHead from "./basic/CustomHead";
|
||||
|
||||
class EntryPage extends React.Component {
|
||||
@ -120,6 +121,7 @@ class EntryPage extends React.Component {
|
||||
<Route exact path="/buy-plan/:owner/:pricingName" render={(props) => <ProductBuyPage {...this.props} pricing={this.state.pricing} onUpdatePricing={onUpdatePricing} {...props} />} />
|
||||
<Route exact path="/buy-plan/:owner/:pricingName/result" render={(props) => <PaymentResultPage {...this.props} pricing={this.state.pricing} onUpdatePricing={onUpdatePricing} {...props} />} />
|
||||
<Route exact path="/qrcode/:owner/:paymentName" render={(props) => <QrCodePage {...this.props} onUpdateApplication={onUpdateApplication} {...props} />} />
|
||||
<Route exact path="/captcha" render={(props) => <CaptchaPage {...props} />} />
|
||||
</Switch>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
@ -84,9 +84,11 @@ class GroupListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -68,9 +68,11 @@ class InvitationListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -13,12 +13,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, InputNumber, Row, Select, Switch} from "antd";
|
||||
import {EyeInvisibleOutlined, EyeTwoTone} from "@ant-design/icons";
|
||||
import {Button, Card, Col, Input, InputNumber, Row, Select, Space, Switch} from "antd";
|
||||
import {EyeInvisibleOutlined, EyeTwoTone, HolderOutlined, UsergroupAddOutlined} from "@ant-design/icons";
|
||||
import * as LddpBackend from "./backend/LdapBackend";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import * as Setting from "./Setting";
|
||||
import i18next from "i18next";
|
||||
import * as GroupBackend from "./backend/GroupBackend";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
@ -30,12 +31,14 @@ class LdapEditPage extends React.Component {
|
||||
organizationName: props.match.params.organizationName,
|
||||
ldap: null,
|
||||
organizations: [],
|
||||
groups: null,
|
||||
};
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getLdap();
|
||||
this.getOrganizations();
|
||||
this.getGroups();
|
||||
}
|
||||
|
||||
getLdap() {
|
||||
@ -60,6 +63,17 @@ class LdapEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getGroups() {
|
||||
GroupBackend.getGroups(this.state.organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
groups: res.data,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateLdapField(key, value) {
|
||||
this.setState((prevState) => {
|
||||
prevState.ldap[key] = value;
|
||||
@ -214,6 +228,31 @@ class LdapEditPage extends React.Component {
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{lineHeight: "32px", textAlign: "right", paddingRight: "25px"}} span={3}>
|
||||
{Setting.getLabel(i18next.t("ldap:Default group"), i18next.t("ldap:Default group - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={21}>
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.ldap.defaultGroup ?? []} onChange={(value => {
|
||||
this.updateLdapField("defaultGroup", value);
|
||||
})}
|
||||
>
|
||||
<Option key={""} value={""}>
|
||||
<Space>
|
||||
{i18next.t("general:Default")}
|
||||
</Space>
|
||||
</Option>
|
||||
{
|
||||
this.state.groups?.map((group) => <Option key={group.name} value={`${group.owner}/${group.name}`}>
|
||||
<Space>
|
||||
{group.type === "Physical" ? <UsergroupAddOutlined /> : <HolderOutlined />}
|
||||
{group.displayName}
|
||||
</Space>
|
||||
</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}}>
|
||||
<Col style={{lineHeight: "32px", textAlign: "right", paddingRight: "25px"}} span={3}>
|
||||
{Setting.getLabel(i18next.t("ldap:Auto Sync"), i18next.t("ldap:Auto Sync - Tooltip"))} :
|
||||
|
@ -72,9 +72,11 @@ class ModelListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -360,7 +360,7 @@ class OrganizationEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.defaultApplication} onChange={(value => {this.updateOrganizationField("defaultApplication", value);})}
|
||||
options={this.state.applications?.map((item) => Setting.getOption(item.name, item.name))
|
||||
options={this.state.applications?.map((item) => Setting.getOption(Setting.getApplicationDisplayName(item.name), item.name))
|
||||
} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -115,11 +115,11 @@ class OrganizationListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
total: this.state.pagination.total - 1},
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
window.dispatchEvent(new Event("storageOrganizationsChanged"));
|
||||
} else {
|
||||
|
@ -70,9 +70,11 @@ class PaymentListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -69,9 +69,11 @@ class PermissionListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -63,9 +63,11 @@ class PlanListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -59,9 +59,11 @@ class PricingListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -65,9 +65,11 @@ class ProductListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -843,7 +843,7 @@ class ProviderEditPage extends React.Component {
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.provider.type !== "ADFS" && this.state.provider.type !== "AzureAD" && this.state.provider.type !== "AzureADB2C" && this.state.provider.type !== "Casdoor" && this.state.provider.type !== "Okta" ? null : (
|
||||
this.state.provider.type !== "ADFS" && this.state.provider.type !== "AzureAD" && this.state.provider.type !== "AzureADB2C" && (this.state.provider.type !== "Casdoor" && this.state.category !== "Storage") && this.state.provider.type !== "Okta" ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
@ -870,7 +870,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology"].includes(this.state.provider.type) ? null : (
|
||||
{["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
||||
@ -885,7 +885,9 @@ class ProviderEditPage extends React.Component {
|
||||
{["Custom HTTP SMS", "Local File System"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} :
|
||||
{["Casdoor"].includes(this.state.provider.type) ?
|
||||
Setting.getLabel(i18next.t("general:Provider"), i18next.t("provider:Provider - Tooltip"))
|
||||
: Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.bucket} onChange={e => {
|
||||
@ -906,7 +908,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Custom HTTP SMS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology"].includes(this.state.provider.type) ? null : (
|
||||
{["Custom HTTP SMS", "Qiniu Cloud Kodo", "Synology", "Casdoor"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
@ -918,10 +920,24 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["AWS S3", "Tencent Cloud COS", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? (
|
||||
{["Casdoor"].includes(this.state.provider.type) ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Region ID"), i18next.t("provider:Region ID - Tooltip"))} :
|
||||
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.content} onChange={e => {
|
||||
this.updateProviderField("content", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
) : null}
|
||||
{["AWS S3", "Tencent Cloud COS", "Qiniu Cloud Kodo", "Casdoor"].includes(this.state.provider.type) ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{["Casdoor"].includes(this.state.provider.type) ?
|
||||
Setting.getLabel(i18next.t("general:Application"), i18next.t("general:Application - Tooltip")) :
|
||||
Setting.getLabel(i18next.t("provider:Region ID"), i18next.t("provider:Region ID - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.regionId} onChange={e => {
|
||||
@ -1298,7 +1314,7 @@ class ProviderEditPage extends React.Component {
|
||||
) : null
|
||||
}
|
||||
{
|
||||
(this.state.provider.type === "Alipay" || this.state.provider.type === "WeChat Pay") ? (
|
||||
(this.state.provider.type === "Alipay" || this.state.provider.type === "WeChat Pay" || this.state.provider.type === "Casdoor") ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Cert"), i18next.t("general:Cert - Tooltip"))} :
|
||||
|
@ -76,9 +76,11 @@ class ProviderListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -40,9 +40,11 @@ class ResourceListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -61,9 +61,11 @@ class RoleListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -27,9 +27,11 @@ class SessionListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -229,6 +229,10 @@ export const OtherProviderInfo = {
|
||||
logo: `${StaticBaseUrl}/img/social_synology.png`,
|
||||
url: "https://www.synology.com/en-global/dsm/feature/file_sharing",
|
||||
},
|
||||
"Casdoor": {
|
||||
logo: `${StaticBaseUrl}/img/casdoor.png`,
|
||||
url: "https://casdoor.org/docs/provider/storage/overview",
|
||||
},
|
||||
},
|
||||
SAML: {
|
||||
"Aliyun IDaaS": {
|
||||
@ -1062,6 +1066,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: "Qiniu Cloud Kodo", name: "Qiniu Cloud Kodo"},
|
||||
{id: "Google Cloud Storage", name: "Google Cloud Storage"},
|
||||
{id: "Synology", name: "Synology"},
|
||||
{id: "Casdoor", name: "Casdoor"},
|
||||
]
|
||||
);
|
||||
} else if (category === "SAML") {
|
||||
@ -1371,6 +1376,13 @@ export function getApplicationName(application) {
|
||||
return `${application?.owner}/${application?.name}`;
|
||||
}
|
||||
|
||||
export function getApplicationDisplayName(application) {
|
||||
if (application.isShared) {
|
||||
return `${application.name}(Shared)`;
|
||||
}
|
||||
return application.name;
|
||||
}
|
||||
|
||||
export function getRandomName() {
|
||||
return Math.random().toString(36).slice(-6);
|
||||
}
|
||||
|
@ -64,9 +64,11 @@ class SubscriptionListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -69,9 +69,11 @@ class SyncerListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -61,9 +61,11 @@ class TokenListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -125,7 +125,7 @@ class TransactionEditPage extends React.Component {
|
||||
application: application,
|
||||
});
|
||||
|
||||
this.getCerts(application.organization);
|
||||
this.getCerts(application);
|
||||
|
||||
this.getSamlMetadata(application.enableSamlPostBinding);
|
||||
});
|
||||
|
@ -54,9 +54,11 @@ class TransactionListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -110,9 +110,11 @@ class UserListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -61,9 +61,11 @@ class WebhookListPage extends BaseListPage {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
this.fetch({
|
||||
pagination: {
|
||||
...this.state.pagination,
|
||||
current: this.state.pagination.current > 1 && this.state.data.length === 1 ? this.state.pagination.current - 1 : this.state.pagination.current,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
|
@ -24,6 +24,12 @@ import * as serviceWorker from "./serviceWorker";
|
||||
import {BrowserRouter} from "react-router-dom";
|
||||
import "./backend/FetchFilter";
|
||||
|
||||
if (!String.prototype.replaceAll) {
|
||||
String.prototype.replaceAll = function(search, replace) {
|
||||
return this.split(search).join(replace);
|
||||
};
|
||||
}
|
||||
|
||||
const container = document.getElementById("root");
|
||||
|
||||
const app = createRoot(container);
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Povolit",
|
||||
"Enable dark logo": "Povolit tmavé logo",
|
||||
"Enable dark logo - Tooltip": "Povolit tmavé logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Povoleno",
|
||||
"Enabled successfully": "Úspěšně povoleno",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Pozvánky",
|
||||
"Is enabled": "Je povoleno",
|
||||
"Is enabled - Tooltip": "Nastavit, zda může být použito",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPy",
|
||||
"LDAPs - Tooltip": "LDAP servery",
|
||||
"Languages": "Jazyky",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Základní DN",
|
||||
"Base DN - Tooltip": "Základní DN při vyhledávání v LDAP",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Upravit LDAP",
|
||||
"Enable SSL": "Povolit SSL",
|
||||
"Enable SSL - Tooltip": "Zda povolit SSL",
|
||||
@ -521,7 +527,7 @@
|
||||
"Failed to initiate MFA": "Nepodařilo se zahájit MFA",
|
||||
"Have problems?": "Máte problémy?",
|
||||
"Multi-factor authentication": "Vícefaktorové ověřování",
|
||||
"Multi-factor authentication - Tooltip": "Dvoufaktorové ověřování - Tooltip",
|
||||
"Multi-factor authentication - Tooltip ": "Dvoufaktorové ověřování - Tooltip",
|
||||
"Multi-factor authentication description": "Popis dvoufaktorového ověřování",
|
||||
"Multi-factor methods": "Metody dvoufaktorového ověřování",
|
||||
"Multi-factor recover": "Obnovení dvoufaktorového ověřování",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Váš telefon je",
|
||||
"preferred": "preferované"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Upravit model",
|
||||
"Model text": "Text modelu",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Odkaz",
|
||||
"Location": "Místo",
|
||||
"Location - Tooltip": "Město bydliště",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Spravované účty",
|
||||
"Modify password...": "Změnit heslo...",
|
||||
"Multi-factor authentication": "Vícefaktorové ověřování",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Ist aktiviert",
|
||||
"Is enabled - Tooltip": "Festlegen, ob es verwendet werden kann",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP-Server",
|
||||
"Languages": "Sprachen",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Basis-DN",
|
||||
"Base DN - Tooltip": "Basis-DN während der LDAP-Suche",
|
||||
"CN": "KN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "LDAP bearbeiten",
|
||||
"Enable SSL": "Aktivieren Sie SSL",
|
||||
"Enable SSL - Tooltip": "Ob SSL aktiviert werden soll",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Modell bearbeiten",
|
||||
"Model text": "Modelltext",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Ort",
|
||||
"Location - Tooltip": "Stadt des Wohnsitzes",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Verwaltete Konten",
|
||||
"Modify password...": "Passwort ändern...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Está habilitado",
|
||||
"Is enabled - Tooltip": "Establecer si se puede usar",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs (Secure LDAP)",
|
||||
"LDAPs - Tooltip": "Servidores LDAP",
|
||||
"Languages": "Idiomas",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "DN base",
|
||||
"Base DN - Tooltip": "Base DN durante la búsqueda LDAP",
|
||||
"CN": "CN (siglas en inglés) podría traducirse como \"Red de Comunicaciones\". Sin embargo, sin más contexto, no es posible saber cuál es el significado exacto de estas siglas",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Editar LDAP",
|
||||
"Enable SSL": "Habilitar SSL",
|
||||
"Enable SSL - Tooltip": "Si se habilita SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Editar modelo",
|
||||
"Model text": "Texto modelo",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Enlace",
|
||||
"Location": "Ubicación",
|
||||
"Location - Tooltip": "Ciudad de residencia",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Cuentas gestionadas",
|
||||
"Modify password...": "Modificar contraseña...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Activer",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Activé",
|
||||
"Enabled successfully": "Activé avec succès",
|
||||
"Enforcers": "Exécuteurs",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Est activé",
|
||||
"Is enabled - Tooltip": "Définir s'il peut être utilisé",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "Serveurs LDAP",
|
||||
"Languages": "Langues",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "DN racine",
|
||||
"Base DN - Tooltip": "Le DN racine (base DN) lors de la recherche LDAP",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Modifier le LDAP",
|
||||
"Enable SSL": "Activer SSL",
|
||||
"Enable SSL - Tooltip": "Activer SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Votre téléphone est",
|
||||
"preferred": "préféré"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Modifier le modèle",
|
||||
"Model text": "Définition du modèle",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Lier",
|
||||
"Location": "Localisation",
|
||||
"Location - Tooltip": "Ville de résidence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Comptes gérés",
|
||||
"Modify password...": "Modifier le mot de passe...",
|
||||
"Multi-factor authentication": "Authentification multifacteur",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Diaktifkan",
|
||||
"Is enabled - Tooltip": "Atur apakah itu dapat digunakan",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "Server LDAP",
|
||||
"Languages": "Bahasa-bahasa",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "DN dasar",
|
||||
"Base DN - Tooltip": "Base DN selama pencarian LDAP",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Mengedit LDAP",
|
||||
"Enable SSL": "Aktifkan SSL",
|
||||
"Enable SSL - Tooltip": "Apakah untuk mengaktifkan SSL?",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Mengedit Model",
|
||||
"Model text": "Teks Model",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Tautan",
|
||||
"Location": "Lokasi",
|
||||
"Location - Tooltip": "Kota tempat tinggal",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Akun yang dikelola",
|
||||
"Modify password...": "Mengubah kata sandi...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "可能になっています",
|
||||
"Is enabled - Tooltip": "使用可能かどうかを設定してください",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAP",
|
||||
"LDAPs - Tooltip": "LDAPサーバー",
|
||||
"Languages": "言語",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "ベース DN",
|
||||
"Base DN - Tooltip": "LDAP検索中のBase DN",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "LDAPを編集",
|
||||
"Enable SSL": "SSL を有効にする",
|
||||
"Enable SSL - Tooltip": "SSLを有効にするかどうか",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "編集モデル",
|
||||
"Model text": "モデルテキスト",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "リンク",
|
||||
"Location": "場所",
|
||||
"Location - Tooltip": "居住都市",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "管理アカウント",
|
||||
"Modify password...": "パスワードを変更する...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "활성화됩니다",
|
||||
"Is enabled - Tooltip": "사용 가능한 지 여부를 설정하세요",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP 서버",
|
||||
"Languages": "언어",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "기본 DN",
|
||||
"Base DN - Tooltip": "LDAP 검색 중 기본 DN",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "LDAP 수정",
|
||||
"Enable SSL": "SSL 활성화",
|
||||
"Enable SSL - Tooltip": "SSL을 활성화할지 여부를 결정하십시오",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "편집 형태 모델",
|
||||
"Model text": "모델 텍스트",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "링크",
|
||||
"Location": "장소",
|
||||
"Location - Tooltip": "거주 도시",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "관리 계정",
|
||||
"Modify password...": "비밀번호 수정하기...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Habilitar",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Habilitado",
|
||||
"Enabled successfully": "Habilitado com sucesso",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Está habilitado",
|
||||
"Is enabled - Tooltip": "Define se está habilitado",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "Servidores LDAP",
|
||||
"Languages": "Idiomas",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN durante a busca LDAP",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Editar LDAP",
|
||||
"Enable SSL": "Habilitar SSL",
|
||||
"Enable SSL - Tooltip": "Se habilitar o SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Editar Modelo",
|
||||
"Model text": "Texto do Modelo",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Localização",
|
||||
"Location - Tooltip": "Cidade de residência",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Contas gerenciadas",
|
||||
"Modify password...": "Modificar senha...",
|
||||
"Multi-factor authentication": "Autenticação de vários fatores",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Включить",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Включено",
|
||||
"Enabled successfully": "Успешно включено",
|
||||
"Enforcers": "Контролёры доступа",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Включен",
|
||||
"Is enabled - Tooltip": "Установить, может ли использоваться",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPы",
|
||||
"LDAPs - Tooltip": "LDAP серверы",
|
||||
"Languages": "Языки",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Базовый DN",
|
||||
"Base DN - Tooltip": "Базовый DN во время поиска LDAP",
|
||||
"CN": "КНР",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Изменить LDAP",
|
||||
"Enable SSL": "Включить SSL",
|
||||
"Enable SSL - Tooltip": "Перевод: Следует ли включать SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Ваш телефон",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Редактировать модель",
|
||||
"Model text": "Модельный текст",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Ссылка",
|
||||
"Location": "Местоположение",
|
||||
"Location - Tooltip": "Город проживания",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Управляемые аккаунты",
|
||||
"Modify password...": "Изменить пароль...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Povoliť",
|
||||
"Enable dark logo": "Povoliť tmavé logo",
|
||||
"Enable dark logo - Tooltip": "Povoliť tmavé logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Povolené",
|
||||
"Enabled successfully": "Úspešne povolené",
|
||||
"Enforcers": "Vynútitelia",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Pozvánky",
|
||||
"Is enabled": "Je povolené",
|
||||
"Is enabled - Tooltip": "Nastavte, či môže byť použitý",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAP",
|
||||
"LDAPs - Tooltip": "LDAP servery",
|
||||
"Languages": "Jazyky",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Základný DN",
|
||||
"Base DN - Tooltip": "Základný DN počas vyhľadávania LDAP",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Upraviť LDAP",
|
||||
"Enable SSL": "Povoliť SSL",
|
||||
"Enable SSL - Tooltip": "Či povoliť SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Váš telefón je",
|
||||
"preferred": "preferované"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Upraviť model",
|
||||
"Model text": "Text modelu",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Odkaz",
|
||||
"Location": "Miesto",
|
||||
"Location - Tooltip": "Mesto bydliska",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Spravované účty",
|
||||
"Modify password...": "Zmeniť heslo...",
|
||||
"Multi-factor authentication": "Viacfaktorová autentifikácia",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Languages",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Edit Model",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Etkinleştir",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Etkin",
|
||||
"Enabled successfully": "Başarıyla etkinleştirildi",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Davetler",
|
||||
"Is enabled": "Aktif Mi?",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "LDAP servers",
|
||||
"Languages": "Diller",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Base DN",
|
||||
"Base DN - Tooltip": "Base DN during LDAP search",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Edit LDAP",
|
||||
"Enable SSL": "Enable SSL",
|
||||
"Enable SSL - Tooltip": "Whether to enable SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Telefon numaranız",
|
||||
"preferred": "tercih edilen"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Modeli Düzenle",
|
||||
"Model text": "Model text",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Link",
|
||||
"Location": "Location",
|
||||
"Location - Tooltip": "City of residence",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Увімкнути",
|
||||
"Enable dark logo": "Увімкнути темний логотип",
|
||||
"Enable dark logo - Tooltip": "Увімкнути темний логотип",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Увімкнено",
|
||||
"Enabled successfully": "Успішно ввімкнено",
|
||||
"Enforcers": "Силовики",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Запрошення",
|
||||
"Is enabled": "Увімкнено",
|
||||
"Is enabled - Tooltip": "Встановіть, чи можна використовувати",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAP",
|
||||
"LDAPs - Tooltip": "Сервери LDAP",
|
||||
"Languages": "Мови",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "Базовий DN",
|
||||
"Base DN - Tooltip": "Базовий DN під час пошуку LDAP",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Редагувати LDAP",
|
||||
"Enable SSL": "Увімкніть SSL",
|
||||
"Enable SSL - Tooltip": "Чи вмикати SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Ваш телефон",
|
||||
"preferred": "бажаний"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Редагувати модель",
|
||||
"Model text": "Текст моделі",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Посилання",
|
||||
"Location": "Місцезнаходження",
|
||||
"Location - Tooltip": "Місто проживання",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Керовані облікові записи",
|
||||
"Modify password...": "Змінити пароль...",
|
||||
"Multi-factor authentication": "Багатофакторна аутентифікація",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
"Enable tour": "Enable tour",
|
||||
"Enable tour - Tooltip": "Display tour for users",
|
||||
"Enabled": "Enabled",
|
||||
"Enabled successfully": "Enabled successfully",
|
||||
"Enforcers": "Enforcers",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Đã được kích hoạt",
|
||||
"Is enabled - Tooltip": "Đặt liệu nó có thể sử dụng hay không",
|
||||
"Is shared": "Is shared",
|
||||
"Is shared - Tooltip": "Share this application with other organizations",
|
||||
"LDAPs": "LDAPs",
|
||||
"LDAPs - Tooltip": "Máy chủ LDAP",
|
||||
"Languages": "Ngôn ngữ",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "DN cơ sở",
|
||||
"Base DN - Tooltip": "Đơn vị căn bản (Base DN) trong quá trình tìm kiếm LDAP",
|
||||
"CN": "CN",
|
||||
"Default group": "Default group",
|
||||
"Default group - Tooltip": "Group to which users belong after synchronization",
|
||||
"Edit LDAP": "Sửa LDAP",
|
||||
"Enable SSL": "Kích hoạt SSL",
|
||||
"Enable SSL - Tooltip": "Có nên kích hoạt SSL hay không?",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "Your phone is",
|
||||
"preferred": "preferred"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "Account Name",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "Secret Key"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "Sửa mô hình",
|
||||
"Model text": "Văn bản mẫu",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "Liên kết",
|
||||
"Location": "Vị trí",
|
||||
"Location - Tooltip": "Thành phố cư trú",
|
||||
"MFA accounts": "MFA accounts",
|
||||
"Managed accounts": "Quản lý tài khoản",
|
||||
"Modify password...": "Sửa đổi mật khẩu...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
|
@ -234,6 +234,8 @@
|
||||
"Enable": "启用",
|
||||
"Enable dark logo": "开启暗黑Logo",
|
||||
"Enable dark logo - Tooltip": "开启暗黑Logo",
|
||||
"Enable tour": "启用导引",
|
||||
"Enable tour - Tooltip": "为用户显示导引",
|
||||
"Enabled": "已开启",
|
||||
"Enabled successfully": "启用成功",
|
||||
"Enforcers": "Casbin执行器",
|
||||
@ -265,6 +267,8 @@
|
||||
"Invitations": "邀请码",
|
||||
"Is enabled": "已启用",
|
||||
"Is enabled - Tooltip": "是否启用",
|
||||
"Is shared": "是否共享",
|
||||
"Is shared - Tooltip": "与其他组织共享此应用",
|
||||
"LDAPs": "LDAP",
|
||||
"LDAPs - Tooltip": "LDAPs",
|
||||
"Languages": "语言",
|
||||
@ -441,6 +445,8 @@
|
||||
"Base DN": "基本DN",
|
||||
"Base DN - Tooltip": "LDAP搜索时的基DN",
|
||||
"CN": "CN",
|
||||
"Default group": "默认群组",
|
||||
"Default group - Tooltip": "同步用户后用户所在的群组",
|
||||
"Edit LDAP": "编辑LDAP",
|
||||
"Enable SSL": "启用SSL",
|
||||
"Enable SSL - Tooltip": "是否启用SSL",
|
||||
@ -551,6 +557,11 @@
|
||||
"Your phone is": "你的手机号",
|
||||
"preferred": "首选"
|
||||
},
|
||||
"mfaAccount": {
|
||||
"Account Name": "账号名",
|
||||
"Issuer": "Issuer",
|
||||
"Secret Key": "密钥"
|
||||
},
|
||||
"model": {
|
||||
"Edit Model": "编辑模型",
|
||||
"Model text": "模型文本",
|
||||
@ -1136,6 +1147,7 @@
|
||||
"Link": "绑定",
|
||||
"Location": "城市",
|
||||
"Location - Tooltip": "居住地址所在的城市",
|
||||
"MFA accounts": "MFA账户",
|
||||
"Managed accounts": "托管账户",
|
||||
"Modify password...": "编辑密码...",
|
||||
"Multi-factor authentication": "多因素认证",
|
||||
|
Reference in New Issue
Block a user