Compare commits

...

14 Commits

Author SHA1 Message Date
Yaodong Yu
042e52bd16 feat: replace casdoor/goth with markbates/goth (#1374) 2022-12-06 17:18:29 +08:00
Yaodong Yu
e207fd243b feat: fix CSS issue that login error pages are not centered (#1371) 2022-12-06 14:00:17 +08:00
Gucheng Wang
30b7fd963f Reduce Resource key size 2022-12-06 11:30:42 +08:00
Yaodong Yu
ca314bbfb5 feat: refactor layout and fix footer CSS (#1370) 2022-12-06 00:50:17 +08:00
imp2002
812c44e070 feat: add and load policy within a specific permission (#1357)
* fix: add and load policy with a specific permission

* fix: use a clear variable name
2022-12-05 17:07:10 +08:00
imp2002
78e45d07cf fix: support RBAC With Domains/Tenants (#1333)
* feat: support RBAC With Domains/Tenants

* fix: add verify for `UpdatePermission`

* Update permission.go

Co-authored-by: hsluoyz <hsluoyz@qq.com>
2022-12-05 16:08:17 +08:00
Yaodong Yu
0856977b92 feat: update to antd 5.0 (#1362)
* feat: update to ant5.X

* fix: incompatible styles

* fix: adjust the style
2022-12-04 23:05:30 +08:00
Chell
a44a4b0300 feat: fix React incorrect usage to fix issue that verification code must be submitted twice to succeed (#1348)
* fix: synchronized user login fields saving

* fix: synchronized user login fields saving

* recover changes

* fix: save username in step 2

* fix: format
2022-12-04 20:58:07 +08:00
Chell
4b29dd8c41 fix: responsive certs page editor (#1360)
* fix: responsive editor width

* fix: format
2022-12-04 16:04:04 +08:00
Yaodong Yu
165e2e33e3 fix: disable formcss in mobile (#1359) 2022-12-04 15:53:46 +08:00
Yang Luo
d13a307ad5 Allow org admin to access GetResources() 2022-12-03 01:10:45 +08:00
Mr Forest
27bd771fed feat: handle the dataSourceName when DB changes (#1352)
* fix: handle the dataSourceName when DB changes

* reduce duplication of code
2022-12-02 22:20:18 +08:00
Yaodong Yu
9f3ee275a8 feat: reformat frontend alert texts with correct i18n (#1341)
* fix: add i18

* fix: standard prompt message
2022-12-02 00:06:28 +08:00
Chell
fcda64ad7d fix: provider sort alphabetical order (#1347) 2022-12-01 22:51:10 +08:00
77 changed files with 1169 additions and 938 deletions

View File

@@ -32,7 +32,9 @@ func InitAuthz() {
var err error
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
a, err := xormadapter.NewAdapterWithTableName(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName()+conf.GetConfigString("dbName"), "casbin_rule", tableNamePrefix, true)
driverName := conf.GetConfigString("driverName")
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
a, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, "casbin_rule", tableNamePrefix, true)
if err != nil {
panic(err)
}

View File

@@ -120,3 +120,13 @@ func GetConfigBatchSize() int {
func GetConfigQuota() *Quota {
return quota
}
func GetConfigRealDataSourceName(driverName string) string {
var dataSourceName string
if driverName != "mysql" {
dataSourceName = GetConfigDataSourceName()
} else {
dataSourceName = GetConfigDataSourceName() + GetConfigString("dbName")
}
return dataSourceName
}

View File

@@ -40,6 +40,15 @@ func (c *ApiController) GetResources() {
value := c.Input().Get("value")
sortField := c.Input().Get("sortField")
sortOrder := c.Input().Get("sortOrder")
userObj, ok := c.RequireSignedInUser()
if !ok {
return
}
if userObj.IsAdmin {
user = ""
}
if limit == "" || page == "" {
c.Data["json"] = object.GetResources(owner, user)
c.ServeJSON()

6
go.mod
View File

@@ -12,7 +12,6 @@ require (
github.com/casbin/casbin/v2 v2.30.1
github.com/casbin/xorm-adapter/v3 v3.0.1
github.com/casdoor/go-sms-sender v0.5.1
github.com/casdoor/goth v1.69.0-FIX2
github.com/casdoor/oss v1.2.0
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc
@@ -27,9 +26,10 @@ require (
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/uuid v1.2.0
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/lestrrat-go/jwx v0.9.0
github.com/lestrrat-go/jwx v1.2.21
github.com/lib/pq v1.8.0
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3
github.com/markbates/goth v1.75.2
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/qiangmzsx/string-adapter/v2 v2.1.0
github.com/robfig/cron/v3 v3.0.1
@@ -44,7 +44,7 @@ require (
github.com/thanhpk/randstr v1.0.4
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect

27
go.sum
View File

@@ -102,8 +102,6 @@ github.com/casbin/xorm-adapter/v3 v3.0.1 h1:0l0zkYxo6cNuIdrBZgFxlje1TRvmheYa/zIp
github.com/casbin/xorm-adapter/v3 v3.0.1/go.mod h1:1BL7rHEDXrxO+vQdSo/ZaWKRivXl7YTos67GdMYcd20=
github.com/casdoor/go-sms-sender v0.5.1 h1:1/Wp1OLkVAVY4lEGQhekSNetSAWhnPcxYPV7xpCZgC0=
github.com/casdoor/go-sms-sender v0.5.1/go.mod h1:kBykbqwgRDXbXdMAIxmZKinVM1WjdqEbej5LAbUbcfI=
github.com/casdoor/goth v1.69.0-FIX2 h1:RgfIMkL9kekylgxHHK2ZY8ASAwOGns2HVlaBwLu7Bcs=
github.com/casdoor/goth v1.69.0-FIX2/go.mod h1:Om55nRo8CkeDkPSNBbzXW4G5uI28ZUkSk5S69dPek3s=
github.com/casdoor/oss v1.2.0 h1:ozLAE+nnNdFQBWbzH8U9spzaO8h8NrB57lBcdyMUUQ8=
github.com/casdoor/oss v1.2.0/go.mod h1:qii35VBuxnR/uEuYSKpS0aJ8htQFOcCVsZ4FHgHLuss=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -127,6 +125,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M=
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b h1:L63RATZFZuFMXy6ixnKmv3eNAXwYQF6HW1vd4IYsQqQ=
@@ -175,6 +176,8 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/goccy/go-json v0.9.6 h1:5/4CtRQdtsX0sal8fdVhTaiMN01Ri8BExZZ8iRmHQ6E=
github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
@@ -302,8 +305,18 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lestrrat-go/jwx v0.9.0 h1:Fnd0EWzTm0kFrBPzE/PEPp9nzllES5buMkksPMjEKpM=
github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk=
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
github.com/lestrrat-go/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4=
github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc=
github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE=
github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A=
github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
github.com/lestrrat-go/jwx v1.2.21 h1:n+yG95UMm5ZFsDdvsZmui+bqat4Cj/di4ys6XbgSlE8=
github.com/lestrrat-go/jwx v1.2.21/go.mod h1:9cfxnOH7G1gN75CaJP2hKGcxFEx5sPh1abRIA/ZJVh4=
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
@@ -312,6 +325,8 @@ github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3 h1:wIONC+HMNRqmWBjuM
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3/go.mod h1:37YR9jabpiIxsb8X9VCIx8qFOjTDIIrIHHODa8C4gz0=
github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0=
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
github.com/markbates/goth v1.75.2 h1:C7KloBMMk50JyXaHhzfqWYLW6+bDcSVIvUGHXneLWro=
github.com/markbates/goth v1.75.2/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc=
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911 h1:erppMjjp69Rertg1zlgRbLJH1u+eCmRPxKjMZ5I8/Ro=
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
@@ -465,8 +480,9 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 h1:BkypuErRT9A9I/iljuaG3/zdMjd/J6m8tKKJQtGfSdA=
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -530,7 +546,6 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=

View File

@@ -83,7 +83,7 @@ func parseToData() *I18nData {
data := I18nData{}
for _, word := range allWords {
tokens := strings.Split(word, ":")
tokens := strings.SplitN(word, ":", 2)
namespace := tokens[0]
key := tokens[1]

View File

@@ -15,11 +15,11 @@
package idp
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"time"
@@ -118,13 +118,14 @@ func (idp *AdfsIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
if err != nil {
return nil, err
}
keyset, err := jwk.Parse(resp.Body)
body, err := ioutil.ReadAll(resp.Body)
keyset, err := jwk.ParseKey(body)
if err != nil {
return nil, err
}
tokenSrc := []byte(token.AccessToken)
publicKey, _ := keyset.Keys[0].Materialize()
idToken, _ := jwt.Parse(bytes.NewReader(tokenSrc), jwt.WithVerify(jwa.RS256, publicKey))
publicKey, _ := keyset.PublicKey()
idToken, _ := jwt.Parse(tokenSrc, jwt.WithVerify(jwa.RS256, publicKey))
sid, _ := idToken.Get("sid")
upn, _ := idToken.Get("upn")
name, _ := idToken.Get("unique_name")

View File

@@ -22,35 +22,35 @@ import (
"time"
"github.com/casdoor/casdoor/util"
"github.com/casdoor/goth"
"github.com/casdoor/goth/providers/amazon"
"github.com/casdoor/goth/providers/apple"
"github.com/casdoor/goth/providers/azuread"
"github.com/casdoor/goth/providers/bitbucket"
"github.com/casdoor/goth/providers/digitalocean"
"github.com/casdoor/goth/providers/discord"
"github.com/casdoor/goth/providers/dropbox"
"github.com/casdoor/goth/providers/facebook"
"github.com/casdoor/goth/providers/gitea"
"github.com/casdoor/goth/providers/github"
"github.com/casdoor/goth/providers/gitlab"
"github.com/casdoor/goth/providers/google"
"github.com/casdoor/goth/providers/heroku"
"github.com/casdoor/goth/providers/instagram"
"github.com/casdoor/goth/providers/kakao"
"github.com/casdoor/goth/providers/line"
"github.com/casdoor/goth/providers/linkedin"
"github.com/casdoor/goth/providers/microsoftonline"
"github.com/casdoor/goth/providers/paypal"
"github.com/casdoor/goth/providers/salesforce"
"github.com/casdoor/goth/providers/shopify"
"github.com/casdoor/goth/providers/slack"
"github.com/casdoor/goth/providers/steam"
"github.com/casdoor/goth/providers/tumblr"
"github.com/casdoor/goth/providers/twitter"
"github.com/casdoor/goth/providers/yahoo"
"github.com/casdoor/goth/providers/yandex"
"github.com/casdoor/goth/providers/zoom"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/amazon"
"github.com/markbates/goth/providers/apple"
"github.com/markbates/goth/providers/azureadv2"
"github.com/markbates/goth/providers/bitbucket"
"github.com/markbates/goth/providers/digitalocean"
"github.com/markbates/goth/providers/discord"
"github.com/markbates/goth/providers/dropbox"
"github.com/markbates/goth/providers/facebook"
"github.com/markbates/goth/providers/gitea"
"github.com/markbates/goth/providers/github"
"github.com/markbates/goth/providers/gitlab"
"github.com/markbates/goth/providers/google"
"github.com/markbates/goth/providers/heroku"
"github.com/markbates/goth/providers/instagram"
"github.com/markbates/goth/providers/kakao"
"github.com/markbates/goth/providers/line"
"github.com/markbates/goth/providers/linkedin"
"github.com/markbates/goth/providers/microsoftonline"
"github.com/markbates/goth/providers/paypal"
"github.com/markbates/goth/providers/salesforce"
"github.com/markbates/goth/providers/shopify"
"github.com/markbates/goth/providers/slack"
"github.com/markbates/goth/providers/steam"
"github.com/markbates/goth/providers/tumblr"
"github.com/markbates/goth/providers/twitter"
"github.com/markbates/goth/providers/yahoo"
"github.com/markbates/goth/providers/yandex"
"github.com/markbates/goth/providers/zoom"
"golang.org/x/oauth2"
)
@@ -74,8 +74,8 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
}
case "AzureAD":
idp = GothIdProvider{
Provider: azuread.New(clientId, clientSecret, redirectUrl, nil),
Session: &azuread.Session{},
Provider: azureadv2.New(clientId, clientSecret, redirectUrl, azureadv2.ProviderOptions{Tenant: "common"}),
Session: &azureadv2.Session{},
}
case "Bitbucket":
idp = GothIdProvider{
@@ -202,6 +202,8 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
Provider: zoom.New(clientId, clientSecret, redirectUrl),
Session: &zoom.Session{},
}
default:
return nil
}
return &idp

View File

@@ -98,7 +98,7 @@ func GetIdProvider(typ string, subType string, clientId string, clientSecret str
return nil
}
var gothList = []string{"Apple", "AzureAd", "Slack", "Steam"}
var gothList = []string{"Apple", "AzureAD", "Slack", "Steam"}
func isGothSupport(provider string) bool {
for _, value := range gothList {

View File

@@ -158,7 +158,7 @@ func initBuiltInApplication() {
},
RedirectUris: []string{},
ExpireInHours: 168,
FormOffset: 8,
FormOffset: 2,
}
AddApplication(application)
}

View File

@@ -111,7 +111,27 @@ func GetPermission(id string) *Permission {
return getPermission(owner, name)
}
// checkPermissionValid verifies if the permission is valid
func checkPermissionValid(permission *Permission) {
enforcer := getEnforcer(permission)
enforcer.EnableAutoSave(false)
policies, groupingPolicies := getPolicies(permission)
if len(groupingPolicies) > 0 {
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
if err != nil {
panic(err)
}
}
_, err := enforcer.AddPolicies(policies)
if err != nil {
panic(err)
}
}
func UpdatePermission(id string, permission *Permission) bool {
checkPermissionValid(permission)
owner, name := util.GetOwnerAndNameFromId(id)
oldPermission := getPermission(owner, name)
if oldPermission == nil {

View File

@@ -29,7 +29,9 @@ func getEnforcer(permission *Permission) *casbin.Enforcer {
tableName = permission.Adapter
}
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
adapter, err := xormadapter.NewAdapterWithTableName(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName()+conf.GetConfigString("dbName"), tableName, tableNamePrefix, true)
driverName := conf.GetConfigString("driverName")
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
if err != nil {
panic(err)
}
@@ -63,22 +65,27 @@ m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
panic(err)
}
// load Policy with a specific Permission
enforcer.LoadFilteredPolicy(xormadapter.Filter{
V5: []string{permission.Owner + "/" + permission.Name},
})
return enforcer
}
func getPolicies(permission *Permission) ([][]string, [][]string) {
var policies [][]string
var groupingPolicies [][]string
permissionId := permission.Owner + "/" + permission.Name
domainExist := len(permission.Domains) > 0
for _, user := range permission.Users {
for _, resource := range permission.Resources {
for _, action := range permission.Actions {
if domainExist {
for _, domain := range permission.Domains {
policies = append(policies, []string{user, domain, resource, strings.ToLower(action)})
policies = append(policies, []string{user, domain, resource, strings.ToLower(action), "", permissionId})
}
} else {
policies = append(policies, []string{user, resource, strings.ToLower(action)})
policies = append(policies, []string{user, resource, strings.ToLower(action), "", "", permissionId})
}
}
}
@@ -88,29 +95,29 @@ func getPolicies(permission *Permission) ([][]string, [][]string) {
for _, subUser := range roleObj.Users {
if domainExist {
for _, domain := range permission.Domains {
groupingPolicies = append(groupingPolicies, []string{subUser, domain, role})
groupingPolicies = append(groupingPolicies, []string{subUser, domain, role, "", "", permissionId})
}
} else {
groupingPolicies = append(groupingPolicies, []string{subUser, role})
groupingPolicies = append(groupingPolicies, []string{subUser, role, "", "", "", permissionId})
}
}
for _, subRole := range roleObj.Roles {
if domainExist {
for _, domain := range permission.Domains {
groupingPolicies = append(groupingPolicies, []string{subRole, domain, role})
groupingPolicies = append(groupingPolicies, []string{subRole, domain, role, "", "", permissionId})
}
} else {
groupingPolicies = append(groupingPolicies, []string{subRole, role})
groupingPolicies = append(groupingPolicies, []string{subRole, role, "", "", "", permissionId})
}
}
for _, resource := range permission.Resources {
for _, action := range permission.Actions {
if domainExist {
for _, domain := range permission.Domains {
policies = append(policies, []string{role, domain, resource, strings.ToLower(action)})
policies = append(policies, []string{role, domain, resource, strings.ToLower(action), "", permissionId})
}
} else {
policies = append(policies, []string{role, resource, strings.ToLower(action)})
policies = append(policies, []string{role, resource, strings.ToLower(action), "", "", permissionId})
}
}
}
@@ -155,7 +162,12 @@ func removePolicies(permission *Permission) {
func Enforce(permissionRule *PermissionRule) bool {
permission := GetPermission(permissionRule.Id)
enforcer := getEnforcer(permission)
allow, err := enforcer.Enforce(permissionRule.V0, permissionRule.V1, permissionRule.V2)
request := []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2}
if permissionRule.V3 != "" {
request = append(request, permissionRule.V3)
}
allow, err := enforcer.Enforce(request...)
if err != nil {
panic(err)
}
@@ -165,7 +177,11 @@ func Enforce(permissionRule *PermissionRule) bool {
func BatchEnforce(permissionRules []PermissionRule) []bool {
var requests [][]interface{}
for _, permissionRule := range permissionRules {
requests = append(requests, []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2})
if permissionRule.V3 != "" {
requests = append(requests, []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2, permissionRule.V3})
} else {
requests = append(requests, []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2})
}
}
permission := GetPermission(permissionRules[0].Id)
enforcer := getEnforcer(permission)

View File

@@ -23,7 +23,7 @@ import (
type Resource struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(250) notnull pk" json:"name"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
User string `xorm:"varchar(100)" json:"user"`
@@ -31,12 +31,12 @@ type Resource struct {
Application string `xorm:"varchar(100)" json:"application"`
Tag string `xorm:"varchar(100)" json:"tag"`
Parent string `xorm:"varchar(100)" json:"parent"`
FileName string `xorm:"varchar(1000)" json:"fileName"`
FileName string `xorm:"varchar(255)" json:"fileName"`
FileType string `xorm:"varchar(100)" json:"fileType"`
FileFormat string `xorm:"varchar(100)" json:"fileFormat"`
FileSize int `json:"fileSize"`
Url string `xorm:"varchar(1000)" json:"url"`
Description string `xorm:"varchar(1000)" json:"description"`
Url string `xorm:"varchar(255)" json:"url"`
Description string `xorm:"varchar(255)" json:"description"`
}
func GetResourceCount(owner, user, field, value string) int {

View File

@@ -9,7 +9,7 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"antd": "^4.22.8",
"antd": "5.0.3",
"codemirror": "^5.61.1",
"copy-to-clipboard": "^3.3.1",
"core-js": "^3.25.0",

View File

@@ -263,8 +263,8 @@ class AdapterEditPage extends React.Component {
const adapter = Setting.deepCopy(this.state.adapter);
AdapterBackend.updateAdapter(this.state.adapter.owner, this.state.adapterName, adapter)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
adapterName: this.state.adapter.name,
});
@@ -275,22 +275,26 @@ class AdapterEditPage extends React.Component {
this.props.history.push(`/adapters/${this.state.owner}/${this.state.adapter.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateAdapterField("name", this.state.adapterName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteAdapter() {
AdapterBackend.deleteAdapter(this.state.adapter)
.then(() => {
this.props.history.push("/adapters");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/adapters");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `adapter failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -47,27 +47,31 @@ class AdapterListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/adapters/${newAdapter.organization}/${newAdapter.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Adapter failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Adapter failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteAdapter(i) {
AdapterBackend.deleteAdapter(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Adapter deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Adapter failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -204,7 +208,7 @@ class AdapterListPage extends BaseListPage {
title={`Sure to delete adapter: ${record.name} ?`}
onConfirm={() => this.deleteAdapter(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -17,7 +17,7 @@ import "./App.less";
import {Helmet} from "react-helmet";
import * as Setting from "./Setting";
import {BarsOutlined, DownOutlined, LogoutOutlined, SettingOutlined} from "@ant-design/icons";
import {Avatar, BackTop, Button, Card, Drawer, Dropdown, Layout, Menu, Result} from "antd";
import {Avatar, Button, Card, ConfigProvider, Drawer, Dropdown, FloatButton, Layout, Menu, Result} from "antd";
import {Link, Redirect, Route, Switch, withRouter} from "react-router-dom";
import OrganizationListPage from "./OrganizationListPage";
import OrganizationEditPage from "./OrganizationEditPage";
@@ -76,7 +76,7 @@ import AdapterListPage from "./AdapterListPage";
import AdapterEditPage from "./AdapterEditPage";
import {withTranslation} from "react-i18next";
const {Header, Footer} = Layout;
const {Header, Footer, Content} = Layout;
class App extends Component {
constructor(props) {
@@ -295,23 +295,16 @@ class App extends Component {
}
renderRightDropdown() {
const menu = (
<Menu onClick={this.handleRightDropdownClick.bind(this)}>
<Menu.Item key="/account">
<SettingOutlined />
&nbsp;&nbsp;
{i18next.t("account:My Account")}
</Menu.Item>
<Menu.Item key="/logout">
<LogoutOutlined />
&nbsp;&nbsp;
{i18next.t("account:Logout")}
</Menu.Item>
</Menu>
);
const items = [];
items.push(Setting.getItem(<><SettingOutlined />&nbsp;&nbsp;{i18next.t("account:My Account")}</>,
"/account"
));
items.push(Setting.getItem(<><LogoutOutlined />&nbsp;&nbsp;{i18next.t("account:Logout")}</>,
"/logout"));
const onClick = this.handleRightDropdownClick.bind(this);
return (
<Dropdown key="/rightDropDown" overlay={menu} className="rightDropDown">
<Dropdown key="/rightDropDown" menu={{items, onClick}} className="rightDropDown">
<div className="ant-dropdown-link" style={{float: "right", cursor: "pointer"}}>
&nbsp;
&nbsp;
@@ -363,155 +356,89 @@ class App extends Component {
return [];
}
res.push(
<Menu.Item key="/">
<Link to="/">
{i18next.t("general:Home")}
</Link>
</Menu.Item>
);
res.push(Setting.getItem(<Link to="/">{i18next.t("general:Home")}</Link>, "/"));
if (Setting.isAdminUser(this.state.account)) {
res.push(
<Menu.Item key="/organizations">
<Link to="/organizations">
{i18next.t("general:Organizations")}
</Link>
</Menu.Item>
);
res.push(Setting.getItem(<Link to="/organizations">{i18next.t("general:Organizations")}</Link>,
"/organizations"));
}
if (Setting.isLocalAdminUser(this.state.account)) {
res.push(
<Menu.Item key="/users">
<Link to="/users">
{i18next.t("general:Users")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/roles">
<Link to="/roles">
{i18next.t("general:Roles")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/permissions">
<Link to="/permissions">
{i18next.t("general:Permissions")}
</Link>
</Menu.Item>
);
res.push(Setting.getItem(<Link to="/users">{i18next.t("general:Users")}</Link>,
"/users"
));
res.push(Setting.getItem(<Link to="/roles">{i18next.t("general:Roles")}</Link>,
"/roles"
));
res.push(Setting.getItem(<Link to="/permissions">{i18next.t("general:Permissions")}</Link>,
"/permissions"
));
}
if (Setting.isAdminUser(this.state.account)) {
res.push(
<Menu.Item key="/models">
<Link to="/models">
{i18next.t("general:Models")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/adapters">
<Link to="/adapters">
{i18next.t("general:Adapters")}
</Link>
</Menu.Item>
);
res.push(Setting.getItem(<Link to="/models">{i18next.t("general:Models")}</Link>,
"/models"
));
res.push(Setting.getItem(<Link to="/adapters">{i18next.t("general:Adapters")}</Link>,
"/adapters"
));
}
if (Setting.isLocalAdminUser(this.state.account)) {
res.push(
<Menu.Item key="/applications">
<Link to="/applications">
{i18next.t("general:Applications")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/providers">
<Link to="/providers">
{i18next.t("general:Providers")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/resources">
<Link to="/resources">
{i18next.t("general:Resources")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/records">
<Link to="/records">
{i18next.t("general:Records")}
</Link>
</Menu.Item>
);
res.push(Setting.getItem(<Link to="/applications">{i18next.t("general:Applications")}</Link>,
"/applications"
));
res.push(Setting.getItem(<Link to="/providers">{i18next.t("general:Providers")}</Link>,
"/providers"
));
res.push(Setting.getItem(<Link to="/resources">{i18next.t("general:Resources")}</Link>,
"/resources"
));
res.push(Setting.getItem(<Link to="/records">{i18next.t("general:Records")}</Link>,
"/records"
));
}
if (Setting.isAdminUser(this.state.account)) {
res.push(
<Menu.Item key="/tokens">
<Link to="/tokens">
{i18next.t("general:Tokens")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/webhooks">
<Link to="/webhooks">
{i18next.t("general:Webhooks")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/syncers">
<Link to="/syncers">
{i18next.t("general:Syncers")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/certs">
<Link to="/certs">
{i18next.t("general:Certs")}
</Link>
</Menu.Item>
);
res.push(Setting.getItem(<Link to="/tokens">{i18next.t("general:Tokens")}</Link>,
"/tokens"
));
res.push(Setting.getItem(<Link to="/webhooks">{i18next.t("general:Webhooks")}</Link>,
"/webhooks"
));
res.push(Setting.getItem(<Link to="/syncers">{i18next.t("general:Syncers")}</Link>,
"/syncers"
));
res.push(Setting.getItem(<Link to="/certs">{i18next.t("general:Certs")}</Link>,
"/certs"
));
if (Conf.EnableExtraPages) {
res.push(
<Menu.Item key="/products">
<Link to="/products">
{i18next.t("general:Products")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/payments">
<Link to="/payments">
{i18next.t("general:Payments")}
</Link>
</Menu.Item>
);
res.push(
<Menu.Item key="/sysinfo">
<Link to="/sysinfo">
{i18next.t("general:SysInfo")}
</Link>
</Menu.Item>
);
res.push(Setting.getItem(<Link to="/products">{i18next.t("general:Products")}</Link>,
"/products"
));
res.push(Setting.getItem(<Link to="/payments">{i18next.t("general:Payments")}</Link>,
"/payments"
));
res.push(Setting.getItem(<Link to="/sysinfo">{i18next.t("general:SysInfo")}</Link>,
"/sysinfo"
));
}
res.push(
<Menu.Item key="/swagger">
<a target="_blank" rel="noreferrer" href={Setting.isLocalhost() ? `${Setting.ServerUrl}/swagger` : "/swagger"}>
{i18next.t("general:Swagger")}
</a>
</Menu.Item>
);
res.push(Setting.getItem(<a target="_blank" rel="noreferrer"
href={Setting.isLocalhost() ? `${Setting.ServerUrl}/swagger` : "/swagger"}>{i18next.t("general:Swagger")}</a>,
"/swagger"
));
}
return res;
@@ -610,46 +537,45 @@ class App extends Component {
renderContent() {
if (!Setting.isMobile()) {
return (
<div style={{display: "flex", flex: "auto", width: "100%", flexDirection: "column"}}>
<Layout style={{display: "flex", alignItems: "stretch"}}>
<Header style={{padding: "0", marginBottom: "3px"}}>
<Layout id="parent-area">
<Header style={{marginBottom: "3px", paddingInline: 0}}>
{
Setting.isMobile() ? null : (
<Link to={"/"}>
<div className="logo" />
</Link>
)
}
<div>
<Menu
// theme="dark"
items={this.renderMenu()}
mode={(Setting.isMobile() && this.isStartPages()) ? "inline" : "horizontal"}
selectedKeys={[`${this.state.selectedMenuKey}`]}
style={{lineHeight: "64px", position: "absolute", left: "145px", right: "200px"}}
>
</Menu>
{
Setting.isMobile() ? null : (
<Link to={"/"}>
<div className="logo" />
</Link>
)
this.renderAccount()
}
<div>
<Menu
// theme="dark"
mode={(Setting.isMobile() && this.isStartPages()) ? "inline" : "horizontal"}
selectedKeys={[`${this.state.selectedMenuKey}`]}
style={{lineHeight: "64px", position: "absolute", left: "145px", right: "200px"}}
>
{
this.renderMenu()
}
</Menu>
{
this.renderAccount()
}
{this.state.account && <SelectLanguageBox languages={this.state.account.organization.languages} />}
</div>
</Header>
<Layout style={{backgroundColor: "#f5f5f5", alignItems: "stretch"}}>
<Card className="content-warp-card">
{
this.renderRouter()
}
</Card>
</Layout>
</Layout>
</div>
{this.state.account && <SelectLanguageBox languages={this.state.account.organization.languages} />}
</div>
</Header>
<Content style={{backgroundColor: "#f5f5f5", alignItems: "stretch", display: "flex", flexDirection: "column"}}>
<Card className="content-warp-card">
{
this.renderRouter()
}
</Card>
</Content>
{
this.renderFooter()
}
</Layout>
);
} else {
return (
<div>
<Layout>
<Header style={{padding: "0", marginBottom: "3px"}}>
{
Setting.isMobile() ? null : (
@@ -661,14 +587,12 @@ class App extends Component {
<Drawer title={i18next.t("general:Close")} placement="left" visible={this.state.menuVisible} onClose={this.onClose}>
<Menu
// theme="dark"
items={this.renderMenu()}
mode={(Setting.isMobile()) ? "inline" : "horizontal"}
selectedKeys={[`${this.state.selectedMenuKey}`]}
style={{lineHeight: "64px"}}
onClick={this.onClose}
>
{
this.renderMenu()
}
</Menu>
</Drawer>
<Button icon={<BarsOutlined />} onClick={this.showMenu} type="text">
@@ -681,10 +605,11 @@ class App extends Component {
{this.state.account && <SelectLanguageBox languages={this.state.account.organization.languages} />}
</div>
</Header>
{
this.renderRouter()
}
</div>
<Content style={{display: "flex", flexDirection: "column"}} >{
this.renderRouter()}
</Content>
{this.renderFooter()}
</Layout>
);
}
}
@@ -721,50 +646,47 @@ class App extends Component {
renderPage() {
if (this.isDoorPages()) {
return (
<div style={{display: "flex", flexDirection: "column", height: "100%"}}>
<div id="login-content-wrap" style={{flexDirection: "column"}}>
<Switch>
<Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage account={this.state.account} {...props} />)} />
<Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage account={this.state.account} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />)} />
<Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
<Route exact path="/login/:owner" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
<Route exact path="/auto-signup/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signup"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/signup/oauth/authorize" render={(props) => <SignupPage account={this.state.account} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/login/saml/authorize/:owner/:applicationName" render={(props) => <LoginPage account={this.state.account} type={"saml"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/cas/:owner/:casApplicationName/logout" render={(props) => this.renderHomeIfLoggedIn(<CasLogout clearAccount={() => this.setState({account: null})} {...props} />)} />
<Route exact path="/cas/:owner/:casApplicationName/login" render={(props) => {return (<LoginPage type={"cas"} mode={"signup"} account={this.state.account} {...props} />);}} />
<Route exact path="/callback" component={AuthCallback} />
<Route exact path="/callback/saml" component={SamlCallback} />
<Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...props} />)} />
<Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...props} />)} />
<Route exact path="/prompt" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} {...props} />)} />
<Route exact path="/prompt/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} {...props} />)} />
<Route exact path="/sysinfo" render={(props) => this.renderLoginIfNotLoggedIn(<SystemInfo {...props} />)} />
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
</Switch>
</div>
{
this.renderFooter()
}
</div>
<>
<Layout id="parent-area">
<Content style={{display: "flex", justifyContent: "center"}}>
<Switch>
<Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage account={this.state.account} {...props} />)} />
<Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage account={this.state.account} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />)} />
<Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
<Route exact path="/login/:owner" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
<Route exact path="/auto-signup/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signup"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/signup/oauth/authorize" render={(props) => <SignupPage account={this.state.account} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/login/saml/authorize/:owner/:applicationName" render={(props) => <LoginPage account={this.state.account} type={"saml"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
<Route exact path="/cas/:owner/:casApplicationName/logout" render={(props) => this.renderHomeIfLoggedIn(<CasLogout clearAccount={() => this.setState({account: null})} {...props} />)} />
<Route exact path="/cas/:owner/:casApplicationName/login" render={(props) => {return (<LoginPage type={"cas"} mode={"signup"} account={this.state.account} {...props} />);}} />
<Route exact path="/callback" component={AuthCallback} />
<Route exact path="/callback/saml" component={SamlCallback} />
<Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...props} />)} />
<Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...props} />)} />
<Route exact path="/prompt" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} {...props} />)} />
<Route exact path="/prompt/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} {...props} />)} />
<Route exact path="/sysinfo" render={(props) => this.renderLoginIfNotLoggedIn(<SystemInfo {...props} />)} />
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
</Switch>
</Content>
{
this.renderFooter()
}
</Layout>
</>
);
}
return (
<div id="parent-area">
<BackTop />
<>
<FloatButton.BackTop />
<CustomGithubCorner />
<div id="content-wrap" style={{flexDirection: "column"}}>
{
this.renderContent()
}
</div>
{
this.renderFooter()
this.renderContent()
}
</div>
</>
);
}
@@ -775,9 +697,16 @@ class App extends Component {
<Helmet>
<link rel="icon" href={"https://cdn.casdoor.com/static/favicon.png"} />
</Helmet>
{
this.renderPage()
}
<ConfigProvider theme={{
token: {
colorPrimary: "rgb(89,54,213)",
colorInfo: "rgb(89,54,213)",
},
}}>
{
this.renderPage()
}
</ConfigProvider>
</React.Fragment>
);
}
@@ -789,9 +718,16 @@ class App extends Component {
<title>{organization.displayName}</title>
<link rel="icon" href={organization.favicon} />
</Helmet>
{
this.renderPage()
}
<ConfigProvider theme={{
token: {
colorPrimary: "rgb(89,54,213)",
colorInfo: "rgb(89,54,213)",
},
}}>
{
this.renderPage()
}
</ConfigProvider>
</React.Fragment>
);
}

View File

@@ -1,6 +1,5 @@
/* stylelint-disable at-rule-name-case */
/* stylelint-disable selector-class-pattern */
@import "~antd/dist/antd.less";
@StaticBaseUrl: "https://cdn.casbin.org";
@@ -28,6 +27,11 @@
color: #61dafb;
}
img {
border-style: none;
vertical-align: middle;
}
#root {
height: 100%;
}
@@ -40,23 +44,8 @@
background-color: #f5f5f5;
}
#content-wrap {
display: flex;
flex: 1 1 0;
align-items: stretch;
width: 100%;
}
#login-content-wrap {
display: flex;
flex: 1 1 0;
width: 100%;
}
#footer {
bottom: 0;
width: 100%;
height: 70px; /* Footer height */
.panel-logo {
margin-bottom: 30px;
}
.language-box {
@@ -101,6 +90,7 @@
.forget-content {
padding: 10px 100px 20px;
margin: 30px auto;
border: 2px solid #fff;
border-radius: 7px;
background-color: rgb(255 255 255);
@@ -131,9 +121,9 @@
}
.loginBackground {
flex: auto;
display: flex;
align-items: center;
flex: 1 1 0;
background: #fff no-repeat;
background-size: 100% 100%;
background-attachment: fixed;

View File

@@ -191,7 +191,7 @@ class ApplicationEditPage extends React.Component {
Setting.showMessage("success", i18next.t("application:File uploaded successfully"));
this.updateApplicationField("termsOfUse", res.data);
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
}
}).finally(() => {
this.setState({uploading: false});
@@ -787,7 +787,7 @@ class ApplicationEditPage extends React.Component {
ApplicationBackend.updateApplication("admin", this.state.applicationName, application)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully saved");
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
applicationName: this.state.application.name,
});
@@ -798,22 +798,26 @@ class ApplicationEditPage extends React.Component {
this.props.history.push(`/applications/${this.state.application.organization}/${this.state.application.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateApplicationField("name", this.state.applicationName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteApplication() {
ApplicationBackend.deleteApplication(this.state.application)
.then(() => {
this.props.history.push("/applications");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/applications");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Application failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -70,7 +70,7 @@ class ApplicationListPage extends BaseListPage {
redirectUris: ["http://localhost:9000/callback"],
tokenFormat: "JWT",
expireInHours: 24 * 7,
formOffset: 8,
formOffset: 2,
};
}
@@ -80,27 +80,31 @@ class ApplicationListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/applications/${newApplication.organization}/${newApplication.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Application failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Application failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteApplication(i) {
ApplicationBackend.deleteApplication(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Application deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Application failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -239,7 +243,7 @@ class ApplicationListPage extends BaseListPage {
onConfirm={() => this.deleteApplication(index)}
disabled={record.name === "app-built-in"}
>
<Button style={{marginBottom: "10px"}} disabled={record.name === "app-built-in"} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} disabled={record.name === "app-built-in"} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -87,7 +87,7 @@ class BaseListPage extends React.Component {
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: "",
onFilterDropdownVisibleChange: visible => {
onFilterDropdownOpenChange: visible => {
if (visible) {
setTimeout(() => this.searchInput.select(), 100);
}

View File

@@ -65,6 +65,7 @@ class CertEditPage extends React.Component {
}
renderCert() {
const editorWidth = Setting.isMobile() ? 22 : 9;
return (
<Card size="small" title={
<div>
@@ -166,7 +167,7 @@ class CertEditPage extends React.Component {
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Certificate"), i18next.t("cert:Certificate - Tooltip"))} :
</Col>
<Col span={9} >
<Col span={editorWidth} >
<Button style={{marginRight: "10px", marginBottom: "10px"}} onClick={() => {
copy(this.state.cert.certificate);
Setting.showMessage("success", i18next.t("cert:Certificate copied to clipboard successfully"));
@@ -189,7 +190,7 @@ class CertEditPage extends React.Component {
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Private key"), i18next.t("cert:Private key - Tooltip"))} :
</Col>
<Col span={9} >
<Col span={editorWidth} >
<Button style={{marginRight: "10px", marginBottom: "10px"}} onClick={() => {
copy(this.state.cert.privateKey);
Setting.showMessage("success", i18next.t("cert:Private key copied to clipboard successfully"));
@@ -217,8 +218,8 @@ class CertEditPage extends React.Component {
const cert = Setting.deepCopy(this.state.cert);
CertBackend.updateCert(this.state.cert.owner, this.state.certName, cert)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
certName: this.state.cert.name,
});
@@ -229,22 +230,26 @@ class CertEditPage extends React.Component {
this.props.history.push(`/certs/${this.state.cert.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateCertField("name", this.state.certName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteCert() {
CertBackend.deleteCert(this.state.cert)
.then(() => {
this.props.history.push("/certs");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/certs");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Cert failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -45,27 +45,31 @@ class CertListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/certs/${newCert.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Cert failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Cert failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteCert(i) {
CertBackend.deleteCert(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Cert deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Cert failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -168,7 +172,7 @@ class CertListPage extends BaseListPage {
title={`Sure to delete cert: ${record.name} ?`}
onConfirm={() => this.deleteCert(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -140,7 +140,7 @@ export const CropperDiv = (props) => {
<Modal
maskClosable={false}
title={title}
visible={visible}
open={visible}
okText={i18next.t("user:Upload a photo")}
confirmLoading={confirmLoading}
onCancel={handleCancel}

View File

@@ -144,7 +144,7 @@ class LdapListPage extends React.Component {
onConfirm={() => this.deleteLdap(index)}
>
<Button style={{marginBottom: "10px"}}
type="danger">{i18next.t("general:Delete")}</Button>
type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -81,7 +81,7 @@ class LdapTable extends React.Component {
table = Setting.deleteRow(table, i);
this.updateTable(table);
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
}
}
)
@@ -162,7 +162,7 @@ class LdapTable extends React.Component {
onConfirm={() => this.deleteRow(table, index)}
>
<Button style={{marginBottom: "10px"}}
type="danger">{i18next.t("general:Delete")}</Button>
type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -158,8 +158,8 @@ class ModelEditPage extends React.Component {
const model = Setting.deepCopy(this.state.model);
ModelBackend.updateModel(this.state.organizationName, this.state.modelName, model)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
modelName: this.state.model.name,
});
@@ -170,22 +170,26 @@ class ModelEditPage extends React.Component {
this.props.history.push(`/models/${this.state.model.owner}/${this.state.model.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateModelField("name", this.state.modelName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteModel() {
ModelBackend.deleteModel(this.state.model)
.then(() => {
this.props.history.push("/models");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/models");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Model failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -40,27 +40,31 @@ class ModelListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/models/${newModel.owner}/${newModel.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Model failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Model failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteModel(i) {
ModelBackend.deleteModel(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Model deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Model failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -142,7 +146,7 @@ class ModelListPage extends BaseListPage {
title={`Sure to delete model: ${record.name} ?`}
onConfirm={() => this.deleteModel(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -336,7 +336,7 @@ class OrganizationEditPage extends React.Component {
OrganizationBackend.updateOrganization(this.state.organization.owner, this.state.organizationName, organization)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully saved");
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
organizationName: this.state.organization.name,
});
@@ -347,22 +347,26 @@ class OrganizationEditPage extends React.Component {
this.props.history.push(`/organizations/${this.state.organization.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateOrganizationField("name", this.state.organizationName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteOrganization() {
OrganizationBackend.deleteOrganization(this.state.organization)
.then(() => {
this.props.history.push("/organizations");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/organizations");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -77,27 +77,31 @@ class OrganizationListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/organizations/${newOrganization.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Organization failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Organization failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteOrganization(i) {
OrganizationBackend.deleteOrganization(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Organization deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Organization failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -227,7 +231,7 @@ class OrganizationListPage extends BaseListPage {
onConfirm={() => this.deleteOrganization(index)}
disabled={record.name === "built-in"}
>
<Button style={{marginBottom: "10px"}} disabled={record.name === "built-in"} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} disabled={record.name === "built-in"} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -64,7 +64,7 @@ export const PasswordModal = (props) => {
<Modal
maskClosable={false}
title={i18next.t("user:Password")}
visible={visible}
open={visible}
okText={i18next.t("user:Set Password")}
cancelText={i18next.t("user:Cancel")}
confirmLoading={confirmLoading}

View File

@@ -78,7 +78,7 @@ class PaymentEditPage extends React.Component {
this.setState({
isInvoiceLoading: false,
});
if (res.msg === "") {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully invoiced");
Setting.openLinkSafe(res.data);
this.getPayment();
@@ -90,7 +90,7 @@ class PaymentEditPage extends React.Component {
this.setState({
isInvoiceLoading: false,
});
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -117,7 +117,7 @@ class PaymentEditPage extends React.Component {
{" " + i18next.t("payment:Confirm your invoice information")}
</div>
}
visible={this.state.isModalVisible}
open={this.state.isModalVisible}
onOk={handleIssueInvoice}
onCancel={handleCancel}
okText={i18next.t("payment:Issue Invoice")}
@@ -443,8 +443,8 @@ class PaymentEditPage extends React.Component {
const payment = Setting.deepCopy(this.state.payment);
PaymentBackend.updatePayment(this.state.payment.owner, this.state.paymentName, payment)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
paymentName: this.state.payment.name,
});
@@ -455,22 +455,26 @@ class PaymentEditPage extends React.Component {
this.props.history.push(`/payments/${this.state.payment.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updatePaymentField("name", this.state.paymentName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deletePayment() {
PaymentBackend.deletePayment(this.state.payment)
.then(() => {
this.props.history.push("/payments");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/payments");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Payment failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -53,28 +53,32 @@ class PaymentListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/payments/${newPayment.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Payment failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
}
)
.catch(error => {
Setting.showMessage("error", `Payment failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deletePayment(i) {
PaymentBackend.deletePayment(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Payment deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Payment failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -222,7 +226,7 @@ class PaymentListPage extends BaseListPage {
title={`Sure to delete payment: ${record.name} ?`}
onConfirm={() => this.deletePayment(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -417,8 +417,8 @@ class PermissionEditPage extends React.Component {
const permission = Setting.deepCopy(this.state.permission);
PermissionBackend.updatePermission(this.state.organizationName, this.state.permissionName, permission)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
permissionName: this.state.permission.name,
});
@@ -429,22 +429,26 @@ class PermissionEditPage extends React.Component {
this.props.history.push(`/permissions/${this.state.permission.owner}/${this.state.permission.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updatePermissionField("name", this.state.permissionName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deletePermission() {
PermissionBackend.deletePermission(this.state.permission)
.then(() => {
this.props.history.push("/permissions");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/permissions");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Permission failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -50,27 +50,31 @@ class PermissionListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/permissions/${newPermission.owner}/${newPermission.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Permission failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Permission failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deletePermission(i) {
PermissionBackend.deletePermission(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Permission deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Permission failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -300,7 +304,7 @@ class PermissionListPage extends BaseListPage {
title={`Sure to delete permission: ${record.name} ?`}
onConfirm={() => this.deletePermission(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -81,11 +81,11 @@ class ProductBuyPage extends React.Component {
ProductBackend.buyProduct(this.state.product.owner, this.state.productName, provider.name)
.then((res) => {
if (res.msg === "") {
if (res.status === "ok") {
const payUrl = res.data;
Setting.goToLink(payUrl);
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.setState({
isPlacingOrder: false,
@@ -93,7 +93,7 @@ class ProductBuyPage extends React.Component {
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -271,8 +271,8 @@ class ProductEditPage extends React.Component {
const product = Setting.deepCopy(this.state.product);
ProductBackend.updateProduct(this.state.product.owner, this.state.productName, product)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
productName: this.state.product.name,
});
@@ -283,22 +283,26 @@ class ProductEditPage extends React.Component {
this.props.history.push(`/products/${this.state.product.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateProductField("name", this.state.productName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteProduct() {
ProductBackend.deleteProduct(this.state.product)
.then(() => {
this.props.history.push("/products");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/products");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Product failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -47,27 +47,31 @@ class ProductListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/products/${newProduct.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Product failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Product failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteProduct(i) {
ProductBackend.deleteProduct(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Product deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Product failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -239,7 +243,7 @@ class ProductListPage extends BaseListPage {
title={`Sure to delete product: ${record.name} ?`}
onConfirm={() => this.deleteProduct(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -257,7 +257,9 @@ class ProviderEditPage extends React.Component {
{id: "SAML", name: "SAML"},
{id: "Payment", name: "Payment"},
{id: "Captcha", name: "Captcha"},
].map((providerCategory, index) => <Option key={index} value={providerCategory.id}>{providerCategory.name}</Option>)
]
.sort((a, b) => a.name.localeCompare(b.name))
.map((providerCategory, index) => <Option key={index} value={providerCategory.id}>{providerCategory.name}</Option>)
}
</Select>
</Col>
@@ -280,7 +282,9 @@ class ProviderEditPage extends React.Component {
}
})}>
{
Setting.getProviderTypeOptions(this.state.provider.category).map((providerType, index) => <Option key={index} value={providerType.id}>{providerType.name}</Option>)
Setting.getProviderTypeOptions(this.state.provider.category)
.sort((a, b) => a.name.localeCompare(b.name))
.map((providerType, index) => <Option key={index} value={providerType.id}>{providerType.name}</Option>)
}
</Select>
</Col>
@@ -790,7 +794,7 @@ class ProviderEditPage extends React.Component {
ProviderBackend.updateProvider(this.state.owner, this.state.providerName, provider)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully saved");
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
owner: this.state.provider.owner,
providerName: this.state.provider.name,
@@ -802,22 +806,26 @@ class ProviderEditPage extends React.Component {
this.props.history.push(`/providers/${this.state.provider.owner}/${this.state.provider.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateProviderField("name", this.state.providerName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteProvider() {
ProviderBackend.deleteProvider(this.state.provider)
.then(() => {
this.props.history.push("/providers");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/providers");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Provider failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -63,27 +63,31 @@ class ProviderListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/providers/${newProvider.owner}/${newProvider.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Provider failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Provider failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteProvider(i) {
ProviderBackend.deleteProvider(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Provider deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Provider failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -208,7 +212,7 @@ class ProviderListPage extends BaseListPage {
title={`Sure to delete provider: ${record.name} ?`}
onConfirm={() => this.deleteProvider(index)}
>
<Button disabled={!Setting.isAdminUser(this.props.account) && (record.owner !== this.props.account.owner)} style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button disabled={!Setting.isAdminUser(this.props.account) && (record.owner !== this.props.account.owner)} style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -71,7 +71,7 @@ export const ResetModal = (props) => {
<Modal
maskClosable={false}
title={buttonText}
visible={visible}
open={visible}
okText={buttonText}
cancelText={i18next.t("user:Cancel")}
confirmLoading={confirmLoading}

View File

@@ -43,15 +43,18 @@ class ResourceListPage extends BaseListPage {
deleteResource(i) {
ResourceBackend.deleteResource(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Resource deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Resource failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -207,16 +210,14 @@ class ResourceListPage extends BaseListPage {
if (record.fileType === "image") {
return (
<a target="_blank" rel="noreferrer" href={record.url}>
<img src={record.url} alt={record.name} width={100} />
<img src={record.url} alt={record.name} width={200} />
</a>
);
} else if (record.fileType === "video") {
return (
<div>
<video width={100} controls>
<source src={text} type="video/mp4" />
</video>
</div>
<video width={200} controls>
<source src={record.url} type="video/mp4" />
</video>
);
}
},
@@ -256,7 +257,7 @@ class ResourceListPage extends BaseListPage {
okText={i18next.t("user:OK")}
cancelText={i18next.t("user:Cancel")}
>
<Button type="danger">{i18next.t("general:Delete")}</Button>
<Button type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -196,8 +196,8 @@ class RoleEditPage extends React.Component {
const role = Setting.deepCopy(this.state.role);
RoleBackend.updateRole(this.state.organizationName, this.state.roleName, role)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
roleName: this.state.role.name,
});
@@ -208,22 +208,26 @@ class RoleEditPage extends React.Component {
this.props.history.push(`/roles/${this.state.role.owner}/${this.state.role.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateRoleField("name", this.state.roleName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteRole() {
RoleBackend.deleteRole(this.state.role)
.then(() => {
this.props.history.push("/roles");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/roles");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Role failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -42,27 +42,31 @@ class RoleListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/roles/${newRole.owner}/${newRole.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Role failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Role failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteRole(i) {
RoleBackend.deleteRole(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Role deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Role failed to delete: ${error}`);
});
}
@@ -175,7 +179,7 @@ class RoleListPage extends BaseListPage {
title={`Sure to delete role: ${record.name} ?`}
onConfirm={() => this.deleteRole(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -33,14 +33,14 @@ class SelectLanguageBox extends React.Component {
}
items = [
this.getItem("English", "en", flagIcon("US", "English")),
this.getItem("简体中文", "zh", flagIcon("CN", "简体中文")),
this.getItem("Español", "es", flagIcon("ES", "Español")),
this.getItem("Français", "fr", flagIcon("FR", "Français")),
this.getItem("Deutsch", "de", flagIcon("DE", "Deutsch")),
this.getItem("日本語", "ja", flagIcon("JP", "日本語")),
this.getItem("한국어", "ko", flagIcon("KR", "한국어")),
this.getItem("Русский", "ru", flagIcon("RU", "Русский")),
Setting.getItem("English", "en", flagIcon("US", "English")),
Setting.getItem("简体中文", "zh", flagIcon("CN", "简体中文")),
Setting.getItem("Español", "es", flagIcon("ES", "Español")),
Setting.getItem("Français", "fr", flagIcon("FR", "Français")),
Setting.getItem("Deutsch", "de", flagIcon("DE", "Deutsch")),
Setting.getItem("日本語", "ja", flagIcon("JP", "日本語")),
Setting.getItem("한국어", "ko", flagIcon("KR", "한국어")),
Setting.getItem("Русский", "ru", flagIcon("RU", "Русский")),
];
getOrganizationLanguages(languages) {
@@ -51,10 +51,6 @@ class SelectLanguageBox extends React.Component {
return select;
}
getItem(label, key, icon) {
return {key, icon, label};
}
render() {
const languageItems = this.getOrganizationLanguages(this.state.languages);
const menu = (

View File

@@ -732,12 +732,12 @@ export function renderLogo(application) {
if (application.homepageUrl !== "") {
return (
<a target="_blank" rel="noreferrer" href={application.homepageUrl}>
<img width={250} src={application.logo} alt={application.displayName} style={{marginBottom: "10px"}} />
<img className="panel-logo" width={250} src={application.logo} alt={application.displayName} />
</a>
);
} else {
return (
<img width={250} src={application.logo} alt={application.displayName} style={{marginBottom: "10px"}} />
<img className="panel-logo" width={250} src={application.logo} alt={application.displayName} />
);
}
}
@@ -858,6 +858,15 @@ export function getLabel(text, tooltip) {
);
}
export function getItem(label, key, icon, children, type) {
return {
key,
icon,
children,
label,
type,
};
}
function repeat(str, len) {
while (str.length < len) {
str += str.substr(0, len - str.length);

View File

@@ -298,8 +298,8 @@ class SyncerEditPage extends React.Component {
const syncer = Setting.deepCopy(this.state.syncer);
SyncerBackend.updateSyncer(this.state.syncer.owner, this.state.syncerName, syncer)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
syncerName: this.state.syncer.name,
});
@@ -310,22 +310,26 @@ class SyncerEditPage extends React.Component {
this.props.history.push(`/syncers/${this.state.syncer.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateSyncerField("name", this.state.syncerName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteSyncer() {
SyncerBackend.deleteSyncer(this.state.syncer)
.then(() => {
this.props.history.push("/syncers");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/syncers");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Syncer failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -51,27 +51,31 @@ class SyncerListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/syncers/${newSyncer.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Syncer failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Syncer failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteSyncer(i) {
SyncerBackend.deleteSyncer(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Syncer deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Syncer failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -232,7 +236,7 @@ class SyncerListPage extends BaseListPage {
title={`Sure to delete syncer: ${record.name} ?`}
onConfirm={() => this.deleteSyncer(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -13,32 +13,33 @@
// limitations under the License.
import * as Setting from "./Setting";
import i18next from "i18next";
export function sendTestEmail(provider, email) {
testEmailProvider(provider, email)
.then((res) => {
if (res.msg === "") {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully send email");
} else {
Setting.showMessage("error", res.msg);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
export function connectSmtpServer(provider) {
testEmailProvider(provider)
.then((res) => {
if (res.msg === "") {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully connecting smtp server");
} else {
Setting.showMessage("error", res.msg);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -167,8 +167,8 @@ class TokenEditPage extends React.Component {
const token = Setting.deepCopy(this.state.token);
TokenBackend.updateToken(this.state.token.owner, this.state.tokenName, token)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
tokenName: this.state.token.name,
});
@@ -179,22 +179,26 @@ class TokenEditPage extends React.Component {
this.props.history.push(`/tokens/${this.state.token.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateTokenField("name", this.state.tokenName);
}
})
.catch(error => {
Setting.showMessage("error", `failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteToken() {
TokenBackend.deleteToken(this.state.token)
.then(() => {
this.props.history.push("/tokens");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/tokens");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Token failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -44,27 +44,31 @@ class TokenListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/tokens/${newToken.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Token failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Token failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteToken(i) {
TokenBackend.deleteToken(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Token deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Token failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -201,7 +205,7 @@ class TokenListPage extends BaseListPage {
title={`Sure to delete token: ${record.name} ?`}
onConfirm={() => this.deleteToken(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -612,7 +612,7 @@ class UserEditPage extends React.Component {
UserBackend.updateUser(this.state.organizationName, this.state.userName, user)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully saved");
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
organizationName: this.state.user.owner,
userName: this.state.user.name,
@@ -632,23 +632,27 @@ class UserEditPage extends React.Component {
}
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateUserField("owner", this.state.organizationName);
this.updateUserField("name", this.state.userName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteUser() {
UserBackend.deleteUser(this.state.user)
.then(() => {
this.props.history.push("/users");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/users");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `User failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -74,27 +74,31 @@ class UserListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/users/${newUser.owner}/${newUser.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `User failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `User failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteUser(i) {
UserBackend.deleteUser(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "User deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `User failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -349,7 +353,7 @@ class UserListPage extends BaseListPage {
title={`Sure to delete user: ${record.name} ?`}
onConfirm={() => this.deleteUser(index)}
>
<Button disabled={disabled} style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button disabled={disabled} style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -26,7 +26,7 @@ class WebAuthnCredentialTable extends React.Component {
registerWebAuthn() {
UserWebauthnBackend.registerWebauthnCredential().then((res) => {
if (res.msg === "") {
if (res.status === "ok") {
Setting.showMessage("success", "Successfully added webauthn credentials");
} else {
Setting.showMessage("error", res.msg);
@@ -34,7 +34,7 @@ class WebAuthnCredentialTable extends React.Component {
this.props.refresh();
}).catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -51,7 +51,7 @@ class WebAuthnCredentialTable extends React.Component {
width: "170px",
render: (text, record, index) => {
return (
<Button style={{marginTop: "5px", marginBottom: "5px", marginRight: "5px"}} type="danger" onClick={() => {this.deleteRow(this.props.table, index);}}>
<Button style={{marginTop: "5px", marginBottom: "5px", marginRight: "5px"}} type="primary" danger onClick={() => {this.deleteRow(this.props.table, index);}}>
{i18next.t("general:Delete")}
</Button>
);

View File

@@ -296,8 +296,8 @@ class WebhookEditPage extends React.Component {
const webhook = Setting.deepCopy(this.state.webhook);
WebhookBackend.updateWebhook(this.state.webhook.owner, this.state.webhookName, webhook)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", "Successfully saved");
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
webhookName: this.state.webhook.name,
});
@@ -308,22 +308,26 @@ class WebhookEditPage extends React.Component {
this.props.history.push(`/webhooks/${this.state.webhook.name}`);
}
} else {
Setting.showMessage("error", res.msg);
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
this.updateWebhookField("name", this.state.webhookName);
}
})
.catch(error => {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteWebhook() {
WebhookBackend.deleteWebhook(this.state.webhook)
.then(() => {
this.props.history.push("/webhooks");
.then((res) => {
if (res.status === "ok") {
this.props.history.push("/webhooks");
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Webhook failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}

View File

@@ -44,27 +44,31 @@ class WebhookListPage extends BaseListPage {
.then((res) => {
if (res.status === "ok") {
this.props.history.push({pathname: `/webhooks/${newWebhook.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
Setting.showMessage("error", `Webhook failed to add: ${res.msg}`);
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Webhook failed to add: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
deleteWebhook(i) {
WebhookBackend.deleteWebhook(this.state.data[i])
.then((res) => {
Setting.showMessage("success", "Webhook deleted successfully");
this.setState({
data: Setting.deleteRow(this.state.data, i),
pagination: {total: this.state.pagination.total - 1},
});
}
)
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},
});
} else {
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
}
})
.catch(error => {
Setting.showMessage("error", `Webhook failed to delete: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -197,7 +201,7 @@ class WebhookListPage extends BaseListPage {
title={`Sure to delete webhook: ${record.name} ?`}
onConfirm={() => this.deleteWebhook(index)}
>
<Button style={{marginBottom: "10px"}} type="danger">{i18next.t("general:Delete")}</Button>
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
</Popconfirm>
</div>
);

View File

@@ -126,7 +126,7 @@ class AuthCallback extends React.Component {
// If service was not specified, Casdoor must display a message notifying the client that it has successfully initiated a single sign-on session.
msg += "Now you can visit apps protected by Casdoor.";
}
Util.showMessage("success", msg);
Setting.showMessage("success", msg);
if (casService !== "") {
const st = res.data;
@@ -135,7 +135,7 @@ class AuthCallback extends React.Component {
window.location.href = newUrl.toString();
}
} else {
Util.showMessage("error", `Failed to log in: ${res.msg}`);
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
}
});
return;
@@ -148,7 +148,7 @@ class AuthCallback extends React.Component {
if (res.status === "ok") {
const responseType = this.getResponseType();
if (responseType === "login") {
Util.showMessage("success", "Logged in successfully");
Setting.showMessage("success", "Logged in successfully");
// Setting.goToLinkSoft(this, "/");
const link = Setting.getFromLink();
@@ -156,7 +156,7 @@ class AuthCallback extends React.Component {
} else if (responseType === "code") {
const code = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
// Util.showMessage("success", `Authorization code: ${res.data}`);
// Setting.showMessage("success", `Authorization code: ${res.data}`);
} else if (responseType === "token" || responseType === "id_token") {
const token = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);

View File

@@ -61,10 +61,7 @@ class ForgetPage extends React.Component {
if (this.state.applicationName !== undefined) {
this.getApplication();
} else {
Util.showMessage(
"error",
i18next.t("forget:Unknown forget type: ") + this.state.type
);
Setting.showMessage("error", i18next.t("forget:Unknown forget type: ") + this.state.type);
}
}
@@ -102,6 +99,13 @@ class ForgetPage extends React.Component {
if (res.status === "ok") {
const phone = res.data.phone;
const email = res.data.email;
const saveFields = () => {
if (this.state.isFixed) {
forms.step2.setFieldsValue({email: this.state.fixedContent});
this.setState({username: this.state.fixedContent});
}
this.setState({current: 1});
};
this.setState({phone: phone, email: email, username: res.data.name, name: res.data.name});
if (phone !== "" && email === "") {
@@ -116,19 +120,15 @@ class ForgetPage extends React.Component {
switch (res.data2) {
case "email":
this.setState({isFixed: true, fixedContent: email, verifyType: "email"});
this.setState({isFixed: true, fixedContent: email, verifyType: "email"}, () => {saveFields();});
break;
case "phone":
this.setState({isFixed: true, fixedContent: phone, verifyType: "phone"});
this.setState({isFixed: true, fixedContent: phone, verifyType: "phone"}, () => {saveFields();});
break;
default:
saveFields();
break;
}
if (this.state.isFixed) {
forms.step2.setFieldsValue({email: this.state.fixedContent});
this.setState({username: this.state.fixedContent});
}
this.setState({current: 1});
} else {
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
}
@@ -136,26 +136,28 @@ class ForgetPage extends React.Component {
break;
case "step2":
const oAuthParams = Util.getOAuthGetParameters();
const login = () => {
AuthBackend.login({
application: forms.step2.getFieldValue("application"),
organization: forms.step2.getFieldValue("organization"),
username: this.state.username,
name: this.state.name,
code: forms.step2.getFieldValue("emailCode"),
phonePrefix: this.state.application?.organizationObj.phonePrefix,
type: "login",
}, oAuthParams).then(res => {
if (res.status === "ok") {
this.setState({current: 2, userId: res.data, username: res.data.split("/")[1]});
} else {
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
}
});
};
if (this.state.verifyType === "email") {
this.setState({username: this.state.email});
this.setState({username: this.state.email}, () => {login();});
} else if (this.state.verifyType === "phone") {
this.setState({username: this.state.phone});
this.setState({username: this.state.phone}, () => {login();});
}
AuthBackend.login({
application: forms.step2.getFieldValue("application"),
organization: forms.step2.getFieldValue("organization"),
username: this.state.username,
name: this.state.name,
code: forms.step2.getFieldValue("emailCode"),
phonePrefix: this.state.application?.organizationObj.phonePrefix,
type: "login",
}, oAuthParams).then(res => {
if (res.status === "ok") {
this.setState({current: 2, userId: res.data, username: res.data.split("/")[1]});
} else {
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
}
});
break;
default:
break;
@@ -490,7 +492,7 @@ class ForgetPage extends React.Component {
return (
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
<CustomGithubCorner />
<div className="login-content forget-content" style={{padding: Setting.isMobile() ? "0" : null, boxShadow: Setting.isMobile() ? "none" : null}}>
<div className="forget-content" style={{padding: Setting.isMobile() ? "0" : null, boxShadow: Setting.isMobile() ? "none" : null}}>
<Row>
<Col span={24} style={{justifyContent: "center"}}>
<Row>

View File

@@ -30,8 +30,6 @@ import {CountDownInput} from "../common/CountDownInput";
import SelectLanguageBox from "../SelectLanguageBox";
import {CaptchaModal} from "../common/CaptchaModal";
const {TabPane} = Tabs;
class LoginPage extends React.Component {
constructor(props) {
super(props);
@@ -67,7 +65,7 @@ class LoginPage extends React.Component {
} else if (this.state.type === "saml") {
this.getSamlApplication();
} else {
Util.showMessage("error", `Unknown authentication type: ${this.state.type}`);
Setting.showMessage("error", `Unknown authentication type: ${this.state.type}`);
}
}
@@ -92,7 +90,7 @@ class LoginPage extends React.Component {
application: res.data,
});
} else {
// Util.showMessage("error", res.msg);
// Setting.showMessage("error", res.msg);
this.setState({
application: res.data,
msg: res.msg,
@@ -122,7 +120,7 @@ class LoginPage extends React.Component {
applicationName: res.data.name,
});
} else {
Util.showMessage("error", res.msg);
Setting.showMessage("error", res.msg);
}
});
}
@@ -269,7 +267,7 @@ class LoginPage extends React.Component {
// If service was not specified, Casdoor must display a message notifying the client that it has successfully initiated a single sign-on session.
msg += "Now you can visit apps protected by Casdoor.";
}
Util.showMessage("success", msg);
Setting.showMessage("success", msg);
this.setState({openCaptchaModal: false});
@@ -281,7 +279,7 @@ class LoginPage extends React.Component {
}
} else {
this.setState({openCaptchaModal: false});
Util.showMessage("error", `Failed to log in: ${res.msg}`);
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
}
});
} else {
@@ -295,13 +293,13 @@ class LoginPage extends React.Component {
const responseType = values["type"];
if (responseType === "login") {
Util.showMessage("success", "Logged in successfully");
Setting.showMessage("success", "Logged in successfully");
const link = Setting.getFromLink();
Setting.goToLink(link);
} else if (responseType === "code") {
this.postCodeLoginAction(res);
// Util.showMessage("success", `Authorization code: ${res.data}`);
// Setting.showMessage("success", `Authorization code: ${res.data}`);
} else if (responseType === "token" || responseType === "id_token") {
const accessToken = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}#${responseType}=${accessToken}?state=${oAuthParams.state}&token_type=bearer`);
@@ -312,7 +310,7 @@ class LoginPage extends React.Component {
}
} else {
this.setState({openCaptchaModal: false});
Util.showMessage("error", `Failed to log in: ${res.msg}`);
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
}
});
}
@@ -363,7 +361,7 @@ class LoginPage extends React.Component {
size="large"
>
<Form.Item
style={{height: 0, visibility: "hidden"}}
hidden={true}
name="application"
rules={[
{
@@ -374,7 +372,7 @@ class LoginPage extends React.Component {
>
</Form.Item>
<Form.Item
style={{height: 0, visibility: "hidden"}}
hidden={true}
name="organization"
rules={[
{
@@ -481,7 +479,7 @@ class LoginPage extends React.Component {
{application.displayName}
</span>
</a>
:
:
</div>
<br />
{
@@ -673,7 +671,7 @@ class LoginPage extends React.Component {
}),
})
.then(res => res.json()).then((res) => {
if (res.msg === "") {
if (res.status === "ok") {
const responseType = values["type"];
if (responseType === "code") {
this.postCodeLoginAction(res);
@@ -689,7 +687,7 @@ class LoginPage extends React.Component {
}
})
.catch(error => {
Setting.showMessage("error", `${i18next.t("application:Failed to connect to server: ")}${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}${error}`);
});
});
}
@@ -734,21 +732,16 @@ class LoginPage extends React.Component {
renderMethodChoiceBox() {
const application = this.getApplicationObj();
const items = [
{label: i18next.t("login:Password"), key: "password"},
];
application.enableCodeSignin ? items.push({label: i18next.t("login:Verification Code"), key: "verificationCode"}) : null;
application.enableWebAuthn ? items.push({label: i18next.t("login:WebAuthn"), key: "webAuthn"}) : null;
if (application.enableCodeSignin || application.enableWebAuthn) {
return (
<div>
<Tabs size={"small"} defaultActiveKey="password" onChange={(key) => {this.setState({loginMethod: key});}} centered>
<TabPane tab={i18next.t("login:Password")} key="password" />
{
!application.enableCodeSignin ? null : (
<TabPane tab={i18next.t("login:Verification Code")} key="verificationCode" />
)
}
{
!application.enableWebAuthn ? null : (
<TabPane tab={i18next.t("login:WebAuthn")} key="webAuthn" />
)
}
<Tabs items={items} size={"small"} defaultActiveKey="password" onChange={(key) => {this.setState({loginMethod: key});}} centered>
</Tabs>
</div>
);
@@ -781,7 +774,7 @@ class LoginPage extends React.Component {
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
<CustomGithubCorner />
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
{Setting.inIframe() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
{Setting.inIframe() || Setting.isMobile() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
<div className="login-panel">
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
<div dangerouslySetInnerHTML={{__html: application.formSideHtml}} />

View File

@@ -203,9 +203,9 @@ class PromptPage extends React.Component {
const user = Setting.deepCopy(this.state.user);
UserBackend.updateUser(this.state.user.owner, this.state.user.name, user)
.then((res) => {
if (res.msg === "") {
if (res.status === "ok") {
if (isFinal) {
Setting.showMessage("success", "Successfully saved");
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.logout();
}
@@ -217,7 +217,7 @@ class PromptPage extends React.Component {
})
.catch(error => {
if (isFinal) {
Setting.showMessage("error", `Failed to connect to server: ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
}
});
}

View File

@@ -16,7 +16,6 @@ import React from "react";
import {Button, Result} from "antd";
import i18next from "i18next";
import {authConfig} from "./Auth";
import * as Util from "./Util";
import * as ApplicationBackend from "../backend/ApplicationBackend";
import * as Setting from "../Setting";
@@ -34,7 +33,7 @@ class ResultPage extends React.Component {
if (this.state.applicationName !== undefined) {
this.getApplication();
} else {
Util.showMessage("error", `Unknown application name: ${this.state.applicationName}`);
Setting.showMessage("error", `Unknown application name: ${this.state.applicationName}`);
}
}

View File

@@ -79,7 +79,7 @@ class SamlCallback extends React.Component {
if (res.status === "ok") {
const responseType = this.getResponseType(redirectUri);
if (responseType === "login") {
Util.showMessage("success", "Logged in successfully");
Setting.showMessage("success", "Logged in successfully");
Setting.goToLink("/");
} else if (responseType === "code") {
const code = res.data;

View File

@@ -42,7 +42,7 @@ const formItemLayout = {
span: 24,
},
sm: {
span: 18,
span: 16,
},
},
};
@@ -94,7 +94,7 @@ class SignupPage extends React.Component {
if (applicationName !== undefined) {
this.getApplication(applicationName);
} else {
Util.showMessage("error", `Unknown application name: ${applicationName}`);
Setting.showMessage("error", `Unknown application name: ${applicationName}`);
}
}
@@ -510,7 +510,7 @@ class SignupPage extends React.Component {
return (
<Modal
title={i18next.t("signup:Terms of Use")}
visible={this.state.isTermsOfUseVisible}
open={this.state.isTermsOfUseVisible}
width={"55vw"}
closable={false}
okText={i18next.t("signup:Accept")}
@@ -563,12 +563,13 @@ class SignupPage extends React.Component {
application: application.name,
organization: application.organization,
}}
style={{width: !Setting.isMobile() ? "400px" : "300px"}}
size="large"
layout={Setting.isMobile() ? "vertical" : "horizontal"}
style={{width: Setting.isMobile() ? "300px" : "400px"}}
>
<Form.Item
style={{height: 0, visibility: "hidden"}}
name="application"
hidden={true}
rules={[
{
required: true,
@@ -578,8 +579,8 @@ class SignupPage extends React.Component {
>
</Form.Item>
<Form.Item
style={{height: 0, visibility: "hidden"}}
name="organization"
hidden={true}
rules={[
{
required: true,
@@ -595,7 +596,7 @@ class SignupPage extends React.Component {
<Button type="primary" htmlType="submit">
{i18next.t("account:Sign Up")}
</Button>
&nbsp;&nbsp;{i18next.t("signup:Have account?")}&nbsp;
&nbsp;&nbsp;{i18next.t("signup:Have account?")}&nbsp;
<a onClick={() => {
const linkInStorage = sessionStorage.getItem("signinUrl");
if (linkInStorage !== null && linkInStorage !== "") {
@@ -632,24 +633,22 @@ class SignupPage extends React.Component {
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
<CustomGithubCorner />
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
{Setting.inIframe() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
{Setting.inIframe() || Setting.isMobile() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
<div className="login-panel" >
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
<div dangerouslySetInnerHTML={{__html: application.formSideHtml}} />
</div>
<div className="login-form">
<div >
{
Setting.renderHelmet(application)
}
{
Setting.renderLogo(application)
}
<SelectLanguageBox languages={application.organizationObj.languages} style={{top: "55px", right: "5px", position: "absolute"}} />
{
this.renderForm(application)
}
</div>
{
Setting.renderHelmet(application)
}
{
Setting.renderLogo(application)
}
<SelectLanguageBox languages={application.organizationObj.languages} style={{top: "55px", right: "5px", position: "absolute"}} />
{
this.renderForm(application)
}
</div>
</div>
</div>

View File

@@ -13,19 +13,11 @@
// limitations under the License.
import React from "react";
import {Alert, Button, Result, message} from "antd";
import {Alert, Button, Result} from "antd";
import {getWechatMessageEvent} from "./AuthBackend";
import * as Setting from "../Setting";
import * as Provider from "./Provider";
export function showMessage(type, text) {
if (type === "success") {
message.success(text);
} else if (type === "error") {
message.error(text);
}
}
export function renderMessage(msg) {
if (msg !== null) {
return (
@@ -36,7 +28,7 @@ export function renderMessage(msg) {
description={msg}
type="error"
action={
<Button size="small" danger>
<Button size="small" type="primary" danger>
Detail
</Button>
}

View File

@@ -148,7 +148,7 @@ export const CaptchaModal = ({
maskClosable={false}
destroyOnClose={true}
title={i18next.t("general:Captcha")}
visible={visible}
open={visible}
width={348}
footer={renderFooter()}
>

View File

@@ -156,7 +156,7 @@ export const CountDownInput = (props) => {
maskClosable={false}
destroyOnClose={true}
title={i18next.t("general:Captcha")}
visible={visible}
open={visible}
okText={i18next.t("user:OK")}
cancelText={i18next.t("user:Cancel")}
onOk={handleOk}

View File

@@ -90,16 +90,15 @@ class PolicyTable extends React.Component {
this.setState({loading: true});
AdapterBackend.syncPolicies(this.props.owner, this.props.name)
.then((res) => {
if (res.status !== "error") {
this.setState({loading: false, policyLists: res});
if (res.status === "ok") {
this.setState({policyLists: res});
} else {
this.setState({loading: false});
Setting.showMessage("error", `Adapter failed to get policies, ${res.msg}`);
Setting.showMessage("error", `${i18next.t("adapter:Failed to sync policies")}: ${res.msg}`);
}
this.setState({loading: false});
})
.catch(error => {
this.setState({loading: false});
Setting.showMessage("error", `Adapter failed to get policies, ${error}`);
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
});
}
@@ -107,9 +106,9 @@ class PolicyTable extends React.Component {
AdapterBackend.UpdatePolicy(this.props.owner, this.props.name, [this.state.oldPolicy, table[i]]).then(res => {
if (res.status === "ok") {
this.setState({editingIndex: "", oldPolicy: ""});
Setting.showMessage("success", i18next.t("adapter:Update policy successfully"));
Setting.showMessage("success", i18next.t("general:Successfully saved"));
} else {
Setting.showMessage("error", i18next.t(`adapter:Update policy failed, ${res.msg}`));
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
}
});
}
@@ -119,12 +118,12 @@ class PolicyTable extends React.Component {
if (res.status === "ok") {
this.setState({editingIndex: "", oldPolicy: "", add: false});
if (res.data !== "Affected") {
Setting.showMessage("info", i18next.t("adapter:Repeated policy"));
Setting.showMessage("info", i18next.t("adapter:Repeated policy rules"));
} else {
Setting.showMessage("success", i18next.t("adapter:Add policy successfully"));
Setting.showMessage("success", i18next.t("general:Successfully added"));
}
} else {
Setting.showMessage("error", i18next.t(`adapter:Add policy failed, ${res.msg}`));
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
}
});
}
@@ -134,9 +133,9 @@ class PolicyTable extends React.Component {
if (res.status === "ok") {
table = Setting.deleteRow(table, i);
this.updateTable(table);
Setting.showMessage("success", i18next.t("adapter:Delete policy successfully"));
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
} else {
Setting.showMessage("error", i18next.t(`adapter:Delete policy failed, ${res.msg}`));
Setting.showMessage("error", i18next.t("general:Failed to delete"));
}
});
}

View File

@@ -89,7 +89,7 @@ i18n.use(initReactI18next).init({
keySeparator: false,
interpolation: {
escapeValue: false,
escapeValue: true,
},
// debug: true,
saveMissing: true,

View File

@@ -18,6 +18,7 @@ import "react-app-polyfill/stable";
import React from "react";
import {createRoot} from "react-dom/client";
import "./index.css";
import "./App.less";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import {BrowserRouter} from "react-router-dom";

View File

@@ -6,15 +6,13 @@
"Sign Up": "Registrieren"
},
"adapter": {
"Add policy successfully": "Add policy successfully",
"Delete policy successfully": "Delete policy successfully",
"Edit Adapter": "Edit Adapter",
"Failed to sync policies: ": "Failed to sync policies: ",
"New Adapter": "New Adapter",
"Policies": "Policies",
"Policies - Tooltip": "Policies - Tooltip",
"Repeated policy": "Repeated policy",
"Sync": "Sync",
"Update policy successfully": "Update policy successfully"
"Repeated policy rules": "Repeated policy rules",
"Sync": "Sync"
},
"application": {
"Always": "Always",
@@ -38,7 +36,6 @@
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
"Enable signup": "Anmeldung aktivieren",
"Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to connect to server": "Failed to connect to server",
"File uploaded successfully": "Datei erfolgreich hochgeladen",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Edit",
@@ -128,7 +125,7 @@
"Please input your username!": "Bitte geben Sie Ihren Benutzernamen ein!",
"Reset": "Reset",
"Retrieve password": "Passwort abrufen",
"Unknown forget type": "Unknown forget type",
"Unknown forget type: ": "Unknown forget type: ",
"Verify": "Überprüfen"
},
"general": {
@@ -167,6 +164,10 @@
"Edit": "Bearbeiten",
"Email": "E-Mail",
"Email - Tooltip": "email",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
"Failed to save": "Failed to save",
"Favicon": "Favicon",
"Favicon - Tooltip": "Application icon",
"First name": "First name",
@@ -237,6 +238,9 @@
"Sorry, you do not have permission to access this page.": "Sorry, you do not have permission to access this page.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Successfully added": "Successfully added",
"Successfully deleted": "Successfully deleted",
"Successfully saved": "Successfully saved",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",

View File

@@ -6,15 +6,13 @@
"Sign Up": "Sign Up"
},
"adapter": {
"Add policy successfully": "Add policy successfully",
"Delete policy successfully": "Delete policy successfully",
"Edit Adapter": "Edit Adapter",
"Failed to sync policies: ": "Failed to sync policies: ",
"New Adapter": "New Adapter",
"Policies": "Policies",
"Policies - Tooltip": "Policies - Tooltip",
"Repeated policy": "Repeated policy",
"Sync": "Sync",
"Update policy successfully": "Update policy successfully"
"Repeated policy rules": "Repeated policy rules",
"Sync": "Sync"
},
"application": {
"Always": "Always",
@@ -38,7 +36,6 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "Enable signup",
"Enable signup - Tooltip": "Enable signup - Tooltip",
"Failed to connect to server": "Failed to connect to server",
"File uploaded successfully": "File uploaded successfully",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Edit",
@@ -128,7 +125,7 @@
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Unknown forget type": "Unknown forget type",
"Unknown forget type: ": "Unknown forget type: ",
"Verify": "Verify"
},
"general": {
@@ -167,6 +164,10 @@
"Edit": "Edit",
"Email": "Email",
"Email - Tooltip": "Email - Tooltip",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
"Failed to save": "Failed to save",
"Favicon": "Favicon",
"Favicon - Tooltip": "Favicon - Tooltip",
"First name": "First name",
@@ -237,6 +238,9 @@
"Sorry, you do not have permission to access this page.": "Sorry, you do not have permission to access this page.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Successfully added": "Successfully added",
"Successfully deleted": "Successfully deleted",
"Successfully saved": "Successfully saved",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",

View File

@@ -6,15 +6,13 @@
"Sign Up": "S'inscrire"
},
"adapter": {
"Add policy successfully": "Add policy successfully",
"Delete policy successfully": "Delete policy successfully",
"Edit Adapter": "Edit Adapter",
"Failed to sync policies: ": "Failed to sync policies: ",
"New Adapter": "New Adapter",
"Policies": "Policies",
"Policies - Tooltip": "Policies - Tooltip",
"Repeated policy": "Repeated policy",
"Sync": "Sync",
"Update policy successfully": "Update policy successfully"
"Repeated policy rules": "Repeated policy rules",
"Sync": "Sync"
},
"application": {
"Always": "Always",
@@ -38,7 +36,6 @@
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
"Enable signup": "Activer l'inscription",
"Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to connect to server": "Failed to connect to server",
"File uploaded successfully": "Fichier téléchargé avec succès",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Edit",
@@ -128,7 +125,7 @@
"Please input your username!": "Veuillez entrer votre nom d'utilisateur !",
"Reset": "Reset",
"Retrieve password": "Récupérer le mot de passe",
"Unknown forget type": "Unknown forget type",
"Unknown forget type: ": "Unknown forget type: ",
"Verify": "Vérifier"
},
"general": {
@@ -167,6 +164,10 @@
"Edit": "Editer",
"Email": "Courriel",
"Email - Tooltip": "email",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
"Failed to save": "Failed to save",
"Favicon": "Favicon",
"Favicon - Tooltip": "Application icon",
"First name": "First name",
@@ -237,6 +238,9 @@
"Sorry, you do not have permission to access this page.": "Désolé, vous n'avez pas la permission d'accéder à cette page.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Successfully added": "Successfully added",
"Successfully deleted": "Successfully deleted",
"Successfully saved": "Successfully saved",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Synchronisateurs",

View File

@@ -6,15 +6,13 @@
"Sign Up": "新規登録"
},
"adapter": {
"Add policy successfully": "Add policy successfully",
"Delete policy successfully": "Delete policy successfully",
"Edit Adapter": "Edit Adapter",
"Failed to sync policies: ": "Failed to sync policies: ",
"New Adapter": "New Adapter",
"Policies": "Policies",
"Policies - Tooltip": "Policies - Tooltip",
"Repeated policy": "Repeated policy",
"Sync": "Sync",
"Update policy successfully": "Update policy successfully"
"Repeated policy rules": "Repeated policy rules",
"Sync": "Sync"
},
"application": {
"Always": "Always",
@@ -38,7 +36,6 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "サインアップを有効にする",
"Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to connect to server": "Failed to connect to server",
"File uploaded successfully": "ファイルが正常にアップロードされました",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Edit",
@@ -128,7 +125,7 @@
"Please input your username!": "ユーザー名を入力してください!",
"Reset": "Reset",
"Retrieve password": "パスワードの取得",
"Unknown forget type": "Unknown forget type",
"Unknown forget type: ": "Unknown forget type: ",
"Verify": "確認する"
},
"general": {
@@ -167,6 +164,10 @@
"Edit": "編集",
"Email": "Eメールアドレス",
"Email - Tooltip": "email",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
"Failed to save": "Failed to save",
"Favicon": "Favicon",
"Favicon - Tooltip": "Application icon",
"First name": "First name",
@@ -237,6 +238,9 @@
"Sorry, you do not have permission to access this page.": "申し訳ありませんが、このページにアクセスする権限がありません。",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Successfully added": "Successfully added",
"Successfully deleted": "Successfully deleted",
"Successfully saved": "Successfully saved",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",

View File

@@ -6,15 +6,13 @@
"Sign Up": "Sign Up"
},
"adapter": {
"Add policy successfully": "Add policy successfully",
"Delete policy successfully": "Delete policy successfully",
"Edit Adapter": "Edit Adapter",
"Failed to sync policies: ": "Failed to sync policies: ",
"New Adapter": "New Adapter",
"Policies": "Policies",
"Policies - Tooltip": "Policies - Tooltip",
"Repeated policy": "Repeated policy",
"Sync": "Sync",
"Update policy successfully": "Update policy successfully"
"Repeated policy rules": "Repeated policy rules",
"Sync": "Sync"
},
"application": {
"Always": "Always",
@@ -38,7 +36,6 @@
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
"Enable signup": "Enable signup",
"Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to connect to server": "Failed to connect to server",
"File uploaded successfully": "File uploaded successfully",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Edit",
@@ -128,7 +125,7 @@
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Unknown forget type": "Unknown forget type",
"Unknown forget type: ": "Unknown forget type: ",
"Verify": "Verify"
},
"general": {
@@ -167,6 +164,10 @@
"Edit": "Edit",
"Email": "Email",
"Email - Tooltip": "email",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
"Failed to save": "Failed to save",
"Favicon": "Favicon",
"Favicon - Tooltip": "Application icon",
"First name": "First name",
@@ -237,6 +238,9 @@
"Sorry, you do not have permission to access this page.": "Sorry, you do not have permission to access this page.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Successfully added": "Successfully added",
"Successfully deleted": "Successfully deleted",
"Successfully saved": "Successfully saved",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",

View File

@@ -6,15 +6,13 @@
"Sign Up": "Регистрация"
},
"adapter": {
"Add policy successfully": "Add policy successfully",
"Delete policy successfully": "Delete policy successfully",
"Edit Adapter": "Edit Adapter",
"Failed to sync policies: ": "Failed to sync policies: ",
"New Adapter": "New Adapter",
"Policies": "Policies",
"Policies - Tooltip": "Policies - Tooltip",
"Repeated policy": "Repeated policy",
"Sync": "Sync",
"Update policy successfully": "Update policy successfully"
"Repeated policy rules": "Repeated policy rules",
"Sync": "Sync"
},
"application": {
"Always": "Always",
@@ -38,7 +36,6 @@
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
"Enable signup": "Включить регистрацию",
"Enable signup - Tooltip": "Whether to allow users to sign up",
"Failed to connect to server": "Failed to connect to server",
"File uploaded successfully": "Файл успешно загружен",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Edit",
@@ -128,7 +125,7 @@
"Please input your username!": "Пожалуйста, введите ваше имя пользователя!",
"Reset": "Сбросить",
"Retrieve password": "Получить пароль",
"Unknown forget type": "Неизвестный тип",
"Unknown forget type: ": "Unknown forget type: ",
"Verify": "Подтвердить"
},
"general": {
@@ -167,6 +164,10 @@
"Edit": "Редактирование",
"Email": "Почта",
"Email - Tooltip": "email",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
"Failed to save": "Failed to save",
"Favicon": "Иконка",
"Favicon - Tooltip": "Application icon",
"First name": "Имя",
@@ -237,6 +238,9 @@
"Sorry, you do not have permission to access this page.": "Извините, вы не имеете права доступа к этой странице.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Successfully added": "Successfully added",
"Successfully deleted": "Successfully deleted",
"Successfully saved": "Successfully saved",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Синхронизаторы",

View File

@@ -6,15 +6,13 @@
"Sign Up": "注册"
},
"adapter": {
"Add policy successfully": "添加策略成功",
"Delete policy successfully": "删除策略成功",
"Edit Adapter": "编辑适配器",
"Failed to sync policies: ": "同步策略失败: ",
"New Adapter": "添加适配器",
"Policies": "策略",
"Policies - Tooltip": "策略",
"Repeated policy": "策略重复",
"Sync": "同步",
"Update policy successfully": "更新策略成功"
"Repeated policy rules": "重复的策略",
"Sync": "同步"
},
"application": {
"Always": "始终开启",
@@ -38,7 +36,6 @@
"Enable signin session - Tooltip": "从应用登录Casdoor后Casdoor是否保持会话",
"Enable signup": "启用注册",
"Enable signup - Tooltip": "是否允许用户注册",
"Failed to connect to server": "无法连接服务器",
"File uploaded successfully": "文件上传成功",
"Form CSS": "表单CSS",
"Form CSS - Edit": "编辑表单CSS",
@@ -128,7 +125,7 @@
"Please input your username!": "请输入您的用户名!",
"Reset": "重置",
"Retrieve password": "找回密码",
"Unknown forget type": "未知的忘记密码类型",
"Unknown forget type: ": "未知的忘记密码类型: ",
"Verify": "验证"
},
"general": {
@@ -167,6 +164,10 @@
"Edit": "编辑",
"Email": "电子邮箱",
"Email - Tooltip": "电子邮件:",
"Failed to add": "添加失败",
"Failed to connect to server": "连接服务器失败",
"Failed to delete": "删除失败",
"Failed to save": "保存失败",
"Favicon": "网站图标",
"Favicon - Tooltip": "网站的Favicon图标",
"First name": "名字",
@@ -237,6 +238,9 @@
"Sorry, you do not have permission to access this page.": "抱歉,您无权访问该页面",
"State": "状态",
"State - Tooltip": "状态",
"Successfully added": "添加成功",
"Successfully deleted": "删除成功",
"Successfully saved": "保存成功",
"Swagger": "API文档",
"Sync": "同步",
"Syncers": "同步器",

View File

@@ -17,6 +17,19 @@
dependencies:
"@ctrl/tinycolor" "^3.4.0"
"@ant-design/cssinjs@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@ant-design/cssinjs/-/cssinjs-1.1.0.tgz#d7b5e0811e8241e66c2812c179bd7b7ef961f7ab"
integrity sha512-9kfWCnlcWZLMc184HL7zGUU3odKo/5HBMNxDxhSds2DoIzi/ojmmOU1A1butWVDSPcAbLyNQ85vxUI8mkkHrlA==
dependencies:
"@babel/runtime" "^7.11.1"
"@emotion/hash" "^0.8.0"
"@emotion/unitless" "^0.7.5"
classnames "^2.3.1"
csstype "^3.0.10"
rc-util "^5.24.2"
stylis "^4.0.13"
"@ant-design/icons-svg@^4.2.1":
version "4.2.1"
resolved "https://registry.yarnpkg.com/@ant-design/icons-svg/-/icons-svg-4.2.1.tgz#8630da8eb4471a4aabdaed7d1ff6a97dcb2cf05a"
@@ -1455,6 +1468,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.16.7":
version "7.20.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.6.tgz#facf4879bfed9b5326326273a64220f099b0fce3"
integrity sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.18.9":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
@@ -1677,6 +1697,16 @@
resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz#75b4c27948c81e88ccd3a8902047bcd797f38d32"
integrity sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==
"@emotion/hash@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
"@emotion/unitless@^0.7.5":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
"@eslint/eslintrc@^1.3.0", "@eslint/eslintrc@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d"
@@ -2066,6 +2096,26 @@
schema-utils "^3.0.0"
source-map "^0.7.3"
"@rc-component/portal@^1.0.0-6", "@rc-component/portal@^1.0.0-8", "@rc-component/portal@^1.0.0-9", "@rc-component/portal@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@rc-component/portal/-/portal-1.0.3.tgz#3aa2c229a7a20ac2412d864e8977e6377973416e"
integrity sha512-rG9j7OMiI9eLFLF6G0B4OcfLac9W8Z7Vjeizbjt/A6R+zzw7vhHbJ4GIkrDpUqXDvFdEEzdxfICpb8/noLwG+w==
dependencies:
"@babel/runtime" "^7.18.0"
classnames "^2.3.2"
rc-util "^5.24.4"
"@rc-component/tour@~1.0.1-2":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@rc-component/tour/-/tour-1.0.1.tgz#aa8ea890462eed43ee0fb33543995b342d87ee76"
integrity sha512-azbiWP0UwGDeWfGS7oCR0gHhbWJW7O6g4wFUaC19oY+eCjmY0RPY0u0p93BJ89D8NoxP9LhSSBuU/YQA5H5kbA==
dependencies:
"@babel/runtime" "^7.18.0"
"@rc-component/portal" "^1.0.0-9"
classnames "^2.3.2"
rc-trigger "^5.3.4"
rc-util "^5.24.4"
"@rollup/plugin-babel@^5.2.0":
version "5.3.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
@@ -3084,55 +3134,57 @@ ansi-styles@^6.0.0:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3"
integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==
antd@^4.22.8:
version "4.22.8"
resolved "https://registry.yarnpkg.com/antd/-/antd-4.22.8.tgz#e2f446932815a522a8aa3d285a8a9bdcb3d0fa9f"
integrity sha512-mqHuCg9itZX+z6wk+mvRBcfz/U9iiIXS4LoNkyo8X/UBgdN8CoetFmrdvA1UQy1BuWa0/n62LiS1LatdvoTuHw==
antd@5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/antd/-/antd-5.0.3.tgz#2cdaffe1afdb5c2f0f3325b2d06d508ec6ddf85a"
integrity sha512-Gqkba0earlR5H6gfT4nsyV3W9rL1Up1+clEXsa1+9Jem/geC2phBImpjWgVjqOjH3L5Oi8SHe0NeYBagDxwP5g==
dependencies:
"@ant-design/colors" "^6.0.0"
"@ant-design/cssinjs" "^1.0.0"
"@ant-design/icons" "^4.7.0"
"@ant-design/react-slick" "~0.29.1"
"@babel/runtime" "^7.18.3"
"@ctrl/tinycolor" "^3.4.0"
"@rc-component/tour" "~1.0.1-2"
classnames "^2.2.6"
copy-to-clipboard "^3.2.0"
dayjs "^1.11.1"
lodash "^4.17.21"
memoize-one "^6.0.0"
moment "^2.29.2"
rc-cascader "~3.6.0"
rc-cascader "~3.7.0"
rc-checkbox "~2.3.0"
rc-collapse "~3.3.0"
rc-dialog "~8.9.0"
rc-drawer "~5.1.0"
rc-collapse "~3.4.2"
rc-dialog "~9.0.2"
rc-drawer "~6.0.0"
rc-dropdown "~4.0.0"
rc-field-form "~1.27.0"
rc-image "~5.7.0"
rc-input "~0.0.1-alpha.5"
rc-input-number "~7.3.5"
rc-mentions "~1.9.1"
rc-menu "~9.6.3"
rc-image "~5.12.0"
rc-input "~0.1.4"
rc-input-number "~7.3.9"
rc-mentions "~1.13.1"
rc-menu "~9.8.0"
rc-motion "^2.6.1"
rc-notification "~4.6.0"
rc-pagination "~3.1.17"
rc-picker "~2.6.10"
rc-progress "~3.3.2"
rc-notification "~5.0.0-alpha.9"
rc-pagination "~3.2.0"
rc-picker "~3.1.1"
rc-progress "~3.4.1"
rc-rate "~2.9.0"
rc-resize-observer "^1.2.0"
rc-segmented "~2.1.0"
rc-select "~14.1.1"
rc-select "~14.1.13"
rc-slider "~10.0.0"
rc-steps "~4.1.0"
rc-switch "~3.2.0"
rc-table "~7.25.3"
rc-tabs "~11.16.0"
rc-textarea "~0.3.0"
rc-steps "~6.0.0-alpha.2"
rc-switch "~4.0.0"
rc-table "~7.26.0"
rc-tabs "~12.4.1"
rc-textarea "~0.4.5"
rc-tooltip "~5.2.0"
rc-tree "~5.6.5"
rc-tree-select "~5.4.0"
rc-tree "~5.7.0"
rc-tree-select "~5.5.4"
rc-trigger "^5.2.10"
rc-upload "~4.3.0"
rc-util "^5.22.5"
scroll-into-view-if-needed "^2.2.25"
shallowequal "^1.1.0"
anymatch@^3.0.3, anymatch@~3.1.2:
version "3.1.2"
@@ -3780,6 +3832,11 @@ classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classna
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
classnames@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
clean-css@^5.2.2:
version "5.3.1"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32"
@@ -4324,6 +4381,11 @@ cssstyle@^2.3.0:
dependencies:
cssom "~0.3.6"
csstype@^3.0.10:
version "3.1.1"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
csstype@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
@@ -4343,15 +4405,10 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"
date-fns@2.x:
version "2.28.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2"
integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==
dayjs@1.x:
version "1.11.3"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.3.tgz#4754eb694a624057b9ad2224b67b15d552589258"
integrity sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A==
dayjs@^1.11.1:
version "1.11.6"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.6.tgz#2e79a226314ec3ec904e3ee1dd5a4f5e5b1c7afb"
integrity sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==
debug@2.6.9, debug@^2.6.0, debug@^2.6.9:
version "2.6.9"
@@ -7310,11 +7367,6 @@ memoize-one@^4.0.0:
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-4.1.0.tgz#a2387c58c03fff27ca390c31b764a79addf3f906"
integrity sha512-2GApq0yI/b22J2j9rhbrAlsHb0Qcz+7yWxeLG8h+95sl1XPUgeLimQSOdur4Vw7cUhrBHwaUZxWFZueojqNRzA==
memoize-one@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
meow@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/meow/-/meow-9.0.0.tgz#cd9510bc5cac9dee7d03c73ee1f9ad959f4ea364"
@@ -7470,7 +7522,7 @@ mkdirp@^0.5.5, mkdirp@~0.5.1:
dependencies:
minimist "^1.2.6"
moment@^2.24.0, moment@^2.29.1, moment@^2.29.2:
moment@^2.29.1:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
@@ -8799,16 +8851,16 @@ rc-align@^4.0.0:
rc-util "^5.3.0"
resize-observer-polyfill "^1.5.1"
rc-cascader@~3.6.0:
version "3.6.1"
resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-3.6.1.tgz#2e94fb3ed770ffd71d87ebcf17a9b44a6442e76f"
integrity sha512-+GmN2Z0IybKT45t0Z94jkjmsOHGxAliobR2tzt05/Gw0AKBYLHX5bdvsVXR7abPnarYyYzZ/cWe8CoFgDjAFNw==
rc-cascader@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-3.7.0.tgz#98134df578ce1cca22be8fb4319b04df4f3dca36"
integrity sha512-SFtGpwmYN7RaWEAGTS4Rkc62ZV/qmQGg/tajr/7mfIkleuu8ro9Hlk6J+aA0x1YS4zlaZBtTcSaXM01QMiEV/A==
dependencies:
"@babel/runtime" "^7.12.5"
array-tree-filter "^2.1.0"
classnames "^2.3.1"
rc-select "~14.1.0"
rc-tree "~5.6.3"
rc-tree "~5.7.0"
rc-util "^5.6.1"
rc-checkbox@~2.3.0:
@@ -8819,10 +8871,10 @@ rc-checkbox@~2.3.0:
"@babel/runtime" "^7.10.1"
classnames "^2.2.1"
rc-collapse@~3.3.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/rc-collapse/-/rc-collapse-3.3.1.tgz#fc66d4c9cfeaf41e932b2de6da2d454874aee55a"
integrity sha512-cOJfcSe3R8vocrF8T+PgaHDrgeA1tX+lwfhwSj60NX9QVRidsILIbRNDLD6nAzmcvVC5PWiIRiR4S1OobxdhCg==
rc-collapse@~3.4.2:
version "3.4.2"
resolved "https://registry.yarnpkg.com/rc-collapse/-/rc-collapse-3.4.2.tgz#1310be7ad4cd0dcfc622c45f6c3b5ffdee403ad7"
integrity sha512-jpTwLgJzkhAgp2Wpi3xmbTbbYExg6fkptL67Uu5LCRVEj6wqmy0DHTjjeynsjOLsppHGHu41t1ELntZ0lEvS/Q==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
@@ -8830,22 +8882,24 @@ rc-collapse@~3.3.0:
rc-util "^5.2.1"
shallowequal "^1.1.0"
rc-dialog@~8.9.0:
version "8.9.0"
resolved "https://registry.yarnpkg.com/rc-dialog/-/rc-dialog-8.9.0.tgz#04dc39522f0321ed2e06018d4a7e02a4c32bd3ea"
integrity sha512-Cp0tbJnrvPchJfnwIvOMWmJ4yjX3HWFatO6oBFD1jx8QkgsQCR0p8nUWAKdd3seLJhEC39/v56kZaEjwp9muoQ==
rc-dialog@~9.0.0, rc-dialog@~9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/rc-dialog/-/rc-dialog-9.0.2.tgz#aadfebdeba145f256c1fac9b9f509f893cdbb5b8"
integrity sha512-s3U+24xWUuB6Bn2Lk/Qt6rufy+uT+QvWkiFhNBcO9APLxcFFczWamaq7x9h8SCuhfc1nHcW4y8NbMsnAjNnWyg==
dependencies:
"@babel/runtime" "^7.10.1"
"@rc-component/portal" "^1.0.0-8"
classnames "^2.2.6"
rc-motion "^2.3.0"
rc-util "^5.21.0"
rc-drawer@~5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/rc-drawer/-/rc-drawer-5.1.0.tgz#c1b8a46e5c064ba46a16233fbcfb1ccec6a73c10"
integrity sha512-pU3Tsn99pxGdYowXehzZbdDVE+4lDXSGb7p8vA9mSmr569oc2Izh4Zw5vLKSe/Xxn2p5MSNbLVqD4tz+pK6SOw==
rc-drawer@~6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/rc-drawer/-/rc-drawer-6.0.1.tgz#437040ac7ba305b5d964ba51e88f30797671e8f8"
integrity sha512-ibWXGf8I+KRPXE03X4s0/xXzQI37YWXUV+oPy+R29GKxkjr98UTMgwvoQDKlZTm5AiaRuVFqhTKm0kNHqJh+TQ==
dependencies:
"@babel/runtime" "^7.10.1"
"@rc-component/portal" "^1.0.0-6"
classnames "^2.2.6"
rc-motion "^2.6.1"
rc-util "^5.21.2"
@@ -8869,73 +8923,61 @@ rc-field-form@~1.27.0:
async-validator "^4.1.0"
rc-util "^5.8.0"
rc-image@~5.7.0:
version "5.7.0"
resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-5.7.0.tgz#e1a3b21099feb3fb9bf8ef3ce12c3fc11a8c1148"
integrity sha512-v6dzSgYfYrH4liKmOZKZZO+x21sJ9KPXNinBfkAoQg2Ihcd5QZ+P/JjB7v60X981XTPGjegy8U17Z8VUX4V36g==
rc-image@~5.12.0:
version "5.12.1"
resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-5.12.1.tgz#1560eda00ef9d33ebdb3c8c74ab134eb00f973d4"
integrity sha512-FMldR/ODwQmlFlhjR4c6hsOHmnn4s9CxmW7PR/9XCYE1XHlGJ5OkSWOtJruoaLjVwt2tQYDRnLANf/mKZ9ReUg==
dependencies:
"@babel/runtime" "^7.11.2"
"@rc-component/portal" "^1.0.2"
classnames "^2.2.6"
rc-dialog "~8.9.0"
rc-dialog "~9.0.0"
rc-util "^5.0.6"
rc-input-number@~7.3.5:
version "7.3.6"
resolved "https://registry.yarnpkg.com/rc-input-number/-/rc-input-number-7.3.6.tgz#54d66bd3fdaef0abfded4c734a12ac6d9461ebab"
integrity sha512-Se62oMOBn9HwF/gSag+YtAYyKZsjJzEsqmyAJHAnAvPfjZJOu7dLMlQRwBbTtELbKXM/Y5Fztcq8CW2Y9f49qA==
rc-input-number@~7.3.9:
version "7.3.11"
resolved "https://registry.yarnpkg.com/rc-input-number/-/rc-input-number-7.3.11.tgz#c7089705a220e1a59ba974fabf89693e00dd2442"
integrity sha512-aMWPEjFeles6PQnMqP5eWpxzsvHm9rh1jQOWXExUEIxhX62Fyl/ptifLHOn17+waDG1T/YUb6flfJbvwRhHrbA==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.5"
rc-util "^5.23.0"
rc-input@~0.0.1-alpha.5:
version "0.0.1-alpha.7"
resolved "https://registry.yarnpkg.com/rc-input/-/rc-input-0.0.1-alpha.7.tgz#53e3f13871275c21d92b51f80b698f389ad45dd3"
integrity sha512-eozaqpCYWSY5LBMwlHgC01GArkVEP+XlJ84OMvdkwUnJBSv83Yxa15pZpn7vACAj84uDC4xOA2CoFdbLuqB08Q==
rc-input@~0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/rc-input/-/rc-input-0.1.4.tgz#45cb4ba209ae6cc835a2acb8629d4f8f0cb347e0"
integrity sha512-FqDdNz+fV2dKNgfXzcSLKvC+jEs1709t7nD+WdfjrdSaOcefpgc7BUJYadc3usaING+b7ediMTfKxuJBsEFbXA==
dependencies:
"@babel/runtime" "^7.11.1"
classnames "^2.2.1"
rc-util "^5.18.1"
rc-mentions@~1.9.1:
version "1.9.2"
resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-1.9.2.tgz#f264ebc4ec734dad9edc8e078b65ab3586d94a7b"
integrity sha512-uxb/lzNnEGmvraKWNGE6KXMVXvt8RQv9XW8R0Dqi3hYsyPiAZeHRCHQKdLARuk5YBhFhZ6ga55D/8XuY367g3g==
rc-mentions@~1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-1.13.1.tgz#c884b70e1505a197f1b32a7c6b39090db6992a72"
integrity sha512-FCkaWw6JQygtOz0+Vxz/M/NWqrWHB9LwqlY2RtcuFqWJNFK9njijOOzTSsBGANliGufVUzx/xuPHmZPBV0+Hgw==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.6"
rc-menu "~9.6.0"
rc-textarea "^0.3.0"
rc-menu "~9.8.0"
rc-textarea "^0.4.0"
rc-trigger "^5.0.4"
rc-util "^5.22.5"
rc-menu@~9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.6.0.tgz#3263a729a81ae49cfdadee112e97d3c702922829"
integrity sha512-d26waws42U/rVwW/+rOE2FN9pX6wUc9bDy38vVQYoie6gE85auWIpl5oChGlnW6nE2epnTwUsgWl8ipOPgmnUA==
rc-menu@~9.8.0:
version "9.8.0"
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.8.0.tgz#d3d820f52ec37e27c5aec42b3cc68bbcfcaba1f7"
integrity sha512-ftO5ExUMMSprzinxtHQz11KIRWY6P/tOs5ZexboWJ835LVQAMXuqDFqkjB/BXVC8WAKjj9t3eZmmweZp+guoYw==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
rc-motion "^2.4.3"
rc-overflow "^1.2.0"
rc-overflow "^1.2.8"
rc-trigger "^5.1.2"
rc-util "^5.12.0"
shallowequal "^1.1.0"
rc-menu@~9.6.3:
version "9.6.3"
resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.6.3.tgz#f0373d0391a97db94147106cddffe87b1e4f4e36"
integrity sha512-KY9QilKWgkJZ0JSpOBgIpQF2wMRRodRxpIMYyIJ3Nd5N6xfVLOxXCxevHcBplt+Ez7MhUF+I03MuAKqWQJLZgw==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
rc-motion "^2.4.3"
rc-overflow "^1.2.0"
rc-trigger "^5.1.2"
rc-util "^5.12.0"
shallowequal "^1.1.0"
rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.2.0, rc-motion@^2.3.0, rc-motion@^2.3.4, rc-motion@^2.4.3, rc-motion@^2.4.4:
rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.3.0, rc-motion@^2.3.4, rc-motion@^2.4.3, rc-motion@^2.4.4:
version "2.6.0"
resolved "https://registry.yarnpkg.com/rc-motion/-/rc-motion-2.6.0.tgz#c60c3e7f15257f55a8cd7794a539f0e2cc751399"
integrity sha512-1MDWA9+i174CZ0SIDenSYm2Wb9YbRkrexjZWR0CUFu7D6f23E8Y0KsTgk9NGOLJsGak5ELZK/Y5lOlf5wQdzbw==
@@ -8944,7 +8986,7 @@ rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.2.0, rc-motion@^2.3.0, rc-motio
classnames "^2.2.1"
rc-util "^5.21.0"
rc-motion@^2.6.1:
rc-motion@^2.6.0, rc-motion@^2.6.1, rc-motion@^2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rc-motion/-/rc-motion-2.6.2.tgz#3d31f97e41fb8e4f91a4a4189b6a98ac63342869"
integrity sha512-4w1FaX3dtV749P8GwfS4fYnFG4Rb9pxvCYPc/b2fw1cmlHJWNNgOFIz7ysiD+eOrzJSvnLJWlNQQncpNMXwwpg==
@@ -8953,17 +8995,17 @@ rc-motion@^2.6.1:
classnames "^2.2.1"
rc-util "^5.21.0"
rc-notification@~4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/rc-notification/-/rc-notification-4.6.0.tgz#4e76fc2d0568f03cc93ac18c9e20763ebe29fa46"
integrity sha512-xF3MKgIoynzjQAO4lqsoraiFo3UXNYlBfpHs0VWvwF+4pimen9/H1DYLN2mfRWhHovW6gRpla73m2nmyIqAMZQ==
rc-notification@~5.0.0-alpha.9:
version "5.0.0-alpha.9"
resolved "https://registry.yarnpkg.com/rc-notification/-/rc-notification-5.0.0-alpha.9.tgz#e6fbf5cc786e508f022691a61a03c0473f5ca7b0"
integrity sha512-QPvq8VHe2M0SE5DHJf7ADWlvfWKnTsj5FVxcu39gdjX98kKmi+BHY1eTPAQkkdGqd6ZXv6xXHl8qKHyWhQcFPA==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
rc-motion "^2.2.0"
rc-motion "^2.6.0"
rc-util "^5.20.1"
rc-overflow@^1.0.0, rc-overflow@^1.2.0:
rc-overflow@^1.0.0:
version "1.2.6"
resolved "https://registry.yarnpkg.com/rc-overflow/-/rc-overflow-1.2.6.tgz#e99fabea04ce4fb13f0dd8835aef4e4cdd4c15a2"
integrity sha512-YqbocgzuQxfq2wZy72vdAgrgzzEuM/5d4gF9TBEodCpXPbUeXGrUXNm1J6G1MSkCU2N0ePIgCEu5qD/0Ldi63Q==
@@ -8973,32 +9015,39 @@ rc-overflow@^1.0.0, rc-overflow@^1.2.0:
rc-resize-observer "^1.0.0"
rc-util "^5.19.2"
rc-pagination@~3.1.17:
version "3.1.17"
resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.17.tgz#91e690aa894806e344cea88ea4a16d244194a1bd"
integrity sha512-/BQ5UxcBnW28vFAcP2hfh+Xg15W0QZn8TWYwdCApchMH1H0CxiaUUcULP8uXcFM1TygcdKWdt3JqsL9cTAfdkQ==
rc-overflow@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc-overflow/-/rc-overflow-1.2.8.tgz#40f140fabc244118543e627cdd1ef750d9481a88"
integrity sha512-QJ0UItckWPQ37ZL1dMEBAdY1dhfTXFL9k6oTTcyydVwoUNMnMqCGqnRNA98axSr/OeDKqR6DVFyi8eA5RQI/uQ==
dependencies:
"@babel/runtime" "^7.11.1"
classnames "^2.2.1"
rc-resize-observer "^1.0.0"
rc-util "^5.19.2"
rc-pagination@~3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.2.0.tgz#4f2fdba9fdac0f48e5c9fb1141973818138af7e1"
integrity sha512-5tIXjB670WwwcAJzAqp2J+cOBS9W3cH/WU1EiYwXljuZ4vtZXKlY2Idq8FZrnYBz8KhN3vwPo9CoV/SJS6SL1w==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.1"
rc-picker@~2.6.10:
version "2.6.10"
resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-2.6.10.tgz#8d0a473c079388bdb2d7358a2a54c7d5095893b4"
integrity sha512-9wYtw0DFWs9FO92Qh2D76P0iojUr8ZhLOtScUeOit6ks/F+TBLrOC1uze3IOu+u9gbDAjmosNWLKbBzx/Yuv2w==
rc-picker@~3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-3.1.2.tgz#fac85964007bdc906d33a8400f53798744ab440f"
integrity sha512-PHf4E91JANMBVjovqhRcZw0fDZYWlDW9APhMD8VxBSs2QeKbnf+vE5BdA3YmHq227woSptbkm9rfhR4dgSn4+g==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.1"
date-fns "2.x"
dayjs "1.x"
moment "^2.24.0"
rc-trigger "^5.0.4"
rc-util "^5.4.0"
shallowequal "^1.1.0"
rc-progress@~3.3.2:
version "3.3.3"
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-3.3.3.tgz#eb9bffbacab1534f2542f9f6861ce772254362b1"
integrity sha512-MDVNVHzGanYtRy2KKraEaWeZLri2ZHWIRyaE1a9MQ2MuJ09m+Wxj5cfcaoaR6z5iRpHpA59YeUxAlpML8N4PJw==
rc-progress@~3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-3.4.1.tgz#a9ffe099e88a4fc03afb09d8603162bf0760d743"
integrity sha512-eAFDHXlk8aWpoXl0llrenPMt9qKHQXphxcVsnKs0FHC6eCSk1ebJtyaVjJUzKe0233ogiLDeEFK1Uihz3s67hw==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.6"
@@ -9033,7 +9082,7 @@ rc-segmented@~2.1.0:
rc-motion "^2.4.4"
rc-util "^5.17.0"
rc-select@~14.1.0, rc-select@~14.1.1:
rc-select@~14.1.0:
version "14.1.8"
resolved "https://registry.yarnpkg.com/rc-select/-/rc-select-14.1.8.tgz#986dc9194212ea56c1acd8317a956c7c88e94f4a"
integrity sha512-1kU/7ZCggyR5r5jVEQfAiN6Sq3LGLD2b6FNz5GWel3TOEQZYyDn0o4FAoIRqS6Y5ldWmkFxtd834ilPnG6NV6w==
@@ -9046,6 +9095,19 @@ rc-select@~14.1.0, rc-select@~14.1.1:
rc-util "^5.16.1"
rc-virtual-list "^3.2.0"
rc-select@~14.1.13:
version "14.1.16"
resolved "https://registry.yarnpkg.com/rc-select/-/rc-select-14.1.16.tgz#0cc4b5a1fc551a2db7c96bc1ece0896317ecdd47"
integrity sha512-71XLHleuZmufpdV2vis5oituRkhg2WNvLpVMJBGWRar6WGAVOHXaY9DR5HvwWry3EGTn19BqnL6Xbybje6f8YA==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
rc-motion "^2.0.1"
rc-overflow "^1.0.0"
rc-trigger "^5.0.4"
rc-util "^5.16.1"
rc-virtual-list "^3.2.0"
rc-slider@~10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-10.0.0.tgz#8ffe1dd3c8799c9d1f81ac808976f18af3dca206"
@@ -9057,28 +9119,28 @@ rc-slider@~10.0.0:
rc-util "^5.18.1"
shallowequal "^1.1.0"
rc-steps@~4.1.0:
version "4.1.4"
resolved "https://registry.yarnpkg.com/rc-steps/-/rc-steps-4.1.4.tgz#0ba82db202d59ca52d0693dc9880dd145b19dc23"
integrity sha512-qoCqKZWSpkh/b03ASGx1WhpKnuZcRWmvuW+ZUu4mvMdfvFzVxblTwUM+9aBd0mlEUFmt6GW8FXhMpHkK3Uzp3w==
rc-steps@~6.0.0-alpha.2:
version "6.0.0-alpha.2"
resolved "https://registry.yarnpkg.com/rc-steps/-/rc-steps-6.0.0-alpha.2.tgz#505e64177111becd911cef4d24f15477438c9e59"
integrity sha512-d/GPx7ATlPbtFeOVt5FB19W11OBCmRd7lLknt4aSoCI6ukwJqpEhWu2INN4pDOQqN04y3PDsWl1q9hnw+ZC5AA==
dependencies:
"@babel/runtime" "^7.10.2"
"@babel/runtime" "^7.16.7"
classnames "^2.2.3"
rc-util "^5.0.1"
rc-util "^5.16.1"
rc-switch@~3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/rc-switch/-/rc-switch-3.2.2.tgz#d001f77f12664d52595b4f6fb425dd9e66fba8e8"
integrity sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==
rc-switch@~4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/rc-switch/-/rc-switch-4.0.0.tgz#55fbf99fc2d680791175037d379e170ba51fbe78"
integrity sha512-IfrYC99vN0gKaTyjQdqYuADU0eH00SAFHg3jOp8HrmUpJruhV1SohJzrCbPqPraZeX/6X/QKkdLfkdnUub05WA==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.1"
rc-util "^5.0.1"
rc-table@~7.25.3:
version "7.25.3"
resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.25.3.tgz#a2941d4fde4c181e687e97a294faca8e4122e26d"
integrity sha512-McsLJ2rg8EEpRBRYN4Pf9gT7ZNYnjvF9zrBpUBBbUX/fxk+eGi5ff1iPIhMyiHsH71/BmTUzX9nc9XqupD0nMg==
rc-table@~7.26.0:
version "7.26.0"
resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.26.0.tgz#9d517e7fa512e7571fdcc453eb1bf19edfac6fbc"
integrity sha512-0cD8e6S+DTGAt5nBZQIPFYEaIukn17sfa5uFL98faHlH/whZzD8ii3dbFL4wmUDEL4BLybhYop+QUfZJ4CPvNQ==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.5"
@@ -9086,27 +9148,28 @@ rc-table@~7.25.3:
rc-util "^5.22.5"
shallowequal "^1.1.0"
rc-tabs@~11.16.0:
version "11.16.0"
resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-11.16.0.tgz#12447069ea1dc480c729e1e40661cfbd46ac4efe"
integrity sha512-CIDPv3lHaXSHTJevmFP2eHoD3Hq9psfKbOZYf6D4FYPACloNGHpz44y3RGeJgataQ7omFLrGBm3dOBMUki87tA==
rc-tabs@~12.4.1:
version "12.4.1"
resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-12.4.1.tgz#a45aa7560ae4e2a91426e74a2e76566f5c8ec9cc"
integrity sha512-yViBZypldDnPffk3IPTarplF1RAv8VQDDnOt9sHDU7pjCnqE72csCU+7kjbLPtPpYniIMQJYyWxh/lsBUcagSA==
dependencies:
"@babel/runtime" "^7.11.2"
classnames "2.x"
rc-dropdown "~4.0.0"
rc-menu "~9.6.0"
rc-menu "~9.8.0"
rc-motion "^2.6.2"
rc-resize-observer "^1.0.0"
rc-util "^5.5.0"
rc-util "^5.16.0"
rc-textarea@^0.3.0, rc-textarea@~0.3.0:
version "0.3.7"
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-0.3.7.tgz#987142891efdedb774883c07e2f51b318fde5a11"
integrity sha512-yCdZ6binKmAQB13hc/oehh0E/QRwoPP1pjF21aHBxlgXO3RzPF6dUu4LG2R4FZ1zx/fQd2L1faktulrXOM/2rw==
rc-textarea@^0.4.0, rc-textarea@~0.4.5:
version "0.4.7"
resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-0.4.7.tgz#627f662d46f99e0059d1c1ebc8db40c65339fe90"
integrity sha512-IQPd1CDI3mnMlkFyzt2O4gQ2lxUsnBAeJEoZGJnkkXgORNqyM9qovdrCj9NzcRfpHgLdzaEbU3AmobNFGUznwQ==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "^2.2.1"
rc-resize-observer "^1.0.0"
rc-util "^5.7.0"
rc-util "^5.24.4"
shallowequal "^1.1.0"
rc-tooltip@^5.0.1:
@@ -9126,21 +9189,21 @@ rc-tooltip@~5.2.0:
classnames "^2.3.1"
rc-trigger "^5.0.0"
rc-tree-select@~5.4.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/rc-tree-select/-/rc-tree-select-5.4.0.tgz#c94b961aca68689f5ee3a43e33881cf693d195ef"
integrity sha512-reRbOqC7Ic/nQocJAJeCl4n6nJUY3NoqiwRXKvhjgZJU7NGr9vIccXEsY+Lghkw5UMpPoxGsIJB0jiAvM18XYA==
rc-tree-select@~5.5.4:
version "5.5.5"
resolved "https://registry.yarnpkg.com/rc-tree-select/-/rc-tree-select-5.5.5.tgz#d28b3b45da1e820cd21762ba0ee93c19429bb369"
integrity sha512-k2av7jF6tW9bIO4mQhaVdV4kJ1c54oxV3/hHVU+oD251Gb5JN+m1RbJFTMf1o0rAFqkvto33rxMdpafaGKQRJw==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
rc-select "~14.1.0"
rc-tree "~5.6.1"
rc-tree "~5.7.0"
rc-util "^5.16.1"
rc-tree@~5.6.1, rc-tree@~5.6.3, rc-tree@~5.6.5:
version "5.6.5"
resolved "https://registry.yarnpkg.com/rc-tree/-/rc-tree-5.6.5.tgz#1947337fc48f3fe20fabaafb1aed3e4ff1ce71b4"
integrity sha512-Bnyen46B251APyRZ9D/jYeTnSqbSEvK2AkU5B4vWkNYgUJNPrxO+VMgcDRedP/8N7YcsgdDT9hxqVvNOq7oCAQ==
rc-tree@~5.7.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/rc-tree/-/rc-tree-5.7.1.tgz#c642b80ad35fef3bf5c63c35382209c84600187e"
integrity sha512-fP04wmM5oyi9jT3DvmweLENswMHuNV5bDqT/1lWcmzAUqJ5/O/Bj7y8dMR5JlnnTojsRoJP6HlS+Az4Bc1h9jA==
dependencies:
"@babel/runtime" "^7.10.1"
classnames "2.x"
@@ -9159,6 +9222,17 @@ rc-trigger@^5.0.0, rc-trigger@^5.0.4, rc-trigger@^5.1.2, rc-trigger@^5.2.10, rc-
rc-motion "^2.0.0"
rc-util "^5.19.2"
rc-trigger@^5.3.4:
version "5.3.4"
resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.3.4.tgz#6b4b26e32825677c837d1eb4d7085035eecf9a61"
integrity sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==
dependencies:
"@babel/runtime" "^7.18.3"
classnames "^2.2.6"
rc-align "^4.0.0"
rc-motion "^2.0.0"
rc-util "^5.19.2"
rc-upload@~4.3.0:
version "4.3.4"
resolved "https://registry.yarnpkg.com/rc-upload/-/rc-upload-4.3.4.tgz#83ff7d3867631c37adbfd72ea3d1fd7e97ca84af"
@@ -9168,7 +9242,7 @@ rc-upload@~4.3.0:
classnames "^2.2.5"
rc-util "^5.2.0"
rc-util@^5.0.1, rc-util@^5.0.6, rc-util@^5.12.0, rc-util@^5.15.0, rc-util@^5.16.1, rc-util@^5.17.0, rc-util@^5.18.1, rc-util@^5.19.2, rc-util@^5.2.0, rc-util@^5.2.1, rc-util@^5.20.1, rc-util@^5.21.0, rc-util@^5.22.5, rc-util@^5.3.0, rc-util@^5.4.0, rc-util@^5.5.0, rc-util@^5.6.1, rc-util@^5.7.0, rc-util@^5.8.0, rc-util@^5.9.4:
rc-util@^5.0.1, rc-util@^5.0.6, rc-util@^5.12.0, rc-util@^5.15.0, rc-util@^5.16.1, rc-util@^5.17.0, rc-util@^5.18.1, rc-util@^5.19.2, rc-util@^5.2.0, rc-util@^5.2.1, rc-util@^5.20.1, rc-util@^5.21.0, rc-util@^5.22.5, rc-util@^5.3.0, rc-util@^5.4.0, rc-util@^5.6.1, rc-util@^5.8.0, rc-util@^5.9.4:
version "5.22.5"
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.22.5.tgz#d4d6d886c5ecb6a2a51dde1840d780a2b70f5179"
integrity sha512-awD2TGMGU97OZftT2R3JwrHWjR8k/xIwqjwcivPskciweUdgXE7QsyXkBKVSBHXS+c17AWWMDWuKWsJSheQy8g==
@@ -9177,6 +9251,15 @@ rc-util@^5.0.1, rc-util@^5.0.6, rc-util@^5.12.0, rc-util@^5.15.0, rc-util@^5.16.
react-is "^16.12.0"
shallowequal "^1.1.0"
rc-util@^5.16.0, rc-util@^5.24.2, rc-util@^5.24.4:
version "5.24.8"
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.24.8.tgz#4d234a5263f42080fb39b9c1b36f9df73af3497b"
integrity sha512-AS222gRVeH5RDdaRUd9ur9/E9MMQn5sZA3d4Z1vGU7JXW9dxD9kPijax00RG+dU2EJTfwySstFLDoSqpAPMNKw==
dependencies:
"@babel/runtime" "^7.18.3"
react-is "^16.12.0"
shallowequal "^1.1.0"
rc-util@^5.21.2, rc-util@^5.23.0:
version "5.23.0"
resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.23.0.tgz#a583b1ec3e1832a80eced7a700a494af0b590743"
@@ -9516,6 +9599,11 @@ regenerate@^1.4.2:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9:
version "0.13.9"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
@@ -10422,6 +10510,11 @@ stylelint@^14.0, stylelint@^14.11.0:
v8-compile-cache "^2.3.0"
write-file-atomic "^4.0.2"
stylis@^4.0.13:
version "4.1.3"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7"
integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"