mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-17 22:23:50 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
8ff0cfd6ec | |||
7a2a40edcc | |||
b7a001ea39 | |||
891e8e21d8 | |||
80b0d26813 | |||
db4ac60bb6 | |||
33a922f026 | |||
9f65053d04 | |||
be969e5efa | |||
9156bd426b | |||
fe4a4328aa | |||
9899022bcd |
@ -27,13 +27,7 @@ import (
|
||||
var Enforcer *casbin.Enforcer
|
||||
|
||||
func InitApi() {
|
||||
var err error
|
||||
|
||||
e, err := object.GetEnforcer(util.GetId("built-in", "api-enforcer-built-in"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = e.InitEnforcer()
|
||||
e, err := object.GetInitializedEnforcer(util.GetId("built-in", "api-enforcer-built-in"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -45,13 +45,7 @@ func (c *ApiController) Enforce() {
|
||||
}
|
||||
|
||||
if enforcerId != "" {
|
||||
enforcer, err := object.GetEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err = enforcer.InitEnforcer()
|
||||
enforcer, err := object.GetInitializedEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
@ -155,13 +149,7 @@ func (c *ApiController) BatchEnforce() {
|
||||
}
|
||||
|
||||
if enforcerId != "" {
|
||||
enforcer, err := object.GetEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err = enforcer.InitEnforcer()
|
||||
enforcer, err := object.GetInitializedEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
33
controllers/get-dashboard.go
Normal file
33
controllers/get-dashboard.go
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllers
|
||||
|
||||
import "github.com/casdoor/casdoor/object"
|
||||
|
||||
// GetDashboard
|
||||
// @Title GetDashboard
|
||||
// @Tag GetDashboard API
|
||||
// @Description get information of dashboard
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /get-dashboard [get]
|
||||
func (c *ApiController) GetDashboard() {
|
||||
data, err := object.GetDashboard()
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(data)
|
||||
}
|
@ -361,6 +361,9 @@ func (c *ApiController) UploadResource() {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Properties == nil {
|
||||
user.Properties = map[string]string{}
|
||||
}
|
||||
user.Properties[tag] = fileUrl
|
||||
user.Properties["isIdCardVerified"] = "false"
|
||||
_, err = object.UpdateUser(user.GetId(), user, []string{"properties"}, false)
|
||||
|
@ -140,10 +140,12 @@ func (c *ApiController) SendSms() {
|
||||
return
|
||||
}
|
||||
|
||||
invalidReceivers := getInvalidSmsReceivers(smsForm)
|
||||
if len(invalidReceivers) != 0 {
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), strings.Join(invalidReceivers, ", ")))
|
||||
return
|
||||
if provider.Type != "Custom HTTP SMS" {
|
||||
invalidReceivers := getInvalidSmsReceivers(smsForm)
|
||||
if len(invalidReceivers) != 0 {
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), strings.Join(invalidReceivers, ", ")))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = object.SendSms(provider, smsForm.Content, smsForm.Receivers...)
|
||||
|
@ -24,20 +24,10 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
const Web3AuthTokenKey = "web3AuthToken"
|
||||
|
||||
type MetaMaskIdProvider struct {
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
type Web3AuthToken struct {
|
||||
Address string `json:"address"`
|
||||
Nonce string `json:"nonce"`
|
||||
CreateAt uint64 `json:"createAt"`
|
||||
TypedData string `json:"typedData"`
|
||||
Signature string `json:"signature"` // signature for typed data
|
||||
}
|
||||
|
||||
func NewMetaMaskIdProvider() *MetaMaskIdProvider {
|
||||
idp := &MetaMaskIdProvider{}
|
||||
return idp
|
||||
|
@ -111,6 +111,8 @@ func GetIdProvider(idpInfo *ProviderInfo, redirectUrl string) IdProvider {
|
||||
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
||||
case "MetaMask":
|
||||
return NewMetaMaskIdProvider()
|
||||
case "Web3Onboard":
|
||||
return NewWeb3OnboardIdProvider()
|
||||
default:
|
||||
if isGothSupport(idpInfo.Type) {
|
||||
return NewGothIdProvider(idpInfo.Type, idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
||||
|
103
idp/web3onboard.go
Normal file
103
idp/web3onboard.go
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package idp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
const Web3AuthTokenKey = "web3AuthToken"
|
||||
|
||||
type Web3AuthToken struct {
|
||||
Address string `json:"address"`
|
||||
Nonce string `json:"nonce"`
|
||||
CreateAt uint64 `json:"createAt"`
|
||||
TypedData string `json:"typedData"` // typed data use for application
|
||||
Signature string `json:"signature"` // signature for typed data
|
||||
WalletType string `json:"walletType"` // e.g."MetaMask", "Coinbase"
|
||||
}
|
||||
|
||||
type Web3OnboardIdProvider struct {
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
func NewWeb3OnboardIdProvider() *Web3OnboardIdProvider {
|
||||
idp := &Web3OnboardIdProvider{}
|
||||
return idp
|
||||
}
|
||||
|
||||
func (idp *Web3OnboardIdProvider) SetHttpClient(client *http.Client) {
|
||||
idp.Client = client
|
||||
}
|
||||
|
||||
func (idp *Web3OnboardIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
web3AuthToken := Web3AuthToken{}
|
||||
if err := json.Unmarshal([]byte(code), &web3AuthToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token := &oauth2.Token{
|
||||
AccessToken: fmt.Sprintf("%v:%v", Web3AuthTokenKey, web3AuthToken.Address),
|
||||
TokenType: "Bearer",
|
||||
Expiry: time.Now().AddDate(0, 1, 0),
|
||||
}
|
||||
|
||||
token = token.WithExtra(map[string]interface{}{
|
||||
Web3AuthTokenKey: web3AuthToken,
|
||||
})
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (idp *Web3OnboardIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
web3AuthToken, ok := token.Extra(Web3AuthTokenKey).(Web3AuthToken)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid web3AuthToken")
|
||||
}
|
||||
|
||||
fmtAddress := fmt.Sprintf("%v_%v",
|
||||
strings.ReplaceAll(strings.TrimSpace(web3AuthToken.WalletType), " ", "_"),
|
||||
web3AuthToken.Address,
|
||||
)
|
||||
userInfo := &UserInfo{
|
||||
Id: fmtAddress,
|
||||
Username: fmtAddress,
|
||||
DisplayName: fmtAddress,
|
||||
AvatarUrl: fmt.Sprintf("metamask:%v", forceEthereumAddress(web3AuthToken.Address)),
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
func forceEthereumAddress(address string) string {
|
||||
// The required address to general MetaMask avatar is a string of length 42 that represents an Ethereum address.
|
||||
// This function is used to force any address as an Ethereum address
|
||||
address = strings.TrimSpace(address)
|
||||
var builder strings.Builder
|
||||
for _, ch := range address {
|
||||
builder.WriteRune(ch)
|
||||
}
|
||||
for len(builder.String()) < 42 {
|
||||
builder.WriteString("0")
|
||||
}
|
||||
if len(builder.String()) > 42 {
|
||||
return builder.String()[:42]
|
||||
}
|
||||
return builder.String()
|
||||
}
|
@ -167,3 +167,18 @@ func (enforcer *Enforcer) InitEnforcer() error {
|
||||
enforcer.Enforcer = casbinEnforcer
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetInitializedEnforcer(enforcerId string) (*Enforcer, error) {
|
||||
enforcer, err := GetEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if enforcer == nil {
|
||||
return nil, fmt.Errorf("the enforcer: %s is not found", enforcerId)
|
||||
}
|
||||
|
||||
err = enforcer.InitEnforcer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return enforcer, nil
|
||||
}
|
||||
|
111
object/get-dashboard.go
Normal file
111
object/get-dashboard.go
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import "time"
|
||||
|
||||
type Dashboard struct {
|
||||
OrganizationCounts []int `json:"organizationCounts"`
|
||||
UserCounts []int `json:"userCounts"`
|
||||
ProviderCounts []int `json:"providerCounts"`
|
||||
ApplicationCounts []int `json:"applicationCounts"`
|
||||
SubscriptionCounts []int `json:"subscriptionCounts"`
|
||||
}
|
||||
|
||||
func GetDashboard() (*Dashboard, error) {
|
||||
dashboard := &Dashboard{
|
||||
OrganizationCounts: make([]int, 31),
|
||||
UserCounts: make([]int, 31),
|
||||
ProviderCounts: make([]int, 31),
|
||||
ApplicationCounts: make([]int, 31),
|
||||
SubscriptionCounts: make([]int, 31),
|
||||
}
|
||||
|
||||
nowTime := time.Now()
|
||||
|
||||
organizations := make([]Organization, 0)
|
||||
if err := ormer.Engine.Find(&organizations); err != nil {
|
||||
return dashboard, err
|
||||
}
|
||||
users := make([]User, 0)
|
||||
if err := ormer.Engine.Find(&users); err != nil {
|
||||
return dashboard, err
|
||||
}
|
||||
providers := make([]Provider, 0)
|
||||
if err := ormer.Engine.Find(&providers); err != nil {
|
||||
return dashboard, err
|
||||
}
|
||||
applications := make([]Application, 0)
|
||||
if err := ormer.Engine.Find(&applications); err != nil {
|
||||
return dashboard, err
|
||||
}
|
||||
subscriptions := make([]Subscription, 0)
|
||||
if err := ormer.Engine.Find(&subscriptions); err != nil {
|
||||
return dashboard, err
|
||||
}
|
||||
|
||||
for i := 30; i >= 0; i-- {
|
||||
cutTime := nowTime.AddDate(0, 0, -i)
|
||||
dashboard.OrganizationCounts[30-i] = countCreatedBefore(organizations, cutTime)
|
||||
dashboard.UserCounts[30-i] = countCreatedBefore(users, cutTime)
|
||||
dashboard.ProviderCounts[30-i] = countCreatedBefore(providers, cutTime)
|
||||
dashboard.ApplicationCounts[30-i] = countCreatedBefore(applications, cutTime)
|
||||
dashboard.SubscriptionCounts[30-i] = countCreatedBefore(subscriptions, cutTime)
|
||||
}
|
||||
|
||||
return dashboard, nil
|
||||
}
|
||||
|
||||
func countCreatedBefore(objects interface{}, before time.Time) int {
|
||||
count := 0
|
||||
switch obj := objects.(type) {
|
||||
case []Organization:
|
||||
for _, o := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", o.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []User:
|
||||
for _, u := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", u.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Provider:
|
||||
for _, p := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", p.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Application:
|
||||
for _, a := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", a.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Subscription:
|
||||
for _, s := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", s.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
@ -484,7 +484,7 @@ func initBuiltInUserEnforcer() {
|
||||
Owner: "built-in",
|
||||
Name: "user-enforcer-built-in",
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: "Permission Enforcer",
|
||||
DisplayName: "User Enforcer",
|
||||
Model: "built-in/user-model-built-in",
|
||||
Adapter: "built-in/user-adapter-built-in",
|
||||
IsEnabled: true,
|
||||
|
@ -47,13 +47,12 @@ type LdapUser struct {
|
||||
Email string `json:"email"`
|
||||
EmailAddress string
|
||||
TelephoneNumber string
|
||||
Mobile string
|
||||
Mobile string `json:"mobile"`
|
||||
MobileTelephoneNumber string
|
||||
RegisteredAddress string
|
||||
PostalAddress string
|
||||
|
||||
GroupId string `json:"groupId"`
|
||||
Phone string `json:"phone"`
|
||||
Address string `json:"address"`
|
||||
MemberOf string `json:"memberOf"`
|
||||
}
|
||||
@ -318,7 +317,7 @@ func SyncLdapUsers(owner string, syncUsers []LdapUser, ldapId string) (existUser
|
||||
DisplayName: syncUser.buildLdapDisplayName(),
|
||||
Avatar: organization.DefaultAvatar,
|
||||
Email: syncUser.Email,
|
||||
Phone: syncUser.Phone,
|
||||
Phone: syncUser.Mobile,
|
||||
Address: []string{syncUser.Address},
|
||||
Affiliation: affiliation,
|
||||
Tag: tag,
|
||||
|
@ -309,8 +309,7 @@ func GetAllRoles(userId string) []string {
|
||||
|
||||
func GetBuiltInModel(modelText string) (model.Model, error) {
|
||||
if modelText == "" {
|
||||
modelText = `
|
||||
[request_definition]
|
||||
modelText = `[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
[policy_definition]
|
||||
|
@ -26,6 +26,8 @@ func getSmsClient(provider *Provider) (sender.SmsClient, error) {
|
||||
|
||||
if provider.Type == sender.HuaweiCloud || provider.Type == sender.AzureACS {
|
||||
client, err = sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.ProviderUrl, provider.AppId)
|
||||
} else if provider.Type == "Custom HTTP SMS" {
|
||||
client, err = newHttpSmsClient(provider.Endpoint, provider.Method, provider.ClientId, provider.Title)
|
||||
} else {
|
||||
client, err = sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.AppId)
|
||||
}
|
||||
|
75
object/sms_custom.go
Normal file
75
object/sms_custom.go
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/casdoor/casdoor/proxy"
|
||||
)
|
||||
|
||||
type HttpSmsClient struct {
|
||||
endpoint string
|
||||
method string
|
||||
paramName string
|
||||
text string
|
||||
}
|
||||
|
||||
func newHttpSmsClient(endpoint string, method string, paramName string, text string) (*HttpSmsClient, error) {
|
||||
client := &HttpSmsClient{
|
||||
endpoint: endpoint,
|
||||
method: method,
|
||||
paramName: paramName,
|
||||
text: text,
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *HttpSmsClient) SendMessage(param map[string]string, targetPhoneNumber ...string) error {
|
||||
var err error
|
||||
|
||||
content := param["code"]
|
||||
httpClient := proxy.DefaultHttpClient
|
||||
|
||||
req, err := http.NewRequest(c.method, c.endpoint, bytes.NewBufferString(content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.method == "POST" {
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.PostForm = map[string][]string{
|
||||
c.paramName: {content},
|
||||
}
|
||||
} else if c.method == "GET" {
|
||||
q := req.URL.Query()
|
||||
q.Add(c.paramName, content)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("SendMessage() error, custom HTTP SMS request failed with status: %s", resp.Status)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
@ -45,7 +45,6 @@ type Syncer struct {
|
||||
DatabaseType string `xorm:"varchar(100)" json:"databaseType"`
|
||||
Database string `xorm:"varchar(100)" json:"database"`
|
||||
Table string `xorm:"varchar(100)" json:"table"`
|
||||
TablePrimaryKey string `xorm:"varchar(100)" json:"tablePrimaryKey"`
|
||||
TableColumns []*TableColumn `xorm:"mediumtext" json:"tableColumns"`
|
||||
AffiliationTable string `xorm:"varchar(100)" json:"affiliationTable"`
|
||||
AvatarBaseUrl string `xorm:"varchar(100)" json:"avatarBaseUrl"`
|
||||
@ -230,6 +229,27 @@ func (syncer *Syncer) getTable() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (syncer *Syncer) getKey() string {
|
||||
key := "id"
|
||||
hasKey := false
|
||||
hasId := false
|
||||
for _, tableColumn := range syncer.TableColumns {
|
||||
if tableColumn.IsKey {
|
||||
hasKey = true
|
||||
key = tableColumn.Name
|
||||
}
|
||||
if tableColumn.Name == "id" {
|
||||
hasId = true
|
||||
}
|
||||
}
|
||||
|
||||
if !hasKey && !hasId {
|
||||
key = syncer.TableColumns[0].Name
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
func RunSyncer(syncer *Syncer) {
|
||||
syncer.initAdapter()
|
||||
syncer.syncUsers()
|
||||
|
@ -20,16 +20,24 @@ import (
|
||||
)
|
||||
|
||||
func (syncer *Syncer) syncUsers() {
|
||||
if len(syncer.TableColumns) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Running syncUsers()..\n")
|
||||
|
||||
users, userMap, userNameMap := syncer.getUserMap()
|
||||
users, _, _ := syncer.getUserMap()
|
||||
oUsers, oUserMap, err := syncer.getOriginalUserMap()
|
||||
if err != nil {
|
||||
fmt.Printf(err.Error())
|
||||
|
||||
timestamp := time.Now().Format("2006-01-02 15:04:05")
|
||||
line := fmt.Sprintf("[%s] %s\n", timestamp, err.Error())
|
||||
updateSyncerErrorText(syncer, line)
|
||||
_, err = updateSyncerErrorText(syncer, line)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -40,48 +48,68 @@ func (syncer *Syncer) syncUsers() {
|
||||
_, affiliationMap, err = syncer.getAffiliationMap()
|
||||
}
|
||||
|
||||
key := syncer.getKey()
|
||||
|
||||
myUsers := map[string]*User{}
|
||||
for _, m := range users {
|
||||
myUsers[syncer.getUserValue(m, key)] = m
|
||||
}
|
||||
|
||||
newUsers := []*User{}
|
||||
for _, oUser := range oUsers {
|
||||
id := oUser.Id
|
||||
if _, ok := userMap[id]; !ok {
|
||||
if _, ok := userNameMap[oUser.Name]; !ok {
|
||||
newUser := syncer.createUserFromOriginalUser(oUser, affiliationMap)
|
||||
fmt.Printf("New user: %v\n", newUser)
|
||||
newUsers = append(newUsers, newUser)
|
||||
}
|
||||
} else {
|
||||
user := userMap[id]
|
||||
oHash := syncer.calculateHash(oUser)
|
||||
primary := syncer.getUserValue(oUser, key)
|
||||
|
||||
if _, ok := myUsers[primary]; !ok {
|
||||
newUser := syncer.createUserFromOriginalUser(oUser, affiliationMap)
|
||||
fmt.Printf("New user: %v\n", newUser)
|
||||
newUsers = append(newUsers, newUser)
|
||||
} else {
|
||||
user := myUsers[primary]
|
||||
oHash := syncer.calculateHash(oUser)
|
||||
if user.Hash == user.PreHash {
|
||||
if user.Hash != oHash {
|
||||
updatedUser := syncer.createUserFromOriginalUser(oUser, affiliationMap)
|
||||
updatedUser.Hash = oHash
|
||||
updatedUser.PreHash = oHash
|
||||
syncer.updateUserForOriginalFields(updatedUser)
|
||||
_, err = syncer.updateUserForOriginalByFields(updatedUser, key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Update from oUser to user: %v\n", updatedUser)
|
||||
}
|
||||
} else {
|
||||
if user.PreHash == oHash {
|
||||
if !syncer.IsReadOnly {
|
||||
updatedOUser := syncer.createOriginalUserFromUser(user)
|
||||
syncer.updateUser(updatedOUser)
|
||||
_, err = syncer.updateUser(updatedOUser)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Update from user to oUser: %v\n", updatedOUser)
|
||||
}
|
||||
|
||||
// update preHash
|
||||
user.PreHash = user.Hash
|
||||
SetUserField(user, "pre_hash", user.PreHash)
|
||||
_, err = SetUserField(user, "pre_hash", user.PreHash)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
if user.Hash == oHash {
|
||||
// update preHash
|
||||
user.PreHash = user.Hash
|
||||
SetUserField(user, "pre_hash", user.PreHash)
|
||||
_, err = SetUserField(user, "pre_hash", user.PreHash)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
updatedUser := syncer.createUserFromOriginalUser(oUser, affiliationMap)
|
||||
updatedUser.Hash = oHash
|
||||
updatedUser.PreHash = oHash
|
||||
syncer.updateUserForOriginalFields(updatedUser)
|
||||
_, err = syncer.updateUserForOriginalByFields(updatedUser, key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Update from oUser to user (2nd condition): %v\n", updatedUser)
|
||||
}
|
||||
}
|
||||
|
@ -80,16 +80,6 @@ func (syncer *Syncer) addUser(user *OriginalUser) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
/*func (syncer *Syncer) getOriginalColumns() []string {
|
||||
res := []string{}
|
||||
for _, tableColumn := range syncer.TableColumns {
|
||||
if tableColumn.CasdoorName != "Id" {
|
||||
res = append(res, tableColumn.Name)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}*/
|
||||
|
||||
func (syncer *Syncer) getCasdoorColumns() []string {
|
||||
res := []string{}
|
||||
for _, tableColumn := range syncer.TableColumns {
|
||||
@ -102,12 +92,14 @@ func (syncer *Syncer) getCasdoorColumns() []string {
|
||||
}
|
||||
|
||||
func (syncer *Syncer) updateUser(user *OriginalUser) (bool, error) {
|
||||
key := syncer.getKey()
|
||||
|
||||
m := syncer.getMapFromOriginalUser(user)
|
||||
pkValue := m[syncer.TablePrimaryKey]
|
||||
delete(m, syncer.TablePrimaryKey)
|
||||
pkValue := m[key]
|
||||
delete(m, key)
|
||||
setString := syncer.getSqlSetStringFromMap(m)
|
||||
|
||||
sql := fmt.Sprintf("update %s set %s where %s = %s", syncer.getTable(), setString, syncer.TablePrimaryKey, pkValue)
|
||||
sql := fmt.Sprintf("update %s set %s where %s = %s", syncer.getTable(), setString, key, pkValue)
|
||||
res, err := syncer.Ormer.Engine.Exec(sql)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@ -142,6 +134,34 @@ func (syncer *Syncer) updateUserForOriginalFields(user *User) (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func (syncer *Syncer) updateUserForOriginalByFields(user *User, key string) (bool, error) {
|
||||
var err error
|
||||
oldUser := User{}
|
||||
|
||||
existed, err := ormer.Engine.Where(key+" = ? and owner = ?", syncer.getUserValue(user, key), user.Owner).Get(&oldUser)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !existed {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if user.Avatar != oldUser.Avatar && user.Avatar != "" {
|
||||
user.PermanentAvatar, err = getPermanentAvatarUrl(user.Owner, user.Name, user.Avatar, true)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
columns := syncer.getCasdoorColumns()
|
||||
columns = append(columns, "affiliation", "hash", "pre_hash")
|
||||
affected, err := ormer.Engine.Where(key+" = ? and owner = ?", syncer.getUserValue(&oldUser, key), oldUser.Owner).Cols(columns...).Update(user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package object
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -164,6 +165,33 @@ func (syncer *Syncer) setUserByKeyValue(user *User, key string, value string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (syncer *Syncer) getUserValue(user *User, key string) string {
|
||||
jsonData, _ := json.Marshal(user)
|
||||
var mapData map[string]interface{}
|
||||
if err := json.Unmarshal(jsonData, &mapData); err != nil {
|
||||
fmt.Println("conversion failed:", err)
|
||||
return user.Id
|
||||
}
|
||||
value := mapData[util.SnakeToCamel(key)]
|
||||
|
||||
if str, ok := value.(string); ok {
|
||||
return str
|
||||
} else {
|
||||
if value != nil {
|
||||
valType := reflect.TypeOf(value)
|
||||
|
||||
typeName := valType.Name()
|
||||
switch typeName {
|
||||
case "bool":
|
||||
return strconv.FormatBool(value.(bool))
|
||||
case "int":
|
||||
return strconv.Itoa(value.(int))
|
||||
}
|
||||
}
|
||||
return user.Id
|
||||
}
|
||||
}
|
||||
|
||||
func (syncer *Syncer) getOriginalUsersFromMap(results []map[string]string) []*OriginalUser {
|
||||
users := []*OriginalUser{}
|
||||
for _, result := range results {
|
||||
|
@ -34,11 +34,7 @@ const UserEnforcerId = "built-in/user-enforcer-built-in"
|
||||
var userEnforcer *UserGroupEnforcer
|
||||
|
||||
func InitUserManager() {
|
||||
enforcer, err := GetEnforcer(UserEnforcerId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = enforcer.InitEnforcer()
|
||||
enforcer, err := GetInitializedEnforcer(UserEnforcerId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -174,6 +170,7 @@ type User struct {
|
||||
Yandex string `xorm:"yandex varchar(100)" json:"yandex"`
|
||||
Zoom string `xorm:"zoom varchar(100)" json:"zoom"`
|
||||
MetaMask string `xorm:"metamask varchar(100)" json:"metamask"`
|
||||
Web3Onboard string `xorm:"web3onboard varchar(100)" json:"web3onboard"`
|
||||
Custom string `xorm:"custom varchar(100)" json:"custom"`
|
||||
|
||||
WebauthnCredentials []webauthn.Credential `xorm:"webauthnCredentials blob" json:"webauthnCredentials"`
|
||||
|
@ -51,6 +51,7 @@ func initAPI() {
|
||||
beego.Router("/api/signup", &controllers.ApiController{}, "POST:Signup")
|
||||
beego.Router("/api/login", &controllers.ApiController{}, "POST:Login")
|
||||
beego.Router("/api/get-app-login", &controllers.ApiController{}, "GET:GetApplicationLogin")
|
||||
beego.Router("/api/get-dashboard", &controllers.ApiController{}, "GET:GetDashboard")
|
||||
beego.Router("/api/logout", &controllers.ApiController{}, "GET,POST:Logout")
|
||||
beego.Router("/api/get-account", &controllers.ApiController{}, "GET:GetAccount")
|
||||
beego.Router("/api/userinfo", &controllers.ApiController{}, "GET:GetUserinfo")
|
||||
|
@ -88,6 +88,17 @@ func CamelToSnakeCase(camel string) string {
|
||||
return strings.ReplaceAll(buf.String(), " ", "")
|
||||
}
|
||||
|
||||
func SnakeToCamel(snake string) string {
|
||||
words := strings.Split(snake, "_")
|
||||
for i := range words {
|
||||
words[i] = strings.ToLower(words[i])
|
||||
if i > 0 {
|
||||
words[i] = strings.Title(words[i])
|
||||
}
|
||||
}
|
||||
return strings.Join(words, "")
|
||||
}
|
||||
|
||||
func GetOwnerAndNameFromId(id string) (string, string) {
|
||||
tokens := strings.Split(id, "/")
|
||||
if len(tokens) != 2 {
|
||||
|
@ -51,31 +51,46 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
webpack: {
|
||||
// use polyfill Buffer with Webpack 5
|
||||
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
||||
// https://craco.js.org/docs/configuration/webpack/
|
||||
configure: (webpackConfig, { env, paths }) => {
|
||||
webpackConfig.resolve.fallback = {
|
||||
// "process": require.resolve('process/browser'),
|
||||
// "util": require.resolve("util/"),
|
||||
// "url": require.resolve("url/"),
|
||||
// "zlib": require.resolve("browserify-zlib"),
|
||||
// "stream": require.resolve("stream-browserify"),
|
||||
// "http": require.resolve("stream-http"),
|
||||
// "https": require.resolve("https-browserify"),
|
||||
// "assert": require.resolve("assert/"),
|
||||
"buffer": require.resolve('buffer/'),
|
||||
"process": false,
|
||||
"util": false,
|
||||
"url": false,
|
||||
"zlib": false,
|
||||
"stream": false,
|
||||
"http": false,
|
||||
"https": false,
|
||||
"assert": false,
|
||||
"buffer": false,
|
||||
};
|
||||
return webpackConfig;
|
||||
configure: {
|
||||
// ignore webpack warnings by source-map-loader
|
||||
// https://github.com/facebook/create-react-app/pull/11752#issuecomment-1345231546
|
||||
ignoreWarnings: [
|
||||
function ignoreSourcemapsloaderWarnings(warning) {
|
||||
return (
|
||||
warning.module &&
|
||||
warning.module.resource.includes('node_modules') &&
|
||||
warning.details &&
|
||||
warning.details.includes('source-map-loader')
|
||||
)
|
||||
},
|
||||
],
|
||||
// use polyfill Buffer with Webpack 5
|
||||
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
||||
// https://craco.js.org/docs/configuration/webpack/
|
||||
resolve: {
|
||||
fallback: {
|
||||
// "process": require.resolve('process/browser'),
|
||||
// "util": require.resolve("util/"),
|
||||
// "url": require.resolve("url/"),
|
||||
// "zlib": require.resolve("browserify-zlib"),
|
||||
// "stream": require.resolve("stream-browserify"),
|
||||
// "http": require.resolve("stream-http"),
|
||||
// "https": require.resolve("https-browserify"),
|
||||
// "assert": require.resolve("assert/"),
|
||||
"buffer": require.resolve('buffer/'),
|
||||
"process": false,
|
||||
"util": false,
|
||||
"url": false,
|
||||
"zlib": false,
|
||||
"stream": false,
|
||||
"http": false,
|
||||
"https": false,
|
||||
"assert": false,
|
||||
"buffer": false,
|
||||
"crypto": false,
|
||||
"os": false,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
@ -13,6 +13,16 @@
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"@web3-onboard/coinbase": "^2.2.5",
|
||||
"@web3-onboard/core": "^2.20.5",
|
||||
"@web3-onboard/frontier": "^2.0.4",
|
||||
"@web3-onboard/gnosis": "^2.1.10",
|
||||
"@web3-onboard/infinity-wallet": "^2.0.4",
|
||||
"@web3-onboard/injected-wallets": "^2.10.4",
|
||||
"@web3-onboard/react": "^2.8.10",
|
||||
"@web3-onboard/sequence": "^2.0.8",
|
||||
"@web3-onboard/taho": "^2.0.5",
|
||||
"@web3-onboard/trust": "^2.0.4",
|
||||
"antd": "5.2.3",
|
||||
"antd-token-previewer": "^1.1.0-22",
|
||||
"buffer": "^6.0.3",
|
||||
@ -20,7 +30,9 @@
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"core-js": "^3.25.0",
|
||||
"craco-less": "^2.0.0",
|
||||
"echarts": "^5.4.3",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"ethers": "5.6.9",
|
||||
"file-saver": "^2.0.5",
|
||||
"i18n-iso-countries": "^7.0.0",
|
||||
"i18next": "^19.8.9",
|
||||
@ -44,7 +56,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "cross-env PORT=7001 craco start",
|
||||
"build": "craco build",
|
||||
"build": "craco --max_old_space_size=4096 build",
|
||||
"test": "craco test",
|
||||
"eject": "craco eject",
|
||||
"crowdin:sync": "crowdin upload && crowdin download",
|
||||
|
@ -153,10 +153,10 @@ class App extends Component {
|
||||
this.setState({selectedMenuKey: "/"});
|
||||
} else if (uri.includes("/organizations") || uri.includes("/trees") || uri.includes("/users") || uri.includes("/groups")) {
|
||||
this.setState({selectedMenuKey: "/orgs"});
|
||||
} else if (uri.includes("/roles") || uri.includes("/permissions") || uri.includes("/models") || uri.includes("/adapters") || uri.includes("/enforcers")) {
|
||||
this.setState({selectedMenuKey: "/auth"});
|
||||
} else if (uri.includes("/applications") || uri.includes("/providers") || uri.includes("/resources") || uri.includes("/certs")) {
|
||||
this.setState({selectedMenuKey: "/identity"});
|
||||
} else if (uri.includes("/roles") || uri.includes("/permissions") || uri.includes("/models") || uri.includes("/adapters") || uri.includes("/enforcers")) {
|
||||
this.setState({selectedMenuKey: "/auth"});
|
||||
} else if (uri.includes("/records") || uri.includes("/tokens") || uri.includes("/sessions")) {
|
||||
this.setState({selectedMenuKey: "/logs"});
|
||||
} else if (uri.includes("/products") || uri.includes("/payments") || uri.includes("/plans") || uri.includes("/pricings") || uri.includes("/subscriptions")) {
|
||||
@ -351,7 +351,7 @@ class App extends Component {
|
||||
}
|
||||
|
||||
|
||||
{Setting.isMobile() ? null : Setting.getNameAtLeast(this.state.account.displayName)} <DownOutlined />
|
||||
{Setting.isMobile() ? null : Setting.getShortText(Setting.getNameAtLeast(this.state.account.displayName), 30)} <DownOutlined />
|
||||
|
||||
|
||||
|
||||
@ -418,6 +418,13 @@ class App extends Component {
|
||||
Setting.getItem(<Link to="/users">{i18next.t("general:Users")}</Link>, "/users"),
|
||||
]));
|
||||
|
||||
res.push(Setting.getItem(<Link style={{color: "black"}} to="/applications">{i18next.t("general:Identity")}</Link>, "/identity", <LockTwoTone />, [
|
||||
Setting.getItem(<Link to="/applications">{i18next.t("general:Applications")}</Link>, "/applications"),
|
||||
Setting.getItem(<Link to="/providers">{i18next.t("general:Providers")}</Link>, "/providers"),
|
||||
Setting.getItem(<Link to="/resources">{i18next.t("general:Resources")}</Link>, "/resources"),
|
||||
Setting.getItem(<Link to="/certs">{i18next.t("general:Certs")}</Link>, "/certs"),
|
||||
]));
|
||||
|
||||
res.push(Setting.getItem(<Link style={{color: "black"}} to="/roles">{i18next.t("general:Authorization")}</Link>, "/auth", <SafetyCertificateTwoTone />, [
|
||||
Setting.getItem(<Link to="/roles">{i18next.t("general:Roles")}</Link>, "/roles"),
|
||||
Setting.getItem(<Link to="/permissions">{i18next.t("general:Permissions")}</Link>, "/permissions"),
|
||||
@ -431,15 +438,6 @@ class App extends Component {
|
||||
return true;
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
if (Setting.isLocalAdminUser(this.state.account)) {
|
||||
res.push(Setting.getItem(<Link style={{color: "black"}} to="/applications">{i18next.t("general:Identity")}</Link>, "/identity", <LockTwoTone />, [
|
||||
Setting.getItem(<Link to="/applications">{i18next.t("general:Applications")}</Link>, "/applications"),
|
||||
Setting.getItem(<Link to="/providers">{i18next.t("general:Providers")}</Link>, "/providers"),
|
||||
Setting.getItem(<Link to="/resources">{i18next.t("general:Resources")}</Link>, "/resources"),
|
||||
Setting.getItem(<Link to="/certs">{i18next.t("general:Certs")}</Link>, "/certs"),
|
||||
]));
|
||||
|
||||
res.push(Setting.getItem(<Link style={{color: "black"}} to="/records">{i18next.t("general:Logging & Auditing")}</Link>, "/logs", <WalletTwoTone />, [
|
||||
Setting.getItem(<Link to="/records">{i18next.t("general:Records")}</Link>, "/records"),
|
||||
|
@ -169,7 +169,7 @@ class EnforcerEditPage extends React.Component {
|
||||
<Select virtual={false} disabled={Setting.builtInObject(this.state.enforcer)} style={{width: "100%"}} value={this.state.enforcer.model} onChange={(model => {
|
||||
this.updateEnforcerField("model", model);
|
||||
})}
|
||||
options={this.state.models.map((model) => Setting.getOption(model.displayName, `${model.owner}/${model.name}`))
|
||||
options={this.state.models.map((model) => Setting.getOption(`${model.owner}/${model.name}`, `${model.owner}/${model.name}`))
|
||||
} />
|
||||
</Col>
|
||||
</Row>
|
||||
@ -181,7 +181,7 @@ class EnforcerEditPage extends React.Component {
|
||||
<Select virtual={false} disabled={Setting.builtInObject(this.state.enforcer)} style={{width: "100%"}} value={this.state.enforcer.adapter} onChange={(adapter => {
|
||||
this.updateEnforcerField("adapter", adapter);
|
||||
})}
|
||||
options={this.state.adapters.map((adapter) => Setting.getOption(adapter.name, `${adapter.owner}/${adapter.name}`))
|
||||
options={this.state.adapters.map((adapter) => Setting.getOption(`${adapter.owner}/${adapter.name}`, `${adapter.owner}/${adapter.name}`))
|
||||
} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -75,7 +75,7 @@ class EnforcerListPage extends BaseListPage {
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
width: "150px",
|
||||
width: "200px",
|
||||
fixed: "left",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
@ -116,10 +116,42 @@ class EnforcerListPage extends BaseListPage {
|
||||
title: i18next.t("general:Display name"),
|
||||
dataIndex: "displayName",
|
||||
key: "displayName",
|
||||
width: "200px",
|
||||
// width: "200px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("displayName"),
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Model"),
|
||||
dataIndex: "model",
|
||||
key: "model",
|
||||
width: "250px",
|
||||
fixed: "left",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Link to={`/models/${text}`}>
|
||||
{text}
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Adapter"),
|
||||
dataIndex: "adapter",
|
||||
key: "adapter",
|
||||
width: "250px",
|
||||
fixed: "left",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Link to={`/adapters/${text}`}>
|
||||
{text}
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Is enabled"),
|
||||
dataIndex: "isEnabled",
|
||||
@ -136,7 +168,7 @@ class EnforcerListPage extends BaseListPage {
|
||||
title: i18next.t("general:Action"),
|
||||
dataIndex: "",
|
||||
key: "op",
|
||||
width: "170px",
|
||||
width: "180px",
|
||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
|
@ -103,7 +103,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
width: "120px",
|
||||
width: "150px",
|
||||
fixed: "left",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
@ -119,7 +119,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("general:Organization"),
|
||||
dataIndex: "owner",
|
||||
key: "owner",
|
||||
width: "120px",
|
||||
width: "140px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("owner"),
|
||||
render: (text, record, index) => {
|
||||
@ -134,7 +134,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("general:Created time"),
|
||||
dataIndex: "createdTime",
|
||||
key: "createdTime",
|
||||
width: "150px",
|
||||
width: "180px",
|
||||
sorter: true,
|
||||
render: (text, record, index) => {
|
||||
return Setting.getFormattedDate(text);
|
||||
@ -144,7 +144,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("general:Updated time"),
|
||||
dataIndex: "updatedTime",
|
||||
key: "updatedTime",
|
||||
width: "150px",
|
||||
width: "180px",
|
||||
sorter: true,
|
||||
render: (text, record, index) => {
|
||||
return Setting.getFormattedDate(text);
|
||||
@ -154,7 +154,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("general:Display name"),
|
||||
dataIndex: "displayName",
|
||||
key: "displayName",
|
||||
width: "100px",
|
||||
// width: "200px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("displayName"),
|
||||
},
|
||||
@ -162,7 +162,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("general:Type"),
|
||||
dataIndex: "type",
|
||||
key: "type",
|
||||
width: "110px",
|
||||
width: "140px",
|
||||
sorter: true,
|
||||
filterMultiple: false,
|
||||
filters: [
|
||||
@ -177,7 +177,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("group:Parent group"),
|
||||
dataIndex: "parentId",
|
||||
key: "parentId",
|
||||
width: "110px",
|
||||
width: "220px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("parentId"),
|
||||
render: (text, record, index) => {
|
||||
@ -199,7 +199,7 @@ class GroupListPage extends BaseListPage {
|
||||
title: i18next.t("general:Action"),
|
||||
dataIndex: "",
|
||||
key: "op",
|
||||
width: "170px",
|
||||
width: "180px",
|
||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||
render: (text, record, index) => {
|
||||
const haveChildren = this.state.groups.find((group) => group.parentId === record.id) !== undefined;
|
||||
|
@ -191,8 +191,8 @@ class LdapSyncPage extends React.Component {
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Phone"),
|
||||
dataIndex: "phone",
|
||||
key: "phone",
|
||||
dataIndex: "mobile",
|
||||
key: "mobile",
|
||||
sorter: (a, b) => a.phone.localeCompare(b.phone),
|
||||
},
|
||||
{
|
||||
|
@ -182,7 +182,7 @@ class OrganizationListPage extends BaseListPage {
|
||||
title: i18next.t("organization:Website URL"),
|
||||
dataIndex: "websiteUrl",
|
||||
key: "websiteUrl",
|
||||
width: "300px",
|
||||
width: "200px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("websiteUrl"),
|
||||
render: (text, record, index) => {
|
||||
@ -243,7 +243,7 @@ class OrganizationListPage extends BaseListPage {
|
||||
title: i18next.t("general:Action"),
|
||||
dataIndex: "",
|
||||
key: "op",
|
||||
width: "320px",
|
||||
width: "350px",
|
||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, InputNumber, Row, Select, Switch} from "antd";
|
||||
import {Button, Card, Checkbox, Col, Input, InputNumber, Row, Select, Switch} from "antd";
|
||||
import {LinkOutlined} from "@ant-design/icons";
|
||||
import * as ProviderBackend from "./backend/ProviderBackend";
|
||||
import * as Setting from "./Setting";
|
||||
@ -25,6 +25,7 @@ import copy from "copy-to-clipboard";
|
||||
import {CaptchaPreview} from "./common/CaptchaPreview";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import {CountryCodeSelect} from "./common/select/CountryCodeSelect";
|
||||
import * as Web3Auth from "./auth/Web3Auth";
|
||||
|
||||
const {Option} = Select;
|
||||
const {TextArea} = Input;
|
||||
@ -356,7 +357,7 @@ class ProviderEditPage extends React.Component {
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.provider.category} onChange={(value => {
|
||||
this.updateProviderField("category", value);
|
||||
if (value === "OAuth") {
|
||||
this.updateProviderField("type", "GitHub");
|
||||
this.updateProviderField("type", "Google");
|
||||
} else if (value === "Email") {
|
||||
this.updateProviderField("type", "Default");
|
||||
this.updateProviderField("host", "smtp.example.com");
|
||||
@ -366,12 +367,12 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("content", "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes.");
|
||||
this.updateProviderField("receiver", this.props.account.email);
|
||||
} else if (value === "SMS") {
|
||||
this.updateProviderField("type", "Aliyun SMS");
|
||||
this.updateProviderField("type", "Twilio SMS");
|
||||
} else if (value === "Storage") {
|
||||
this.updateProviderField("type", "Local File System");
|
||||
this.updateProviderField("type", "AWS S3");
|
||||
this.updateProviderField("domain", Setting.getFullServerUrl());
|
||||
} else if (value === "SAML") {
|
||||
this.updateProviderField("type", "Aliyun IDaaS");
|
||||
this.updateProviderField("type", "Keycloak");
|
||||
} else if (value === "Payment") {
|
||||
this.updateProviderField("type", "PayPal");
|
||||
} else if (value === "Captcha") {
|
||||
@ -406,12 +407,16 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("type", value);
|
||||
if (value === "Local File System") {
|
||||
this.updateProviderField("domain", Setting.getFullServerUrl());
|
||||
}
|
||||
if (value === "Custom") {
|
||||
} else if (value === "Custom") {
|
||||
this.updateProviderField("customAuthUrl", "https://door.casdoor.com/login/oauth/authorize");
|
||||
this.updateProviderField("scopes", "openid profile email");
|
||||
this.updateProviderField("customTokenUrl", "https://door.casdoor.com/api/login/oauth/access_token");
|
||||
this.updateProviderField("customUserInfoUrl", "https://door.casdoor.com/api/userinfo");
|
||||
} else if (value === "Custom HTTP SMS") {
|
||||
this.updateProviderField("endpoint", "https://door.casdoor.com/api/get-account");
|
||||
this.updateProviderField("method", "GET");
|
||||
this.updateProviderField("clientId", "param1");
|
||||
this.updateProviderField("title", "");
|
||||
}
|
||||
})}>
|
||||
{
|
||||
@ -547,30 +552,33 @@ class ProviderEditPage extends React.Component {
|
||||
)
|
||||
}
|
||||
{
|
||||
(this.state.provider.category === "Captcha" && this.state.provider.type === "Default") || (this.state.provider.category === "Web3") || (this.state.provider.category === "Storage" && this.state.provider.type === "Local File System") ? null : (
|
||||
<React.Fragment>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{this.getClientIdLabel(this.state.provider)} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.clientId} onChange={e => {
|
||||
this.updateProviderField("clientId", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{this.getClientSecretLabel(this.state.provider)} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.clientSecret} onChange={e => {
|
||||
this.updateProviderField("clientSecret", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)
|
||||
(this.state.provider.category === "Captcha" && this.state.provider.type === "Default") ||
|
||||
(this.state.provider.category === "SMS" && this.state.provider.type === "Custom HTTP SMS") ||
|
||||
(this.state.provider.category === "Web3") ||
|
||||
(this.state.provider.category === "Storage" && this.state.provider.type === "Local File System") ? null : (
|
||||
<React.Fragment>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{this.getClientIdLabel(this.state.provider)} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.clientId} onChange={e => {
|
||||
this.updateProviderField("clientId", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{this.getClientSecretLabel(this.state.provider)} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.clientSecret} onChange={e => {
|
||||
this.updateProviderField("clientSecret", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.provider.category !== "Email" && this.state.provider.type !== "WeChat" && this.state.provider.type !== "Aliyun Captcha" && this.state.provider.type !== "WeChat Pay" ? null : (
|
||||
@ -623,14 +631,14 @@ class ProviderEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.domain} onChange={e => {
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.domain} onChange={e => {
|
||||
this.updateProviderField("domain", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
{this.state.provider.category === "Storage" ? (
|
||||
{this.state.provider.category === "Storage" || this.state.provider.type === "Custom HTTP SMS" ? (
|
||||
<div>
|
||||
{["Local File System"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
@ -638,25 +646,25 @@ class ProviderEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("provider:Endpoint"), i18next.t("provider:Region endpoint for Internet"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.endpoint} onChange={e => {
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.endpoint} onChange={e => {
|
||||
this.updateProviderField("endpoint", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? null : (
|
||||
{["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.intranetEndpoint} onChange={e => {
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.intranetEndpoint} onChange={e => {
|
||||
this.updateProviderField("intranetEndpoint", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Local File System"].includes(this.state.provider.type) ? null : (
|
||||
{["Custom HTTP SMS", "Local File System"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} :
|
||||
@ -668,23 +676,25 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Path prefix"), i18next.t("provider:Path prefix - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.pathPrefix} onChange={e => {
|
||||
this.updateProviderField("pathPrefix", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
{["MinIO", "Google Cloud Storage", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? null : (
|
||||
{["Custom HTTP SMS"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Path prefix"), i18next.t("provider:Path prefix - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.pathPrefix} onChange={e => {
|
||||
this.updateProviderField("pathPrefix", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Custom HTTP SMS", "MinIO", "Google Cloud Storage", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.domain} disabled={this.state.provider.type === "Local File System"} onChange={e => {
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.domain} disabled={this.state.provider.type === "Local File System"} onChange={e => {
|
||||
this.updateProviderField("domain", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
@ -704,6 +714,49 @@ class ProviderEditPage extends React.Component {
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
{
|
||||
this.state.provider.type !== "Custom HTTP SMS" ? null : (
|
||||
<React.Fragment>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("general:Method"), i18next.t("provider:Method - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.provider.method} onChange={value => {
|
||||
this.updateProviderField("method", value);
|
||||
}}>
|
||||
{
|
||||
[
|
||||
{id: "GET", name: "GET"},
|
||||
{id: "POST", name: "POST"},
|
||||
].map((method, index) => <Option key={index} value={method.id}>{method.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Parameter name"), i18next.t("provider:Parameter name - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.clientId} onChange={e => {
|
||||
this.updateProviderField("clientId", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Content"), i18next.t("provider:Content - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<TextArea autoSize={{minRows: 3, maxRows: 100}} value={this.state.provider.title} onChange={e => {
|
||||
this.updateProviderField("title", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
{this.getAppIdRow(this.state.provider)}
|
||||
{
|
||||
this.state.provider.category === "Email" ? (
|
||||
@ -779,7 +832,7 @@ class ProviderEditPage extends React.Component {
|
||||
</React.Fragment>
|
||||
) : this.state.provider.category === "SMS" ? (
|
||||
<React.Fragment>
|
||||
{["Twilio SMS", "Amazon SNS", "Azure ACS", "Msg91 SMS", "Infobip SMS"].includes(this.state.provider.type) ?
|
||||
{["Custom HTTP SMS", "Twilio SMS", "Amazon SNS", "Azure ACS", "Msg91 SMS", "Infobip SMS"].includes(this.state.provider.type) ?
|
||||
null :
|
||||
(<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
@ -793,7 +846,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
{["Infobip SMS"].includes(this.state.provider.type) ?
|
||||
{["Custom HTTP SMS", "Infobip SMS"].includes(this.state.provider.type) ?
|
||||
null :
|
||||
(<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
@ -811,27 +864,32 @@ class ProviderEditPage extends React.Component {
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:SMS Test"), i18next.t("provider:SMS Test - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={4} >
|
||||
<Input.Group compact>
|
||||
<CountryCodeSelect
|
||||
style={{width: "30%"}}
|
||||
value={this.state.provider.content}
|
||||
onChange={(value) => {
|
||||
this.updateProviderField("content", value);
|
||||
}}
|
||||
countryCodes={this.props.account.organization.countryCodes}
|
||||
/>
|
||||
<Input value={this.state.provider.receiver}
|
||||
style={{width: "70%"}}
|
||||
placeholder = {i18next.t("user:Input your phone number")}
|
||||
onChange={e => {
|
||||
this.updateProviderField("receiver", e.target.value);
|
||||
}} />
|
||||
</Input.Group>
|
||||
</Col>
|
||||
{["Custom HTTP SMS"].includes(this.state.provider.type) ?
|
||||
null :
|
||||
(
|
||||
<Col span={4} >
|
||||
<Input.Group compact>
|
||||
<CountryCodeSelect
|
||||
style={{width: "30%"}}
|
||||
value={this.state.provider.content}
|
||||
onChange={(value) => {
|
||||
this.updateProviderField("content", value);
|
||||
}}
|
||||
countryCodes={this.props.account.organization.countryCodes}
|
||||
/>
|
||||
<Input value={this.state.provider.receiver}
|
||||
style={{width: "70%"}}
|
||||
placeholder = {i18next.t("user:Input your phone number")}
|
||||
onChange={e => {
|
||||
this.updateProviderField("receiver", e.target.value);
|
||||
}} />
|
||||
</Input.Group>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
<Col span={2} >
|
||||
<Button style={{marginLeft: "10px", marginBottom: "5px"}} type="primary"
|
||||
disabled={!Setting.isValidPhone(this.state.provider.receiver)}
|
||||
disabled={!Setting.isValidPhone(this.state.provider.receiver) && (this.state.provider.type !== "Custom HTTP SMS" || this.state.provider.endpoint === "")}
|
||||
onClick={() => ProviderEditTestSms.sendTestSms(this.state.provider, "+" + Setting.getCountryCode(this.state.provider.content) + this.state.provider.receiver)} >
|
||||
{i18next.t("provider:Send Testing SMS")}
|
||||
</Button>
|
||||
@ -954,6 +1012,30 @@ class ProviderEditPage extends React.Component {
|
||||
</Row>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
this.state.provider.type === "Web3Onboard" ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Wallets"), i18next.t("provider:Wallets - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<Checkbox.Group
|
||||
options={Web3Auth.getWeb3OnboardWalletsOptions()}
|
||||
value={() => {
|
||||
try {
|
||||
return JSON.parse(this.state.provider.metadata);
|
||||
} catch {
|
||||
return ["injected"];
|
||||
}
|
||||
}}
|
||||
onChange={options => {
|
||||
this.updateProviderField("metadata", JSON.stringify(options));
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
) : null
|
||||
}
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Provider URL"), i18next.t("provider:Provider URL - Tooltip"))} :
|
||||
|
@ -93,6 +93,10 @@ export const OtherProviderInfo = {
|
||||
logo: `${StaticBaseUrl}/img/social_azure.png`,
|
||||
url: "https://azure.microsoft.com/en-us/products/communication-services",
|
||||
},
|
||||
"Custom HTTP SMS": {
|
||||
logo: `${StaticBaseUrl}/img/email_default.png`,
|
||||
url: "https://casdoor.org/docs/provider/sms/overview",
|
||||
},
|
||||
"Infobip SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_infobip.png`,
|
||||
url: "https://portal.infobip.com/homepage/",
|
||||
@ -255,6 +259,10 @@ export const OtherProviderInfo = {
|
||||
logo: `${StaticBaseUrl}/img/social_metamask.svg`,
|
||||
url: "https://metamask.io/",
|
||||
},
|
||||
"Web3Onboard": {
|
||||
logo: `${StaticBaseUrl}/img/social_web3onboard.svg`,
|
||||
url: "https://onboard.blocknative.com/",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -888,6 +896,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: "Aliyun SMS", name: "Alibaba Cloud SMS"},
|
||||
{id: "Amazon SNS", name: "Amazon SNS"},
|
||||
{id: "Azure ACS", name: "Azure ACS"},
|
||||
{id: "Custom HTTP SMS", name: "Custom HTTP SMS"},
|
||||
{id: "Infobip SMS", name: "Infobip SMS"},
|
||||
{id: "Tencent Cloud SMS", name: "Tencent Cloud SMS"},
|
||||
{id: "Baidu Cloud SMS", name: "Baidu Cloud SMS"},
|
||||
@ -938,6 +947,7 @@ export function getProviderTypeOptions(category) {
|
||||
} else if (category === "Web3") {
|
||||
return ([
|
||||
{id: "MetaMask", name: "MetaMask"},
|
||||
{id: "Web3Onboard", name: "Web3-Onboard"},
|
||||
]);
|
||||
} else {
|
||||
return [];
|
||||
|
@ -313,16 +313,6 @@ class SyncerEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("syncer:Table primary key"), i18next.t("syncer:Table primary key - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.syncer.tablePrimaryKey} onChange={e => {
|
||||
this.updateSyncerField("tablePrimaryKey", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("syncer:Table columns"), i18next.t("syncer:Table columns - Tooltip"))} :
|
||||
|
@ -570,7 +570,7 @@ class UserEditPage extends React.Component {
|
||||
{name: "ID card back", value: "idCardBack"},
|
||||
{name: "ID card with person", value: "idCardWithPerson"},
|
||||
].map((entry) => {
|
||||
return this.renderImage(this.state.user.properties[entry.value] || "", this.getIdCardType(entry.name), this.getIdCardText(entry.name), entry.value, disabled);
|
||||
return this.renderImage(this.state.user.properties === null ? "" : (this.state.user.properties[entry.value] || ""), this.getIdCardType(entry.name), this.getIdCardText(entry.name), entry.value, disabled);
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
@ -995,11 +995,13 @@ class UserEditPage extends React.Component {
|
||||
<Col span={4} style={{textAlign: "center", margin: "auto"}} key={tag}>
|
||||
{
|
||||
imgUrl ?
|
||||
<a target="_blank" rel="noreferrer" href={imgUrl} style={{marginBottom: "10px"}}>
|
||||
<AccountAvatar src={imgUrl} alt={imgUrl} size={90} style={{marginBottom: "20px"}} />
|
||||
</a>
|
||||
<div style={{marginBottom: "10px"}}>
|
||||
<a target="_blank" rel="noreferrer" href={imgUrl} style={{marginBottom: "10px"}}>
|
||||
<AccountAvatar src={imgUrl} alt={imgUrl} height={150} />
|
||||
</a>
|
||||
</div>
|
||||
:
|
||||
<Col style={{height: "78%", border: "1px dotted grey", borderRadius: 3, marginBottom: 5}}>
|
||||
<Col style={{height: "78%", border: "1px dotted grey", borderRadius: 3, marginBottom: "10px"}}>
|
||||
<div style={{fontSize: 30, margin: 10}}>+</div>
|
||||
<div style={{verticalAlign: "middle", marginBottom: 10}}>{`Upload ${title}...`}</div>
|
||||
</Col>
|
||||
|
@ -17,7 +17,7 @@ import {MetaMaskAvatar} from "react-metamask-avatar";
|
||||
|
||||
class AccountAvatar extends React.Component {
|
||||
render() {
|
||||
const {src, size} = this.props;
|
||||
const {src, size, width, height} = this.props;
|
||||
// The avatar for Metamask account is directly generated by an algorithm based on the address
|
||||
// src = "metamask:0xC304b2cC0Be8E9ce10fF3Afd34820Ed306A23600";
|
||||
const matchMetaMask = src.match(/^metamask:(\w+)$/);
|
||||
@ -27,9 +27,19 @@ class AccountAvatar extends React.Component {
|
||||
<MetaMaskAvatar address={address} size={size} />
|
||||
);
|
||||
}
|
||||
return (
|
||||
<img width={size} height={size} src={src} />
|
||||
);
|
||||
if (size !== undefined) {
|
||||
return (
|
||||
<img width={size} height={size} src={src} />
|
||||
);
|
||||
} else if (width === undefined) {
|
||||
return (
|
||||
<img height={height} src={src} />
|
||||
);
|
||||
} else if (height === undefined) {
|
||||
return (
|
||||
<img width={width} src={src} />
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ class AuthCallback extends React.Component {
|
||||
if (code === null) {
|
||||
code = params.get("authCode");
|
||||
}
|
||||
// The code for Metamask is the JSON-serialized string of Web3AuthToken
|
||||
// The code for Web3 is the JSON-serialized string of Web3AuthToken
|
||||
// Due to the limited length of URLs, we only pass the web3AuthTokenKey
|
||||
if (code === null) {
|
||||
code = params.get("web3AuthTokenKey");
|
||||
|
@ -321,6 +321,10 @@ const authInfo = {
|
||||
scope: "",
|
||||
endpoint: "",
|
||||
},
|
||||
Web3Onboard: {
|
||||
scope: "",
|
||||
endpoint: "",
|
||||
},
|
||||
};
|
||||
|
||||
export function getProviderUrl(provider) {
|
||||
@ -465,5 +469,7 @@ export function getAuthUrl(application, provider, method) {
|
||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
||||
} else if (provider.type === "MetaMask") {
|
||||
return `${redirectUri}?state=${state}`;
|
||||
} else if (provider.type === "Web3Onboard") {
|
||||
return `${redirectUri}?state=${state}`;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import i18next from "i18next";
|
||||
import * as Provider from "./Provider";
|
||||
import {getProviderLogoURL} from "../Setting";
|
||||
import {GithubLoginButton, GoogleLoginButton} from "react-social-login-buttons";
|
||||
import {authViaMetaMask} from "./Web3Auth";
|
||||
import {authViaMetaMask, authViaWeb3Onboard} from "./Web3Auth";
|
||||
import QqLoginButton from "./QqLoginButton";
|
||||
import FacebookLoginButton from "./FacebookLoginButton";
|
||||
import WeiboLoginButton from "./WeiboLoginButton";
|
||||
@ -46,7 +46,7 @@ import {getEvent} from "./Util";
|
||||
import {Modal} from "antd";
|
||||
|
||||
function getSigninButton(provider) {
|
||||
const text = i18next.t("login:Sign in with {type}").replace("{type}", provider.type);
|
||||
const text = i18next.t("login:Sign in with {type}").replace("{type}", provider.displayName !== "" ? provider.displayName : provider.type);
|
||||
if (provider.type === "GitHub") {
|
||||
return <GithubLoginButton text={text} align={"center"} />;
|
||||
} else if (provider.type === "Google") {
|
||||
@ -121,6 +121,8 @@ function goToSamlUrl(provider, location) {
|
||||
export function goToWeb3Url(application, provider, method) {
|
||||
if (provider.type === "MetaMask") {
|
||||
authViaMetaMask(application, provider, method);
|
||||
} else if (provider.type === "Web3Onboard") {
|
||||
authViaWeb3Onboard(application, provider, method);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,25 @@ import {v4 as uuidv4} from "uuid";
|
||||
import {SignTypedDataVersion, recoverTypedSignature} from "@metamask/eth-sig-util";
|
||||
import {getAuthUrl} from "./Provider";
|
||||
import {Buffer} from "buffer";
|
||||
// import {toChecksumAddress} from "ethereumjs-util";
|
||||
import Onboard from "@web3-onboard/core";
|
||||
import injectedModule from "@web3-onboard/injected-wallets";
|
||||
import infinityWalletModule from "@web3-onboard/infinity-wallet";
|
||||
import sequenceModule from "@web3-onboard/sequence";
|
||||
import trustModule from "@web3-onboard/trust";
|
||||
import frontierModule from "@web3-onboard/frontier";
|
||||
import tahoModule from "@web3-onboard/taho";
|
||||
import coinbaseModule from "@web3-onboard/coinbase";
|
||||
import gnosisModule from "@web3-onboard/gnosis";
|
||||
// import keystoneModule from "@web3-onboard/keystone";
|
||||
// import keepkeyModule from "@web3-onboard/keepkey";
|
||||
// import dcentModule from "@web3-onboard/dcent";
|
||||
// import ledgerModule from "@web3-onboard/ledger";
|
||||
// import trezorModule from "@web3-onboard/trezor";
|
||||
// import walletConnectModule from "@web3-onboard/walletconnect";
|
||||
// import fortmaticModule from "@web3-onboard/fortmatic";
|
||||
// import portisModule from "@web3-onboard/portis";
|
||||
// import magicModule from "@web3-onboard/magic";
|
||||
|
||||
global.Buffer = Buffer;
|
||||
|
||||
export function generateNonce() {
|
||||
@ -147,3 +165,174 @@ export async function authViaMetaMask(application, provider, method) {
|
||||
showMessage("error", `${i18next.t("login:Failed to obtain MetaMask authorization")}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
const web3Wallets = {
|
||||
// injected wallets
|
||||
injected: {
|
||||
label: "Injected",
|
||||
wallet: injectedModule(),
|
||||
},
|
||||
// sdk wallets
|
||||
coinbase: {
|
||||
label: "Coinbase",
|
||||
wallet: coinbaseModule(),
|
||||
},
|
||||
trust: {
|
||||
label: "Trust",
|
||||
wallet: trustModule(),
|
||||
},
|
||||
gnosis: {
|
||||
label: "Gnosis",
|
||||
wallet: gnosisModule(),
|
||||
},
|
||||
sequence: {
|
||||
label: "Sequence",
|
||||
wallet: sequenceModule(),
|
||||
},
|
||||
taho: {
|
||||
label: "Taho",
|
||||
wallet: tahoModule(),
|
||||
},
|
||||
frontier: {
|
||||
label: "Frontier",
|
||||
wallet: frontierModule(),
|
||||
},
|
||||
infinityWallet: {
|
||||
label: "Infinity Wallet",
|
||||
wallet: infinityWalletModule(),
|
||||
},
|
||||
// hardware wallets
|
||||
// keystone: {
|
||||
// label: "Keystone",
|
||||
// wallet: keystoneModule(),
|
||||
// },
|
||||
// keepkey: {
|
||||
// label: "KeepKey",
|
||||
// wallet: keepkeyModule(),
|
||||
// },
|
||||
// dcent: {
|
||||
// label: "D'CENT",
|
||||
// wallet: dcentModule(),
|
||||
// },
|
||||
|
||||
// some wallet need custome `apiKey` or `projectId` configure item
|
||||
// const magic = magicModule({
|
||||
// apiKey: "magicApiKey",
|
||||
// });
|
||||
// const fortmatic = fortmaticModule({
|
||||
// apiKey: "fortmaticApiKey",
|
||||
// });
|
||||
// const portis = portisModule({
|
||||
// apiKey: "portisApiKey",
|
||||
// });
|
||||
// const ledger = ledgerModule({
|
||||
// projectId: "ledgerProjectId"
|
||||
// });
|
||||
// const walletConnect = walletConnectModule({
|
||||
// projectId: "walletConnectProjectId",
|
||||
// });
|
||||
};
|
||||
|
||||
export function getWeb3OnboardWalletsOptions() {
|
||||
return Object.entries(web3Wallets).map(([key, value]) => ({
|
||||
label: value.label,
|
||||
value: key,
|
||||
}));
|
||||
}
|
||||
|
||||
function getWeb3OnboardWallets(options) {
|
||||
if (options === null || options === undefined || !Array.isArray(options)) {
|
||||
return [];
|
||||
}
|
||||
return options.map(walletType => {
|
||||
if (walletType && web3Wallets[walletType]?.wallet) {
|
||||
return web3Wallets[walletType]?.wallet;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function initWeb3Onboard(application, provider) {
|
||||
// init wallet
|
||||
// options = ["injected","coinbase",...]
|
||||
const options = JSON.parse(provider.metadata);
|
||||
const wallets = getWeb3OnboardWallets(options);
|
||||
|
||||
// init chain
|
||||
// const InfuraKey = "2fa45cbe531e4e65be4fcbf408e651a8";
|
||||
const chains = [
|
||||
// {
|
||||
// id: "0x1",
|
||||
// token: "ETH",
|
||||
// label: "Ethereum Mainnet",
|
||||
// rpcUrl: `https://mainnet.infura.io/v3/${InfuraKey}`,
|
||||
// },
|
||||
// {
|
||||
// id: "0x5",
|
||||
// token: "ETH",
|
||||
// label: "Goerli",
|
||||
// rpcUrl: `https://goerli.infura.io/v3/${InfuraKey}`,
|
||||
// },
|
||||
{
|
||||
id: "0x13881",
|
||||
token: "MATIC",
|
||||
label: "Polygon - Mumbai",
|
||||
rpcUrl: "https://matic-mumbai.chainstacklabs.com",
|
||||
},
|
||||
{
|
||||
id: "0x38",
|
||||
token: "BNB",
|
||||
label: "Binance",
|
||||
rpcUrl: "https://bsc-dataseed.binance.org/",
|
||||
},
|
||||
{
|
||||
id: "0xA",
|
||||
token: "OETH",
|
||||
label: "Optimism",
|
||||
rpcUrl: "https://mainnet.optimism.io",
|
||||
},
|
||||
{
|
||||
id: "0xA4B1",
|
||||
token: "ARB-ETH",
|
||||
label: "Arbitrum",
|
||||
rpcUrl: "https://rpc.ankr.com/arbitrum",
|
||||
},
|
||||
];
|
||||
|
||||
const appMetadata = {
|
||||
name: "Casdoor",
|
||||
description: "Connect a wallet using Casdoor",
|
||||
recommendedInjectedWallets: [
|
||||
{name: "MetaMask", url: "https://metamask.io"},
|
||||
{name: "Coinbase", url: "https://wallet.coinbase.com/"},
|
||||
],
|
||||
};
|
||||
|
||||
const web3Onboard = Onboard({
|
||||
wallets,
|
||||
chains,
|
||||
appMetadata,
|
||||
});
|
||||
return web3Onboard;
|
||||
}
|
||||
|
||||
export async function authViaWeb3Onboard(application, provider, method) {
|
||||
try {
|
||||
const onboard = initWeb3Onboard(application, provider);
|
||||
const connectedWallets = await onboard.connectWallet();
|
||||
if (connectedWallets.length > 0) {
|
||||
const wallet = connectedWallets[0];
|
||||
const account = wallet.accounts[0];
|
||||
const address = account.address;
|
||||
const token = {
|
||||
address: address, // e.g."0xbd5444d31fe4139ee36bea29e43d4ac67ae276de"
|
||||
walletType: wallet.label, // e.g."MetaMask"
|
||||
createAt: Math.floor(new Date().getTime() / 1000),
|
||||
};
|
||||
setWeb3AuthToken(token);
|
||||
const redirectUri = `${getAuthUrl(application, provider, method)}&web3AuthTokenKey=${getWeb3AuthTokenKey(address)}`;
|
||||
goToLink(redirectUri);
|
||||
}
|
||||
} catch (err) {
|
||||
showMessage("error", `${i18next.t("login:Failed to obtain Web3-Onboard authorization")}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
25
web/src/backend/DashboardBackend.js
Normal file
25
web/src/backend/DashboardBackend.js
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import * as Setting from "../Setting";
|
||||
|
||||
export function getDashboard(owner, name) {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-dashboard`, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Accept-Language": Setting.getAcceptLanguage(),
|
||||
},
|
||||
}).then(res => res.json());
|
||||
}
|
@ -13,8 +13,11 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Card, Col, Row} from "antd";
|
||||
import {Card, Col, Row, Spin, Statistic} from "antd";
|
||||
import {ArrowUpOutlined} from "@ant-design/icons";
|
||||
import * as ApplicationBackend from "../backend/ApplicationBackend";
|
||||
import * as DashboardBackend from "../backend/DashboardBackend";
|
||||
import * as echarts from "echarts";
|
||||
import * as Setting from "../Setting";
|
||||
import SingleCard from "./SingleCard";
|
||||
import i18next from "i18next";
|
||||
@ -25,11 +28,13 @@ class HomePage extends React.Component {
|
||||
this.state = {
|
||||
classes: props,
|
||||
applications: null,
|
||||
dashboardData: null,
|
||||
};
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getApplicationsByOrganization(this.props.account.owner);
|
||||
this.getDashboard();
|
||||
}
|
||||
|
||||
getApplicationsByOrganization(organizationName) {
|
||||
@ -41,6 +46,21 @@ class HomePage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getDashboard() {
|
||||
DashboardBackend.getDashboard()
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
dashboardData: res.data,
|
||||
}, () => {
|
||||
this.renderEChart();
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getItems() {
|
||||
let items = [];
|
||||
if (Setting.isAdminUser(this.props.account)) {
|
||||
@ -75,9 +95,53 @@ class HomePage extends React.Component {
|
||||
return items;
|
||||
}
|
||||
|
||||
renderEChart() {
|
||||
const data = this.state.dashboardData;
|
||||
|
||||
const chartDom = document.getElementById("echarts-chart");
|
||||
const myChart = echarts.init(chartDom);
|
||||
const currentDate = new Date();
|
||||
const dateArray = [];
|
||||
for (let i = 30; i >= 0; i--) {
|
||||
const date = new Date(currentDate);
|
||||
date.setDate(date.getDate() - i);
|
||||
const month = parseInt(date.getMonth()) + 1;
|
||||
const day = parseInt(date.getDate());
|
||||
const formattedDate = `${month}-${day}`;
|
||||
dateArray.push(formattedDate);
|
||||
}
|
||||
const option = {
|
||||
title: {text: i18next.t("home:Past 30 Days")},
|
||||
tooltip: {trigger: "axis"},
|
||||
legend: {data: [
|
||||
i18next.t("general:Users"),
|
||||
i18next.t("general:Providers"),
|
||||
i18next.t("general:Applications"),
|
||||
i18next.t("general:Organizations"),
|
||||
i18next.t("general:Subscriptions"),
|
||||
]},
|
||||
grid: {left: "3%", right: "4%", bottom: "3%", containLabel: true},
|
||||
xAxis: {type: "category", boundaryGap: false, data: dateArray},
|
||||
yAxis: {type: "value"},
|
||||
series: [
|
||||
{name: i18next.t("general:Organizations"), type: "line", data: data?.organizationCounts},
|
||||
{name: i18next.t("general:Users"), type: "line", data: data?.userCounts},
|
||||
{name: i18next.t("general:Providers"), type: "line", data: data?.providerCounts},
|
||||
{name: i18next.t("general:Applications"), type: "line", data: data?.applicationCounts},
|
||||
{name: i18next.t("general:Subscriptions"), type: "line", data: data?.subscriptionCounts},
|
||||
],
|
||||
};
|
||||
myChart.setOption(option);
|
||||
}
|
||||
|
||||
renderCards() {
|
||||
if (this.state.applications === null) {
|
||||
return null;
|
||||
const data = this.state.dashboardData;
|
||||
if (data === null) {
|
||||
return (
|
||||
<div style={{display: "flex", justifyContent: "center", alignItems: "center", marginTop: "10%"}}>
|
||||
<Spin size="large" tip={i18next.t("login:Loading")} style={{paddingTop: "10%"}} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const items = this.getItems();
|
||||
@ -96,24 +160,35 @@ class HomePage extends React.Component {
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div style={{marginRight: "15px", marginLeft: "15px"}}>
|
||||
<Row style={{marginLeft: "-20px", marginRight: "-20px", marginTop: "20px"}} gutter={24}>
|
||||
{
|
||||
items.map(item => {
|
||||
return (
|
||||
<SingleCard logo={item.logo} link={item.link} title={item.name} desc={item.organizer} time={item.createdTime} isSingle={items.length === 1} key={item.name} />
|
||||
);
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
<Row gutter={80}>
|
||||
<Col span={50}>
|
||||
<Card bordered={false} bodyStyle={{width: "100%", height: "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||
<Statistic title={i18next.t("home:Total users")} fontSize="100px" value={data?.userCounts[30]} valueStyle={{fontSize: "30px"}} style={{width: "200px", paddingLeft: "10px"}} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={50}>
|
||||
<Card bordered={false} bodyStyle={{width: "100%", height: "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||
<Statistic title={i18next.t("home:New users today")} fontSize="100px" value={data?.userCounts[30] - data?.userCounts[30 - 1]} valueStyle={{fontSize: "30px"}} prefix={<ArrowUpOutlined />} style={{width: "200px", paddingLeft: "10px"}} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={50}>
|
||||
<Card bordered={false} bodyStyle={{width: "100%", height: "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||
<Statistic title={i18next.t("home:New users past 7 days")} value={data?.userCounts[30] - data?.userCounts[30 - 7]} valueStyle={{fontSize: "30px"}} prefix={<ArrowUpOutlined />} style={{width: "200px", paddingLeft: "10px"}} />
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={50}>
|
||||
<Card bordered={false} bodyStyle={{width: "100%", height: "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
|
||||
<Statistic title={i18next.t("home:New users past 30 days")} value={data?.userCounts[30] - data?.userCounts[30 - 30]} valueStyle={{fontSize: "30px"}} prefix={<ArrowUpOutlined />} style={{width: "200px", paddingLeft: "10px"}} />
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div style={{display: "flex", justifyContent: "center", flexDirection: "column", alignItems: "center"}}>
|
||||
<Row style={{width: "100%"}}>
|
||||
<Col span={24} style={{display: "flex", justifyContent: "center"}} >
|
||||
{
|
||||
@ -121,6 +196,8 @@ class HomePage extends React.Component {
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
<div id="echarts-chart"
|
||||
style={{width: "80%", height: "400px", textAlign: "center", marginTop: "20px"}}></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ class OAuthWidget extends React.Component {
|
||||
// should add the unlink user's info, cause the user may not be logged in, but a admin want to unlink the user.
|
||||
user: this.props.user,
|
||||
};
|
||||
if (providerType === "MetaMask") {
|
||||
if (providerType === "MetaMask" || providerType === "Web3Onboard") {
|
||||
delWeb3AuthToken(linkedValue);
|
||||
}
|
||||
AuthBackend.unlink(body)
|
||||
@ -158,7 +158,12 @@ class OAuthWidget extends React.Component {
|
||||
</Col>
|
||||
<Col span={24 - this.props.labelSpan} >
|
||||
<AccountAvatar style={{marginRight: "10px"}} size={30} src={avatarUrl} alt={name} referrerPolicy="no-referrer" />
|
||||
<span style={{width: this.props.labelSpan === 3 ? "300px" : "200px", display: (Setting.isMobile()) ? "inline" : "inline-block"}}>
|
||||
<span style={{
|
||||
width: this.props.labelSpan === 3 ? "300px" : "200px",
|
||||
display: (Setting.isMobile()) ? "inline" : "inline-block",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}} title={name}>
|
||||
{
|
||||
linkedValue === "" ? (
|
||||
`(${i18next.t("general:empty")})`
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Tabellenname des Policy Stores",
|
||||
"Adapters": "Adapter",
|
||||
"Add": "Hinzufügen",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "Affiliation-URL",
|
||||
"Affiliation URL - Tooltip": "Die Homepage-URL für die Zugehörigkeit",
|
||||
"Application": "Applikation",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Anwendungen",
|
||||
"Applications that require authentication": "Anwendungen, die eine Authentifizierung erfordern",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Öffentliches Avatarbild für den Benutzer",
|
||||
"Back": "Back",
|
||||
"Back Home": "Zurück nach Hause",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Abbrechen",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Zertifikat",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Homepage der Anwendung",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Einzigartiger Zufallsstring",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Ist aktiviert",
|
||||
"Is enabled - Tooltip": "Festlegen, ob es verwendet werden kann",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Verfügbare Sprachen",
|
||||
"Last name": "Nachname",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Symbole, die die Anwendung der Außenwelt präsentiert",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "Nutzer",
|
||||
"User - Tooltip": "Stellen Sie sicher, dass der Benutzername korrekt ist",
|
||||
"User Management": "User Management",
|
||||
"User containers": "Nutzerpools",
|
||||
"User type": "Benutzertyp",
|
||||
"User type - Tooltip": "Tags, denen der Benutzer angehört, standardmäßig auf \"normaler Benutzer\" festgelegt",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Wie USD, CNY usw.",
|
||||
"Download Invoice": "Rechnung herunterladen",
|
||||
"Edit Payment": "Zahlung bearbeiten",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "individuell",
|
||||
"Invoice URL": "Rechnungs-URL",
|
||||
"Invoice URL - Tooltip": "URL für den Download der Rechnung",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Produktname",
|
||||
"Result": "Ergebnis",
|
||||
"Return to Website": "Zurück zur Website",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "Die Zahlung ist fehlgeschlagen",
|
||||
"The payment is still under processing": "Die Zahlung wird immer noch bearbeitet",
|
||||
"Type - Tooltip": "Zahlungsmethode, die beim Kauf des Produkts verwendet wurde",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Zugriffsschlüssel",
|
||||
"Agent ID": "Agenten-ID",
|
||||
"Agent ID - Tooltip": "Agenten-ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "App ID",
|
||||
"App ID - Tooltip": "App-ID",
|
||||
"App key": "App-Key",
|
||||
"App key - Tooltip": "App-Schlüssel",
|
||||
"App secret": "App-Secret",
|
||||
"AppSecret - Tooltip": "App-Geheimnis",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "Auth-URL",
|
||||
"Auth URL - Tooltip": "Auth-URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Bucket",
|
||||
"Bucket - Tooltip": "Name des Buckets",
|
||||
"Can not parse metadata": "Kann Metadaten nicht durchsuchen / auswerten",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Ob das Scannen von QR-Codes zum Einloggen aktiviert werden soll",
|
||||
"Endpoint": "Endpoint",
|
||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Bitte verwenden Sie WeChat und scanne den QR-Code ein, um dich anzumelden",
|
||||
"Port": "Port",
|
||||
"Port - Tooltip": "Stellen Sie sicher, dass der Port offen ist",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "ausgelöst",
|
||||
"Provider URL": "Provider-URL",
|
||||
"Provider URL - Tooltip": "URL zur Konfiguration des Dienstanbieters, dieses Feld dient nur als Referenz und wird in Casdoor nicht verwendet",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Regions-ID",
|
||||
"Region ID - Tooltip": "Regions-ID für den Dienstleister",
|
||||
"Region endpoint for Internet": "Regionsendpunkt für das Internet",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Vom Server verwendet, um die API des Verifizierungscodes-Providers für die Verifizierung aufzurufen",
|
||||
"Send Testing Email": "Senden Sie eine Test-E-Mail",
|
||||
"Send Testing SMS": "Sende Test-SMS",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Signatur Namen",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Fehlermeldung",
|
||||
"Error text - Tooltip": "Fehler Text",
|
||||
"Is hashed": "ist gehasht",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "Neuer Syncer",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Table name of the policy store",
|
||||
"Adapters": "Adapters",
|
||||
"Add": "Add",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "Affiliation URL",
|
||||
"Affiliation URL - Tooltip": "The homepage URL for the affiliation",
|
||||
"Application": "Application",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Applications",
|
||||
"Applications that require authentication": "Applications that require authentication",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Public avatar image for the user",
|
||||
"Back": "Back",
|
||||
"Back Home": "Back Home",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Cancel",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Cert",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Home page of the application",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Unique random string",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Available languages",
|
||||
"Last name": "Last name",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icons that the application presents to the outside world",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "User",
|
||||
"User - Tooltip": "Make sure the username is correct",
|
||||
"User Management": "User Management",
|
||||
"User containers": "User pools",
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Like USD, CNY, etc.",
|
||||
"Download Invoice": "Download Invoice",
|
||||
"Edit Payment": "Edit Payment",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individual",
|
||||
"Invoice URL": "Invoice URL",
|
||||
"Invoice URL - Tooltip": "URL for downloading the invoice",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Product Name",
|
||||
"Result": "Result",
|
||||
"Return to Website": "Return to Website",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "The payment has failed",
|
||||
"The payment is still under processing": "The payment is still under processing",
|
||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Access key",
|
||||
"Agent ID": "Agent ID",
|
||||
"Agent ID - Tooltip": "Agent ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "App ID",
|
||||
"App ID - Tooltip": "App ID",
|
||||
"App key": "App key",
|
||||
"App key - Tooltip": "App key",
|
||||
"App secret": "App secret",
|
||||
"AppSecret - Tooltip": "App secret",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "Auth URL",
|
||||
"Auth URL - Tooltip": "Auth URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Bucket",
|
||||
"Bucket - Tooltip": "Name of bucket",
|
||||
"Can not parse metadata": "Can not parse metadata",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Whether to allow scanning QR code to login",
|
||||
"Endpoint": "Endpoint",
|
||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "Email address of \"From\"",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Please use WeChat and scan the QR code to sign in",
|
||||
"Port": "Port",
|
||||
"Port - Tooltip": "Make sure the port is open",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Prompted",
|
||||
"Provider URL": "Provider URL",
|
||||
"Provider URL - Tooltip": "URL for configuring the service provider, this field is only used for reference and is not used in Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Region ID",
|
||||
"Region ID - Tooltip": "Region ID for the service provider",
|
||||
"Region endpoint for Internet": "Region endpoint for Internet",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Used by the server to call the verification code provider API for verification",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Sign Name",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Error text",
|
||||
"Error text - Tooltip": "Error text",
|
||||
"Is hashed": "Is hashed",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "New Syncer",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Nombre de la tabla de la tienda de políticas",
|
||||
"Adapters": "Adaptadores",
|
||||
"Add": "Añadir",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "URL de afiliación",
|
||||
"Affiliation URL - Tooltip": "La URL de la página de inicio para la afiliación",
|
||||
"Application": "Aplicación",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Aplicaciones",
|
||||
"Applications that require authentication": "Aplicaciones que requieren autenticación",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Imagen de avatar pública para el usuario",
|
||||
"Back": "Back",
|
||||
"Back Home": "Regreso a casa",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Cancelar",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "ificado",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Página de inicio de la aplicación",
|
||||
"ID": "identificación",
|
||||
"ID - Tooltip": "Cadena aleatoria única",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Está habilitado",
|
||||
"Is enabled - Tooltip": "Establecer si se puede usar",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Idiomas disponibles",
|
||||
"Last name": "Apellido",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logotipo",
|
||||
"Logo - Tooltip": "Iconos que la aplicación presenta al mundo exterior",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "Usuario",
|
||||
"User - Tooltip": "Asegúrate de que el nombre de usuario sea correcto",
|
||||
"User Management": "User Management",
|
||||
"User containers": "Piscinas de usuarios",
|
||||
"User type": "Tipo de usuario",
|
||||
"User type - Tooltip": "Etiquetas a las que el usuario pertenece, con una configuración predeterminada en \"usuario-normal\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Como USD, CNY, etc.",
|
||||
"Download Invoice": "Descargar factura",
|
||||
"Edit Payment": "Editar pago",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individuo",
|
||||
"Invoice URL": "URL de factura",
|
||||
"Invoice URL - Tooltip": "URL para descargar la factura",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Nombre del producto",
|
||||
"Result": "Resultado",
|
||||
"Return to Website": "Regresar al sitio web",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "El pago ha fallado",
|
||||
"The payment is still under processing": "El pago aún está en proceso",
|
||||
"Type - Tooltip": "Método de pago utilizado al comprar el producto",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Clave de acceso",
|
||||
"Agent ID": "Identificador de agente",
|
||||
"Agent ID - Tooltip": "Identificador de agente",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "ID de aplicación",
|
||||
"App ID - Tooltip": "Identificador de la aplicación",
|
||||
"App key": "Clave de aplicación",
|
||||
"App key - Tooltip": "Clave de aplicación",
|
||||
"App secret": "Secreto de la aplicación",
|
||||
"AppSecret - Tooltip": "Secreto de aplicación",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "URL de autenticación",
|
||||
"Auth URL - Tooltip": "URL de autenticación",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Cubo",
|
||||
"Bucket - Tooltip": "Nombre del balde",
|
||||
"Can not parse metadata": "No se puede analizar los metadatos",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Si permitir el escaneo de códigos QR para acceder",
|
||||
"Endpoint": "Punto final",
|
||||
"Endpoint (Intranet)": "Punto final (intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Por favor, utiliza WeChat y escanea el código QR para iniciar sesión",
|
||||
"Port": "Puerto",
|
||||
"Port - Tooltip": "Asegúrate de que el puerto esté abierto",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Estimulado",
|
||||
"Provider URL": "URL del proveedor",
|
||||
"Provider URL - Tooltip": "Dirección URL para configurar el proveedor de servicios, este campo sólo se utiliza como referencia y no se utiliza en Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "ID de región",
|
||||
"Region ID - Tooltip": "Identificación de región para el proveedor de servicios",
|
||||
"Region endpoint for Internet": "Punto final de la región para Internet",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Utilizado por el servidor para llamar a la API del proveedor de códigos de verificación para verificar",
|
||||
"Send Testing Email": "Enviar correo electrónico de prueba",
|
||||
"Send Testing SMS": "Enviar SMS de prueba",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Firma de Nombre",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Texto de error",
|
||||
"Error text - Tooltip": "Texto de error",
|
||||
"Is hashed": "Está encriptado",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "Nuevo Syncer",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Nom de la table du magasin de politique",
|
||||
"Adapters": "Adaptateurs",
|
||||
"Add": "Ajouter",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "URL d'affiliation",
|
||||
"Affiliation URL - Tooltip": "La URL de la page d'accueil pour l'affiliation",
|
||||
"Application": "Application",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Applications",
|
||||
"Applications that require authentication": "Applications qui nécessitent une authentification",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Image d'avatar public pour l'utilisateur",
|
||||
"Back": "Back",
|
||||
"Back Home": "Retour à la maison",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Annuler",
|
||||
"Captcha": "Captcha (prononcé « kæptʃə » en anglais) est un acronyme qui signifie « Completely Automated Public Turing test to tell Computers and Humans Apart ». En français, le terme est souvent traduit par « test de Turing complètement automatisé et public pour différencier les ordinateurs et les humains ». Le système est utilisé pour empêcher les spammeurs, les robots et les logiciels malveillants d'accéder aux sites Web en leur demandant de résoudre une tâche de reconnaissance de caractères ou d'images, qui peut être difficile pour les machines à comprendre mais facile pour les humains",
|
||||
"Cert": "ainement",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Page d'accueil de l'application",
|
||||
"ID": "Identité",
|
||||
"ID - Tooltip": "Chaîne unique aléatoire",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Est activé",
|
||||
"Is enabled - Tooltip": "Définir s'il peut être utilisé",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Langues disponibles",
|
||||
"Last name": "Nom de famille",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icônes que l'application présente au monde extérieur",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "Utilisateur",
|
||||
"User - Tooltip": "Assurez-vous que le nom d'utilisateur est correct",
|
||||
"User Management": "User Management",
|
||||
"User containers": "Piscines d'utilisateurs",
|
||||
"User type": "Type d'utilisateur",
|
||||
"User type - Tooltip": "Balises auxquelles l'utilisateur appartient, avec une valeur par défaut \"utilisateur-normal\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Comme USD, CNY, etc.",
|
||||
"Download Invoice": "Télécharger la facture",
|
||||
"Edit Payment": "Modifier le paiement",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individu",
|
||||
"Invoice URL": "URL de facture",
|
||||
"Invoice URL - Tooltip": "URL pour télécharger la facture",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Nom du produit",
|
||||
"Result": "Résultat",
|
||||
"Return to Website": "Retourner sur le site web",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "Le paiement a échoué",
|
||||
"The payment is still under processing": "Le paiement est encore en cours de traitement",
|
||||
"Type - Tooltip": "Méthode de paiement utilisée lors de l'achat du produit",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Clé d'accès",
|
||||
"Agent ID": "Identifiant d'agent",
|
||||
"Agent ID - Tooltip": "Identifiant d'agent",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "Identifiant d'application",
|
||||
"App ID - Tooltip": "Identifiant d'application",
|
||||
"App key": "Clé d'application",
|
||||
"App key - Tooltip": "Clé d'application",
|
||||
"App secret": "Secret d'application",
|
||||
"AppSecret - Tooltip": "Secret de l'application",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "URL d'authentification",
|
||||
"Auth URL - Tooltip": "URL d'authentification",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "seau",
|
||||
"Bucket - Tooltip": "Nom du seau",
|
||||
"Can not parse metadata": "Impossible d'analyser les métadonnées",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Doit-on autoriser la numérisation de QR code pour se connecter ?",
|
||||
"Endpoint": "Point final",
|
||||
"Endpoint (Intranet)": "Point final (intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Veuillez utiliser WeChat et scanner le code QR pour vous connecter",
|
||||
"Port": "Port",
|
||||
"Port - Tooltip": "Assurez-vous que le port est ouvert",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Incité",
|
||||
"Provider URL": "URL du fournisseur",
|
||||
"Provider URL - Tooltip": "URL pour configurer le fournisseur de services, ce champ est uniquement utilisé à titre de référence et n'est pas utilisé dans Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Identifiant de région",
|
||||
"Region ID - Tooltip": "Identifiant de région pour le fournisseur de services",
|
||||
"Region endpoint for Internet": "Point de terminaison de région pour Internet",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Utilisé par le serveur pour appeler l'API du fournisseur de code de vérification pour vérifier",
|
||||
"Send Testing Email": "Envoyer un e-mail de test",
|
||||
"Send Testing SMS": "Envoyer des messages SMS de tests",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Nom de signature",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Texte d'erreur",
|
||||
"Error text - Tooltip": "Texte d'erreur",
|
||||
"Is hashed": "Est-haché",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "Nouveau synchroniseur",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Nama tabel dari penyimpanan kebijakan",
|
||||
"Adapters": "Adaptor",
|
||||
"Add": "Tambahkan",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "URL Afiliasi",
|
||||
"Affiliation URL - Tooltip": "URL halaman depan untuk afiliasi",
|
||||
"Application": "Aplikasi",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Aplikasi",
|
||||
"Applications that require authentication": "Aplikasi yang memerlukan autentikasi",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Gambar avatar publik untuk pengguna",
|
||||
"Back": "Back",
|
||||
"Back Home": "Kembali ke Rumah",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Membatalkan",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Sertifikat",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Halaman utama aplikasi",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Karakter acak unik",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Diaktifkan",
|
||||
"Is enabled - Tooltip": "Atur apakah itu dapat digunakan",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Bahasa yang tersedia",
|
||||
"Last name": "Nama belakang",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Ikon-ikon yang disajikan aplikasi ke dunia luar",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "Pengguna",
|
||||
"User - Tooltip": "Pastikan username-nya benar",
|
||||
"User Management": "User Management",
|
||||
"User containers": "User pools",
|
||||
"User type": "Jenis pengguna",
|
||||
"User type - Tooltip": "Tag yang dimiliki oleh pengguna, defaultnya adalah \"normal-user\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Seperti USD, CNY, dll.",
|
||||
"Download Invoice": "Unduh Faktur",
|
||||
"Edit Payment": "Edit Pembayaran",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individu",
|
||||
"Invoice URL": "URL Faktur",
|
||||
"Invoice URL - Tooltip": "URL untuk mengunduh faktur",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Nama Produk",
|
||||
"Result": "Hasil",
|
||||
"Return to Website": "Kembali ke Situs Web",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "Pembayaran gagal",
|
||||
"The payment is still under processing": "Pembayaran masih dalam proses",
|
||||
"Type - Tooltip": "Metode pembayaran yang digunakan saat membeli produk",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Kunci akses",
|
||||
"Agent ID": "ID agen",
|
||||
"Agent ID - Tooltip": "ID Agen",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "ID Aplikasi",
|
||||
"App ID - Tooltip": "ID Aplikasi",
|
||||
"App key": "Kunci aplikasi",
|
||||
"App key - Tooltip": "Kunci aplikasi",
|
||||
"App secret": "Rahasia aplikasi",
|
||||
"AppSecret - Tooltip": "Rahasia aplikasi",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "URL Otorisasi",
|
||||
"Auth URL - Tooltip": "URL terautentikasi",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Ember",
|
||||
"Bucket - Tooltip": "Nama ember",
|
||||
"Can not parse metadata": "Tidak dapat mengurai metadata",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Apakah diizinkan untuk memindai kode QR untuk masuk?",
|
||||
"Endpoint": "Titik akhir",
|
||||
"Endpoint (Intranet)": "Titik Akhir (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Silakan gunakan WeChat dan pindai kode QR untuk masuk",
|
||||
"Port": "Pelabuhan",
|
||||
"Port - Tooltip": "Pastikan port terbuka",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Mendorong",
|
||||
"Provider URL": "URL penyedia",
|
||||
"Provider URL - Tooltip": "URL untuk melakukan konfigurasi service provider, kolom ini hanya digunakan sebagai referensi dan tidak digunakan dalam Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Daerah ID",
|
||||
"Region ID - Tooltip": "Daerah ID untuk penyedia layanan",
|
||||
"Region endpoint for Internet": "Titik akhir wilayah untuk Internet",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Digunakan oleh server untuk memanggil API penyedia kode verifikasi untuk melakukan verifikasi",
|
||||
"Send Testing Email": "Kirim Email Uji Coba",
|
||||
"Send Testing SMS": "Kirim SMS Uji Coba",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Tanda Tangan",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Teks kesalahan",
|
||||
"Error text - Tooltip": "Teks kesalahan",
|
||||
"Is hashed": "Apakah di-hash?",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "Sinkronisasi Baru",
|
||||
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"account": {
|
||||
"Chats & Messages": "Chats & Messages",
|
||||
"Logout": "Logout",
|
||||
"My Account": "My Account",
|
||||
"Sign Up": "Sign Up"
|
||||
@ -127,19 +126,6 @@
|
||||
"Scope - Tooltip": "Usage scenarios of the certificate",
|
||||
"Type - Tooltip": "Type of certificate"
|
||||
},
|
||||
"chat": {
|
||||
"AI": "AI",
|
||||
"Edit Chat": "Edit Chat",
|
||||
"Group": "Group",
|
||||
"Message count": "Message count",
|
||||
"New Chat": "New Chat",
|
||||
"Single": "Single",
|
||||
"User1": "User1",
|
||||
"User1 - Tooltip": "User1 - Tooltip",
|
||||
"User2": "User2",
|
||||
"User2 - Tooltip": "User2 - Tooltip",
|
||||
"Users - Tooltip": "Users - Tooltip"
|
||||
},
|
||||
"code": {
|
||||
"Code you received": "Code you received",
|
||||
"Email code": "Email code",
|
||||
@ -179,22 +165,24 @@
|
||||
"Adapter - Tooltip": "Table name of the policy store",
|
||||
"Adapters": "Adapters",
|
||||
"Add": "Add",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "Affiliation URL",
|
||||
"Affiliation URL - Tooltip": "The homepage URL for the affiliation",
|
||||
"Application": "Application",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Applications",
|
||||
"Applications that require authentication": "Applications that require authentication",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Public avatar image for the user",
|
||||
"Back": "Back",
|
||||
"Back Home": "Back Home",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Cancel",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Cert",
|
||||
"Cert - Tooltip": "The public key certificate that needs to be verified by the client SDK corresponding to this application",
|
||||
"Certs": "Certs",
|
||||
"Chats": "Chats",
|
||||
"Click to Upload": "Click to Upload",
|
||||
"Client IP": "Client IP",
|
||||
"Close": "Close",
|
||||
@ -224,7 +212,6 @@
|
||||
"Failed to connect to server": "Failed to connect to server",
|
||||
"Failed to delete": "Failed to delete",
|
||||
"Failed to enable": "Failed to enable",
|
||||
"Failed to get answer": "Failed to get answer",
|
||||
"Failed to remove": "Failed to remove",
|
||||
"Failed to save": "Failed to save",
|
||||
"Failed to verify": "Failed to verify",
|
||||
@ -242,6 +229,7 @@
|
||||
"Home - Tooltip": "Home page of the application",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Unique random string",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -250,6 +238,7 @@
|
||||
"Languages - Tooltip": "Available languages",
|
||||
"Last name": "Last name",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icons that the application presents to the outside world",
|
||||
"MFA items": "MFA items",
|
||||
@ -257,7 +246,6 @@
|
||||
"Master password": "Master password",
|
||||
"Master password - Tooltip": "Can be used to log in to all users under this organization, making it convenient for administrators to log in as this user to solve technical issues",
|
||||
"Menu": "Menu",
|
||||
"Messages": "Messages",
|
||||
"Method": "Method",
|
||||
"Model": "Model",
|
||||
"Model - Tooltip": "Casbin access control model",
|
||||
@ -344,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "User",
|
||||
"User - Tooltip": "Make sure the username is correct",
|
||||
"User Management": "User Management",
|
||||
"User containers": "User pools",
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
@ -425,16 +414,6 @@
|
||||
"sign up now": "sign up now",
|
||||
"username, Email or phone": "username, Email or phone"
|
||||
},
|
||||
"message": {
|
||||
"Author": "Author",
|
||||
"Author - Tooltip": "Author - Tooltip",
|
||||
"Chat": "Chat",
|
||||
"Chat - Tooltip": "Chat - Tooltip",
|
||||
"Edit Message": "Edit Message",
|
||||
"New Message": "New Message",
|
||||
"Text": "Text",
|
||||
"Text - Tooltip": "Text - Tooltip"
|
||||
},
|
||||
"mfa": {
|
||||
"Each time you sign in to your Account, you'll need your password and a authentication code": "Each time you sign in to your Account, you'll need your password and a authentication code",
|
||||
"Enable multi-factor authentication": "Enable multi-factor authentication",
|
||||
@ -508,6 +487,7 @@
|
||||
"Currency - Tooltip": "Like USD, CNY, etc.",
|
||||
"Download Invoice": "Download Invoice",
|
||||
"Edit Payment": "Edit Payment",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individual",
|
||||
"Invoice URL": "Invoice URL",
|
||||
"Invoice URL - Tooltip": "URL for downloading the invoice",
|
||||
@ -541,6 +521,7 @@
|
||||
"Product - Tooltip": "Product Name",
|
||||
"Result": "Result",
|
||||
"Return to Website": "Return to Website",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "The payment has failed",
|
||||
"The payment is still under processing": "The payment is still under processing",
|
||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||
@ -635,14 +616,20 @@
|
||||
"Access key - Tooltip": "Access key",
|
||||
"Agent ID": "Agent ID",
|
||||
"Agent ID - Tooltip": "Agent ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "App ID",
|
||||
"App ID - Tooltip": "App ID",
|
||||
"App key": "App key",
|
||||
"App key - Tooltip": "App key",
|
||||
"App secret": "App secret",
|
||||
"AppSecret - Tooltip": "App secret",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "Auth URL",
|
||||
"Auth URL - Tooltip": "Auth URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Bucket",
|
||||
"Bucket - Tooltip": "Name of bucket",
|
||||
"Can not parse metadata": "Can not parse metadata",
|
||||
@ -676,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Whether to allow scanning QR code to login",
|
||||
"Endpoint": "Endpoint",
|
||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "Email address of \"From\"",
|
||||
"From name": "From name",
|
||||
@ -701,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Please use WeChat and scan the QR code to sign in",
|
||||
"Port": "Port",
|
||||
"Port - Tooltip": "Make sure the port is open",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Prompted",
|
||||
"Provider URL": "Provider URL",
|
||||
"Provider URL - Tooltip": "URL for configuring the service provider, this field is only used for reference and is not used in Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Region ID",
|
||||
"Region ID - Tooltip": "Region ID for the service provider",
|
||||
"Region endpoint for Internet": "Region endpoint for Internet",
|
||||
@ -728,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Used by the server to call the verification code provider API for verification",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Sign Name",
|
||||
@ -842,6 +840,7 @@
|
||||
"Error text": "Error text",
|
||||
"Error text - Tooltip": "Error text",
|
||||
"Is hashed": "Is hashed",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "New Syncer",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "ポリシー・ストアのテーブル名",
|
||||
"Adapters": "アダプター",
|
||||
"Add": "追加",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "所属するURL",
|
||||
"Affiliation URL - Tooltip": "所属先のホームページURL",
|
||||
"Application": "アプリケーション",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "アプリケーション",
|
||||
"Applications that require authentication": "認証が必要なアプリケーション",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "アバター",
|
||||
"Avatar - Tooltip": "ユーザーのパブリックアバター画像",
|
||||
"Back": "Back",
|
||||
"Back Home": "帰宅",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "キャンセルします",
|
||||
"Captcha": "キャプチャ",
|
||||
"Cert": "証明書",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "アプリケーションのホームページ",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "ユニークなランダム文字列",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "可能になっています",
|
||||
"Is enabled - Tooltip": "使用可能かどうかを設定してください",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "利用可能な言語",
|
||||
"Last name": "苗字",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "ロゴ",
|
||||
"Logo - Tooltip": "アプリケーションが外部世界に示すアイコン",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "ユーザー",
|
||||
"User - Tooltip": "ユーザー名が正しいことを確認してください",
|
||||
"User Management": "User Management",
|
||||
"User containers": "ユーザープール",
|
||||
"User type": "ユーザータイプ",
|
||||
"User type - Tooltip": "ユーザーが属するタグは、デフォルトでは「通常ユーザー」となります",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "米ドル、人民元など。",
|
||||
"Download Invoice": "請求書のダウンロード",
|
||||
"Edit Payment": "支払い編集",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "個人",
|
||||
"Invoice URL": "請求書のURL",
|
||||
"Invoice URL - Tooltip": "請求書のダウンロード用のURL",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "製品名",
|
||||
"Result": "結果",
|
||||
"Return to Website": "ウェブサイトに戻る",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "支払いに失敗しました",
|
||||
"The payment is still under processing": "支払いはまだ処理中です",
|
||||
"Type - Tooltip": "製品を購入する際に使用される支払方法",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "アクセスキー",
|
||||
"Agent ID": "エージェントID",
|
||||
"Agent ID - Tooltip": "エージェントID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "アプリID",
|
||||
"App ID - Tooltip": "アプリID",
|
||||
"App key": "アプリキー",
|
||||
"App key - Tooltip": "アプリキー",
|
||||
"App secret": "アプリの秘密鍵",
|
||||
"AppSecret - Tooltip": "アプリの秘密鍵",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "認証URL",
|
||||
"Auth URL - Tooltip": "認証URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "バケツ",
|
||||
"Bucket - Tooltip": "バケットの名前",
|
||||
"Can not parse metadata": "メタデータを解析できません",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "ログインするためにQRコードをスキャンすることを許可するかどうか",
|
||||
"Endpoint": "エンドポイント",
|
||||
"Endpoint (Intranet)": "エンドポイント(イントラネット)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "WeChatを使用し、QRコードをスキャンしてサインインしてください",
|
||||
"Port": "ポート",
|
||||
"Port - Tooltip": "ポートが開いていることを確認してください",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "促された",
|
||||
"Provider URL": "プロバイダーURL",
|
||||
"Provider URL - Tooltip": "サービスプロバイダーの設定用URL。このフィールドは参照用にのみ使用され、Casdoorでは使用されません",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "地域ID",
|
||||
"Region ID - Tooltip": "サービスプロバイダの地域ID",
|
||||
"Region endpoint for Internet": "インターネットのリージョンエンドポイント",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "認証のためにサーバーによって使用され、認証コードプロバイダAPIを呼び出すためのもの",
|
||||
"Send Testing Email": "テスト用メールを送信する",
|
||||
"Send Testing SMS": "テストSMSを送信してください",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "署名",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "エラーテキスト",
|
||||
"Error text - Tooltip": "エラーテキスト",
|
||||
"Is hashed": "ハッシュ化されました",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "新しいシンクロナイザー",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "정책 저장소의 테이블 이름",
|
||||
"Adapters": "어댑터",
|
||||
"Add": "추가하다",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "소속 URL",
|
||||
"Affiliation URL - Tooltip": "소속 홈페이지 URL",
|
||||
"Application": "응용 프로그램",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "응용 프로그램",
|
||||
"Applications that require authentication": "인증이 필요한 애플리케이션들",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "아바타",
|
||||
"Avatar - Tooltip": "사용자를 위한 공개 아바타 이미지",
|
||||
"Back": "Back",
|
||||
"Back Home": "집으로 돌아오기",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "취소",
|
||||
"Captcha": "캡차",
|
||||
"Cert": "인증서",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "어플리케이션 홈 페이지",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "유일한 랜덤 문자열",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "활성화됩니다",
|
||||
"Is enabled - Tooltip": "사용 가능한 지 여부를 설정하세요",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "사용 가능한 언어",
|
||||
"Last name": "성",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "로고",
|
||||
"Logo - Tooltip": "애플리케이션이 외부 세계에 제시하는 아이콘들",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "사용자",
|
||||
"User - Tooltip": "사용자 이름이 정확한지 확인하세요",
|
||||
"User Management": "User Management",
|
||||
"User containers": "사용자 풀",
|
||||
"User type": "사용자 유형",
|
||||
"User type - Tooltip": "사용자가 속한 태그는 기본적으로 \"보통 사용자\"로 설정됩니다",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "USD, CNY 등과 같이.",
|
||||
"Download Invoice": "인보이스 다운로드",
|
||||
"Edit Payment": "결제 수정",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "개인",
|
||||
"Invoice URL": "송장 URL",
|
||||
"Invoice URL - Tooltip": "송장 다운로드를 위한 URL",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "제품 이름",
|
||||
"Result": "결과",
|
||||
"Return to Website": "웹 사이트로 돌아가기",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "결제가 실패했습니다",
|
||||
"The payment is still under processing": "지불은 아직 처리 중입니다",
|
||||
"Type - Tooltip": "제품을 구매할 때 사용되는 결제 방법",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "액세스 키",
|
||||
"Agent ID": "에이전트 ID",
|
||||
"Agent ID - Tooltip": "에이전트 ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "앱 ID",
|
||||
"App ID - Tooltip": "앱 식별자",
|
||||
"App key": "앱 키",
|
||||
"App key - Tooltip": "앱 키",
|
||||
"App secret": "앱 비밀키",
|
||||
"AppSecret - Tooltip": "앱 비밀번호",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "인증 URL",
|
||||
"Auth URL - Tooltip": "인증 URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "양동이",
|
||||
"Bucket - Tooltip": "양동이의 이름",
|
||||
"Can not parse metadata": "메타데이터를 구문 분석할 수 없습니다",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "QR 코드를 스캔해서 로그인할 수 있는지 여부",
|
||||
"Endpoint": "엔드포인트",
|
||||
"Endpoint (Intranet)": "엔드포인트 (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "WeChat를 사용하시고 QR 코드를 스캔하여 로그인해주세요",
|
||||
"Port": "포트",
|
||||
"Port - Tooltip": "포트가 열려 있는지 확인하세요",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "자극 받은",
|
||||
"Provider URL": "제공자 URL",
|
||||
"Provider URL - Tooltip": "서비스 제공 업체 구성을 위한 URL이며, 이 필드는 참조 용도로만 사용되며 Casdoor에서 사용되지 않습니다",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "지역 ID",
|
||||
"Region ID - Tooltip": "서비스 제공업체의 지역 ID",
|
||||
"Region endpoint for Internet": "인터넷 지역 엔드포인트",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "검증을 위해 서버에서 인증 코드 공급자 API를 호출하는 데 사용됩니다",
|
||||
"Send Testing Email": "테스트 이메일을 보내기",
|
||||
"Send Testing SMS": "테스트 SMS를 보내세요",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "신명서",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "오류 메시지",
|
||||
"Error text - Tooltip": "에러 텍스트",
|
||||
"Is hashed": "해시화 되었습니다",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "신규 싱크어",
|
||||
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"account": {
|
||||
"Chats & Messages": "Chats & Messages",
|
||||
"Logout": "Logout",
|
||||
"My Account": "My Account",
|
||||
"Sign Up": "Sign Up"
|
||||
@ -127,19 +126,6 @@
|
||||
"Scope - Tooltip": "Usage scenarios of the certificate",
|
||||
"Type - Tooltip": "Type of certificate"
|
||||
},
|
||||
"chat": {
|
||||
"AI": "AI",
|
||||
"Edit Chat": "Edit Chat",
|
||||
"Group": "Group",
|
||||
"Message count": "Message count",
|
||||
"New Chat": "New Chat",
|
||||
"Single": "Single",
|
||||
"User1": "User1",
|
||||
"User1 - Tooltip": "User1 - Tooltip",
|
||||
"User2": "User2",
|
||||
"User2 - Tooltip": "User2 - Tooltip",
|
||||
"Users - Tooltip": "Users - Tooltip"
|
||||
},
|
||||
"code": {
|
||||
"Code you received": "Code you received",
|
||||
"Email code": "Email code",
|
||||
@ -179,22 +165,24 @@
|
||||
"Adapter - Tooltip": "Table name of the policy store",
|
||||
"Adapters": "Adapters",
|
||||
"Add": "Add",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "Affiliation URL",
|
||||
"Affiliation URL - Tooltip": "The homepage URL for the affiliation",
|
||||
"Application": "Application",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Applications",
|
||||
"Applications that require authentication": "Applications that require authentication",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Public avatar image for the user",
|
||||
"Back": "Back",
|
||||
"Back Home": "Back Home",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Cancel",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Cert",
|
||||
"Cert - Tooltip": "The public key certificate that needs to be verified by the client SDK corresponding to this application",
|
||||
"Certs": "Certs",
|
||||
"Chats": "Chats",
|
||||
"Click to Upload": "Click to Upload",
|
||||
"Client IP": "Client IP",
|
||||
"Close": "Close",
|
||||
@ -224,7 +212,6 @@
|
||||
"Failed to connect to server": "Failed to connect to server",
|
||||
"Failed to delete": "Failed to delete",
|
||||
"Failed to enable": "Failed to enable",
|
||||
"Failed to get answer": "Failed to get answer",
|
||||
"Failed to remove": "Failed to remove",
|
||||
"Failed to save": "Failed to save",
|
||||
"Failed to verify": "Failed to verify",
|
||||
@ -242,6 +229,7 @@
|
||||
"Home - Tooltip": "Home page of the application",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Unique random string",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -250,6 +238,7 @@
|
||||
"Languages - Tooltip": "Available languages",
|
||||
"Last name": "Last name",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icons that the application presents to the outside world",
|
||||
"MFA items": "MFA items",
|
||||
@ -257,7 +246,6 @@
|
||||
"Master password": "Master password",
|
||||
"Master password - Tooltip": "Can be used to log in to all users under this organization, making it convenient for administrators to log in as this user to solve technical issues",
|
||||
"Menu": "Menu",
|
||||
"Messages": "Messages",
|
||||
"Method": "Method",
|
||||
"Model": "Model",
|
||||
"Model - Tooltip": "Casbin access control model",
|
||||
@ -344,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "User",
|
||||
"User - Tooltip": "Make sure the username is correct",
|
||||
"User Management": "User Management",
|
||||
"User containers": "User pools",
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
@ -425,16 +414,6 @@
|
||||
"sign up now": "sign up now",
|
||||
"username, Email or phone": "username, Email or phone"
|
||||
},
|
||||
"message": {
|
||||
"Author": "Author",
|
||||
"Author - Tooltip": "Author - Tooltip",
|
||||
"Chat": "Chat",
|
||||
"Chat - Tooltip": "Chat - Tooltip",
|
||||
"Edit Message": "Edit Message",
|
||||
"New Message": "New Message",
|
||||
"Text": "Text",
|
||||
"Text - Tooltip": "Text - Tooltip"
|
||||
},
|
||||
"mfa": {
|
||||
"Each time you sign in to your Account, you'll need your password and a authentication code": "Each time you sign in to your Account, you'll need your password and a authentication code",
|
||||
"Enable multi-factor authentication": "Enable multi-factor authentication",
|
||||
@ -508,6 +487,7 @@
|
||||
"Currency - Tooltip": "Like USD, CNY, etc.",
|
||||
"Download Invoice": "Download Invoice",
|
||||
"Edit Payment": "Edit Payment",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individual",
|
||||
"Invoice URL": "Invoice URL",
|
||||
"Invoice URL - Tooltip": "URL for downloading the invoice",
|
||||
@ -541,6 +521,7 @@
|
||||
"Product - Tooltip": "Product Name",
|
||||
"Result": "Result",
|
||||
"Return to Website": "Return to Website",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "The payment has failed",
|
||||
"The payment is still under processing": "The payment is still under processing",
|
||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||
@ -635,14 +616,20 @@
|
||||
"Access key - Tooltip": "Access key",
|
||||
"Agent ID": "Agent ID",
|
||||
"Agent ID - Tooltip": "Agent ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "App ID",
|
||||
"App ID - Tooltip": "App ID",
|
||||
"App key": "App key",
|
||||
"App key - Tooltip": "App key",
|
||||
"App secret": "App secret",
|
||||
"AppSecret - Tooltip": "App secret",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "Auth URL",
|
||||
"Auth URL - Tooltip": "Auth URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Bucket",
|
||||
"Bucket - Tooltip": "Name of bucket",
|
||||
"Can not parse metadata": "Can not parse metadata",
|
||||
@ -676,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Whether to allow scanning QR code to login",
|
||||
"Endpoint": "Endpoint",
|
||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "Email address of \"From\"",
|
||||
"From name": "From name",
|
||||
@ -701,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Please use WeChat and scan the QR code to sign in",
|
||||
"Port": "Port",
|
||||
"Port - Tooltip": "Make sure the port is open",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Prompted",
|
||||
"Provider URL": "Provider URL",
|
||||
"Provider URL - Tooltip": "URL for configuring the service provider, this field is only used for reference and is not used in Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Region ID",
|
||||
"Region ID - Tooltip": "Region ID for the service provider",
|
||||
"Region endpoint for Internet": "Region endpoint for Internet",
|
||||
@ -728,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Used by the server to call the verification code provider API for verification",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Sign Name",
|
||||
@ -842,6 +840,7 @@
|
||||
"Error text": "Error text",
|
||||
"Error text - Tooltip": "Error text",
|
||||
"Is hashed": "Is hashed",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "New Syncer",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Nome da tabela do armazenamento de políticas",
|
||||
"Adapters": "Adaptadores",
|
||||
"Add": "Adicionar",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "URL da Afiliação",
|
||||
"Affiliation URL - Tooltip": "A URL da página inicial para a afiliação",
|
||||
"Application": "Aplicação",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Aplicações",
|
||||
"Applications that require authentication": "Aplicações que requerem autenticação",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Imagem de avatar pública do usuário",
|
||||
"Back": "Voltar",
|
||||
"Back Home": "Voltar para a Página Inicial",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Cancelar",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Certificado",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Página inicial do aplicativo",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "String única aleatória",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Está habilitado",
|
||||
"Is enabled - Tooltip": "Define se está habilitado",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Idiomas disponíveis",
|
||||
"Last name": "Sobrenome",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Ícones que o aplicativo apresenta para o mundo externo",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Hora de Atualização",
|
||||
"User": "Usuário",
|
||||
"User - Tooltip": "Certifique-se de que o nome de usuário esteja correto",
|
||||
"User Management": "User Management",
|
||||
"User containers": "Pools de Usuários",
|
||||
"User type": "Tipo de Usuário",
|
||||
"User type - Tooltip": "Tags às quais o usuário pertence, com valor padrão de \"usuário-normal\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Como USD, CNY, etc.",
|
||||
"Download Invoice": "Baixar Fatura",
|
||||
"Edit Payment": "Editar Pagamento",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individual",
|
||||
"Invoice URL": "URL da Fatura",
|
||||
"Invoice URL - Tooltip": "URL para baixar a fatura",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Nome do Produto",
|
||||
"Result": "Resultado",
|
||||
"Return to Website": "Retornar ao Website",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "O pagamento falhou",
|
||||
"The payment is still under processing": "O pagamento ainda está sendo processado",
|
||||
"Type - Tooltip": "Método de pagamento utilizado ao comprar o produto",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Chave de acesso",
|
||||
"Agent ID": "ID do Agente",
|
||||
"Agent ID - Tooltip": "ID do Agente",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "ID do aplicativo",
|
||||
"App ID - Tooltip": "ID do aplicativo",
|
||||
"App key": "Chave do aplicativo",
|
||||
"App key - Tooltip": "Chave do aplicativo",
|
||||
"App secret": "Segredo do aplicativo",
|
||||
"AppSecret - Tooltip": "Segredo do aplicativo",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "URL de autenticação",
|
||||
"Auth URL - Tooltip": "URL de autenticação",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Bucket",
|
||||
"Bucket - Tooltip": "Nome do bucket",
|
||||
"Can not parse metadata": "Não é possível analisar metadados",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Se permite escanear código QR para fazer login",
|
||||
"Endpoint": "Endpoint",
|
||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "Endereço do remetente",
|
||||
"From address - Tooltip": "Endereço de e-mail do remetente",
|
||||
"From name": "Nome do remetente",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Por favor, use o WeChat e escaneie o código QR para fazer login",
|
||||
"Port": "Porta",
|
||||
"Port - Tooltip": "Certifique-se de que a porta esteja aberta",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Solicitado",
|
||||
"Provider URL": "URL do Provedor",
|
||||
"Provider URL - Tooltip": "URL para configurar o provedor de serviço, este campo é apenas usado para referência e não é usado no Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "ID da Região",
|
||||
"Region ID - Tooltip": "ID da região para o provedor de serviços",
|
||||
"Region endpoint for Internet": "Endpoint da região para a Internet",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Usada pelo servidor para chamar a API do fornecedor de código de verificação para verificação",
|
||||
"Send Testing Email": "Enviar E-mail de Teste",
|
||||
"Send Testing SMS": "Enviar SMS de Teste",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Nome do Sinal",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Texto de erro",
|
||||
"Error text - Tooltip": "Texto de erro",
|
||||
"Is hashed": "Está criptografado",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "Novo Syncer",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Имя таблицы хранилища политик",
|
||||
"Adapters": "Адаптеры",
|
||||
"Add": "Добавить",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "URL принадлежности",
|
||||
"Affiliation URL - Tooltip": "URL домашней страницы для аффилированности",
|
||||
"Application": "Приложение",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Приложения",
|
||||
"Applications that require authentication": "Приложения, которые требуют аутентификации",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Аватар",
|
||||
"Avatar - Tooltip": "Публичное изображение аватара пользователя",
|
||||
"Back": "Back",
|
||||
"Back Home": "Домой",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Отменить",
|
||||
"Captcha": "Капча",
|
||||
"Cert": "Сертификат",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Главная страница приложения",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Уникальная случайная строка",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Включен",
|
||||
"Is enabled - Tooltip": "Установить, может ли использоваться",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Доступные языки",
|
||||
"Last name": "Фамилия",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Логотип",
|
||||
"Logo - Tooltip": "Иконки, которые приложение представляет во внешний мир",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "Пользователь",
|
||||
"User - Tooltip": "Убедитесь, что имя пользователя правильное",
|
||||
"User Management": "User Management",
|
||||
"User containers": "Пользовательские пулы",
|
||||
"User type": "Тип пользователя",
|
||||
"User type - Tooltip": "Теги, к которым принадлежит пользователь, по умолчанию \"обычный пользователь\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Как и USD, CNY и т.д.",
|
||||
"Download Invoice": "Загрузить счет-фактуру",
|
||||
"Edit Payment": "Редактировать оплату",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Индивидуальный",
|
||||
"Invoice URL": "URL счета-фактуры",
|
||||
"Invoice URL - Tooltip": "URL для загрузки счета-фактуры",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Название продукта",
|
||||
"Result": "Результат",
|
||||
"Return to Website": "Вернуться на веб-сайт",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "Оплата не удалась",
|
||||
"The payment is still under processing": "Оплата все еще обрабатывается",
|
||||
"Type - Tooltip": "Способ оплаты, используемый при покупке товара",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Ключ доступа",
|
||||
"Agent ID": "Идентификатор агента",
|
||||
"Agent ID - Tooltip": "Агент ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "Идентификатор приложения",
|
||||
"App ID - Tooltip": "Идентификатор приложения",
|
||||
"App key": "Ключ приложения",
|
||||
"App key - Tooltip": "Ключ приложения",
|
||||
"App secret": "Секрет приложения",
|
||||
"AppSecret - Tooltip": "Секрет приложения",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "Адрес авторизации",
|
||||
"Auth URL - Tooltip": "URL авторизации",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Ведро",
|
||||
"Bucket - Tooltip": "Название ведра",
|
||||
"Can not parse metadata": "Невозможно проанализировать метаданные",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Разрешить ли сканирование QR-кода для входа в систему",
|
||||
"Endpoint": "Конечная точка",
|
||||
"Endpoint (Intranet)": "Конечная точка (интранет)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Пожалуйста, используйте WeChat и отсканируйте QR-код для входа в систему",
|
||||
"Port": "Порт",
|
||||
"Port - Tooltip": "Убедитесь, что порт открыт",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Побудил",
|
||||
"Provider URL": "URL поставщика",
|
||||
"Provider URL - Tooltip": "URL для настройки поставщика услуг, это поле используется только для ссылки и не используется в Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Идентификатор региона",
|
||||
"Region ID - Tooltip": "Идентификатор региона для провайдера услуг",
|
||||
"Region endpoint for Internet": "Региональный конечная точка для Интернета",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Используется сервером для вызова API-интерфейса поставщика кода подтверждения для проверки",
|
||||
"Send Testing Email": "Отправить тестовое письмо",
|
||||
"Send Testing SMS": "Отправить тестовое SMS-сообщение",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Подпись имени",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Текст ошибки",
|
||||
"Error text - Tooltip": "Текст ошибки",
|
||||
"Is hashed": "Хешировано",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "Новый синхронизатор",
|
||||
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"account": {
|
||||
"Chats & Messages": "Chats & Messages",
|
||||
"Logout": "Logout",
|
||||
"My Account": "My Account",
|
||||
"Sign Up": "Sign Up"
|
||||
@ -127,19 +126,6 @@
|
||||
"Scope - Tooltip": "Usage scenarios of the certificate",
|
||||
"Type - Tooltip": "Type of certificate"
|
||||
},
|
||||
"chat": {
|
||||
"AI": "AI",
|
||||
"Edit Chat": "Edit Chat",
|
||||
"Group": "Group",
|
||||
"Message count": "Message count",
|
||||
"New Chat": "New Chat",
|
||||
"Single": "Single",
|
||||
"User1": "User1",
|
||||
"User1 - Tooltip": "User1 - Tooltip",
|
||||
"User2": "User2",
|
||||
"User2 - Tooltip": "User2 - Tooltip",
|
||||
"Users - Tooltip": "Users - Tooltip"
|
||||
},
|
||||
"code": {
|
||||
"Code you received": "Code you received",
|
||||
"Email code": "Email code",
|
||||
@ -179,22 +165,24 @@
|
||||
"Adapter - Tooltip": "Table name of the policy store",
|
||||
"Adapters": "Adapters",
|
||||
"Add": "Add",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "Affiliation URL",
|
||||
"Affiliation URL - Tooltip": "The homepage URL for the affiliation",
|
||||
"Application": "Application",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Applications",
|
||||
"Applications that require authentication": "Applications that require authentication",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Avatar",
|
||||
"Avatar - Tooltip": "Public avatar image for the user",
|
||||
"Back": "Back",
|
||||
"Back Home": "Back Home",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Cancel",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Cert",
|
||||
"Cert - Tooltip": "The public key certificate that needs to be verified by the client SDK corresponding to this application",
|
||||
"Certs": "Certs",
|
||||
"Chats": "Chats",
|
||||
"Click to Upload": "Click to Upload",
|
||||
"Client IP": "Client IP",
|
||||
"Close": "Close",
|
||||
@ -224,7 +212,6 @@
|
||||
"Failed to connect to server": "Failed to connect to server",
|
||||
"Failed to delete": "Failed to delete",
|
||||
"Failed to enable": "Failed to enable",
|
||||
"Failed to get answer": "Failed to get answer",
|
||||
"Failed to remove": "Failed to remove",
|
||||
"Failed to save": "Failed to save",
|
||||
"Failed to verify": "Failed to verify",
|
||||
@ -242,6 +229,7 @@
|
||||
"Home - Tooltip": "Home page of the application",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Unique random string",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Is enabled",
|
||||
"Is enabled - Tooltip": "Set whether it can use",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -250,6 +238,7 @@
|
||||
"Languages - Tooltip": "Available languages",
|
||||
"Last name": "Last name",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icons that the application presents to the outside world",
|
||||
"MFA items": "MFA items",
|
||||
@ -257,7 +246,6 @@
|
||||
"Master password": "Master password",
|
||||
"Master password - Tooltip": "Can be used to log in to all users under this organization, making it convenient for administrators to log in as this user to solve technical issues",
|
||||
"Menu": "Menu",
|
||||
"Messages": "Messages",
|
||||
"Method": "Method",
|
||||
"Model": "Model",
|
||||
"Model - Tooltip": "Casbin access control model",
|
||||
@ -344,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "User",
|
||||
"User - Tooltip": "Make sure the username is correct",
|
||||
"User Management": "User Management",
|
||||
"User containers": "User pools",
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
@ -425,16 +414,6 @@
|
||||
"sign up now": "sign up now",
|
||||
"username, Email or phone": "username, Email or phone"
|
||||
},
|
||||
"message": {
|
||||
"Author": "Author",
|
||||
"Author - Tooltip": "Author - Tooltip",
|
||||
"Chat": "Chat",
|
||||
"Chat - Tooltip": "Chat - Tooltip",
|
||||
"Edit Message": "Edit Message",
|
||||
"New Message": "New Message",
|
||||
"Text": "Text",
|
||||
"Text - Tooltip": "Text - Tooltip"
|
||||
},
|
||||
"mfa": {
|
||||
"Each time you sign in to your Account, you'll need your password and a authentication code": "Each time you sign in to your Account, you'll need your password and a authentication code",
|
||||
"Enable multi-factor authentication": "Enable multi-factor authentication",
|
||||
@ -508,6 +487,7 @@
|
||||
"Currency - Tooltip": "Like USD, CNY, etc.",
|
||||
"Download Invoice": "Download Invoice",
|
||||
"Edit Payment": "Edit Payment",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Individual",
|
||||
"Invoice URL": "Invoice URL",
|
||||
"Invoice URL - Tooltip": "URL for downloading the invoice",
|
||||
@ -541,6 +521,7 @@
|
||||
"Product - Tooltip": "Product Name",
|
||||
"Result": "Result",
|
||||
"Return to Website": "Return to Website",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "The payment has failed",
|
||||
"The payment is still under processing": "The payment is still under processing",
|
||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||
@ -635,14 +616,20 @@
|
||||
"Access key - Tooltip": "Access key",
|
||||
"Agent ID": "Agent ID",
|
||||
"Agent ID - Tooltip": "Agent ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "App ID",
|
||||
"App ID - Tooltip": "App ID",
|
||||
"App key": "App key",
|
||||
"App key - Tooltip": "App key",
|
||||
"App secret": "App secret",
|
||||
"AppSecret - Tooltip": "App secret",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "Auth URL",
|
||||
"Auth URL - Tooltip": "Auth URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Bucket",
|
||||
"Bucket - Tooltip": "Name of bucket",
|
||||
"Can not parse metadata": "Can not parse metadata",
|
||||
@ -676,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Whether to allow scanning QR code to login",
|
||||
"Endpoint": "Endpoint",
|
||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "Email address of \"From\"",
|
||||
"From name": "From name",
|
||||
@ -701,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Please use WeChat and scan the QR code to sign in",
|
||||
"Port": "Port",
|
||||
"Port - Tooltip": "Make sure the port is open",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Prompted",
|
||||
"Provider URL": "Provider URL",
|
||||
"Provider URL - Tooltip": "URL for configuring the service provider, this field is only used for reference and is not used in Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Region ID",
|
||||
"Region ID - Tooltip": "Region ID for the service provider",
|
||||
"Region endpoint for Internet": "Region endpoint for Internet",
|
||||
@ -728,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Used by the server to call the verification code provider API for verification",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Sign Name",
|
||||
@ -842,6 +840,7 @@
|
||||
"Error text": "Error text",
|
||||
"Error text - Tooltip": "Error text",
|
||||
"Is hashed": "Is hashed",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "New Syncer",
|
||||
|
@ -165,16 +165,19 @@
|
||||
"Adapter - Tooltip": "Tên bảng của kho lưu trữ chính sách",
|
||||
"Adapters": "Bộ chuyển đổi",
|
||||
"Add": "Thêm vào",
|
||||
"Admin": "Admin",
|
||||
"Affiliation URL": "Đường dẫn liên kết liên kết",
|
||||
"Affiliation URL - Tooltip": "Đường dẫn URL trang chủ của liên kết",
|
||||
"Application": "Ứng dụng",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "Ứng dụng",
|
||||
"Applications that require authentication": "Các ứng dụng yêu cầu xác thực",
|
||||
"Authorization": "Authorization",
|
||||
"Avatar": "Ảnh đại diện",
|
||||
"Avatar - Tooltip": "Ảnh đại diện công khai cho người dùng",
|
||||
"Back": "Back",
|
||||
"Back Home": "Trở về nhà",
|
||||
"Business & Payments": "Business & Payments",
|
||||
"Cancel": "Hủy bỏ",
|
||||
"Captcha": "Captcha",
|
||||
"Cert": "Chứng chỉ",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "Trang chủ của ứng dụng",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "Chuỗi ngẫu nhiên độc nhất",
|
||||
"Identity": "Identity",
|
||||
"Is enabled": "Đã được kích hoạt",
|
||||
"Is enabled - Tooltip": "Đặt liệu nó có thể sử dụng hay không",
|
||||
"LDAPs": "LDAPs",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "Các ngôn ngữ hiện có",
|
||||
"Last name": "Họ",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Biểu tượng mà ứng dụng hiển thị ra ngoài thế giới",
|
||||
"MFA items": "MFA items",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "Updated time",
|
||||
"User": "Người dùng",
|
||||
"User - Tooltip": "Hãy đảm bảo tên đăng nhập chính xác",
|
||||
"User Management": "User Management",
|
||||
"User containers": "Nhóm người dùng",
|
||||
"User type": "Loại người dùng",
|
||||
"User type - Tooltip": "Các thẻ mà người dùng thuộc vào, mặc định là \"người dùng bình thường\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "Như USD, CNY, v.v.",
|
||||
"Download Invoice": "Tải hóa đơn",
|
||||
"Edit Payment": "Chỉnh sửa thanh toán",
|
||||
"Failed reason": "Failed reason",
|
||||
"Individual": "Cá nhân",
|
||||
"Invoice URL": "Đường link hoá đơn",
|
||||
"Invoice URL - Tooltip": "Đường link để tải hóa đơn xuống",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "Tên sản phẩm",
|
||||
"Result": "Kết quả",
|
||||
"Return to Website": "Trở lại trang web",
|
||||
"The payment has been canceled": "The payment has been canceled",
|
||||
"The payment has failed": "Thanh toán đã thất bại",
|
||||
"The payment is still under processing": "Thanh toán vẫn đang được xử lý",
|
||||
"Type - Tooltip": "Phương thức thanh toán được sử dụng khi mua sản phẩm",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Khóa truy cập",
|
||||
"Agent ID": "Mã đại lý",
|
||||
"Agent ID - Tooltip": "Mã đại lý",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "ID ứng dụng",
|
||||
"App ID - Tooltip": "Định danh ứng dụng",
|
||||
"App key": "Khóa ứng dụng",
|
||||
"App key - Tooltip": "Khóa ứng dụng",
|
||||
"App secret": "Mã bí mật ứng dụng",
|
||||
"AppSecret - Tooltip": "Bí mật ứng dụng",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "URL xác thực",
|
||||
"Auth URL - Tooltip": "URL chứng thực",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "Thùng đựng nước",
|
||||
"Bucket - Tooltip": "Tên của cái xô",
|
||||
"Can not parse metadata": "Không thể phân tích siêu dữ liệu",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "Cho phép quét mã QR để đăng nhập",
|
||||
"Endpoint": "Điểm cuối",
|
||||
"Endpoint (Intranet)": "Điểm kết thúc (mạng nội bộ)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "From address",
|
||||
"From address - Tooltip": "From address - Tooltip",
|
||||
"From name": "From name",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "Vui lòng sử dụng WeChat và quét mã QR để đăng nhập",
|
||||
"Port": "Cảng",
|
||||
"Port - Tooltip": "Chắc chắn rằng cổng đang mở",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "Thúc đẩy",
|
||||
"Provider URL": "Địa chỉ URL nhà cung cấp",
|
||||
"Provider URL - Tooltip": "URL để cấu hình nhà cung cấp dịch vụ, trường này chỉ được sử dụng để tham khảo và không được sử dụng trong Casdoor",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "Định danh khu vực",
|
||||
"Region ID - Tooltip": "Định danh khu vực cho nhà cung cấp dịch vụ",
|
||||
"Region endpoint for Internet": "Điểm cuối khu vực cho Internet",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "Được sử dụng bởi máy chủ để gọi API nhà cung cấp mã xác minh để xác minh",
|
||||
"Send Testing Email": "Gửi Email kiểm tra",
|
||||
"Send Testing SMS": "Gửi SMS kiểm tra",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "Ký tên",
|
||||
@ -815,6 +840,7 @@
|
||||
"Error text": "Văn bản lỗi",
|
||||
"Error text - Tooltip": "Văn bản lỗi",
|
||||
"Is hashed": "Đã được băm mã hóa",
|
||||
"Is key": "Is key",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "New Syncer: Đồng bộ mới",
|
||||
|
@ -139,8 +139,8 @@
|
||||
"Submit and complete": "完成提交"
|
||||
},
|
||||
"enforcer": {
|
||||
"Edit Enforcer": "Edit Enforcer",
|
||||
"New Enforcer": "New Enforcer"
|
||||
"Edit Enforcer": "编辑Casbin执行器",
|
||||
"New Enforcer": "新建Casbin执行器"
|
||||
},
|
||||
"forget": {
|
||||
"Account": "账号",
|
||||
@ -163,18 +163,21 @@
|
||||
"Action": "操作",
|
||||
"Adapter": "适配器",
|
||||
"Adapter - Tooltip": "策略存储的表名",
|
||||
"Adapters": "适配器",
|
||||
"Adapters": "Casbin适配器",
|
||||
"Add": "添加",
|
||||
"Admin": "管理工具",
|
||||
"Affiliation URL": "工作单位URL",
|
||||
"Affiliation URL - Tooltip": "工作单位的官网URL",
|
||||
"Application": "应用",
|
||||
"Application - Tooltip": "Application - Tooltip",
|
||||
"Applications": "应用",
|
||||
"Applications that require authentication": "需要认证和鉴权的应用",
|
||||
"Authorization": "Casbin权限管理",
|
||||
"Avatar": "头像",
|
||||
"Avatar - Tooltip": "公开展示的用户头像",
|
||||
"Back": "返回",
|
||||
"Back Home": "返回到首页",
|
||||
"Business & Payments": "商业 & 付款",
|
||||
"Cancel": "取消",
|
||||
"Captcha": "人机验证码",
|
||||
"Cert": "证书",
|
||||
@ -204,7 +207,7 @@
|
||||
"Enable": "启用",
|
||||
"Enabled": "已开启",
|
||||
"Enabled successfully": "启用成功",
|
||||
"Enforcers": "Enforcers",
|
||||
"Enforcers": "Casbin执行器",
|
||||
"Failed to add": "添加失败",
|
||||
"Failed to connect to server": "连接服务器失败",
|
||||
"Failed to delete": "删除失败",
|
||||
@ -226,6 +229,7 @@
|
||||
"Home - Tooltip": "应用的首页",
|
||||
"ID": "ID",
|
||||
"ID - Tooltip": "唯一的随机字符串",
|
||||
"Identity": "身份认证",
|
||||
"Is enabled": "已启用",
|
||||
"Is enabled - Tooltip": "是否启用",
|
||||
"LDAPs": "LDAP",
|
||||
@ -234,6 +238,7 @@
|
||||
"Languages - Tooltip": "可选语言",
|
||||
"Last name": "姓氏",
|
||||
"Later": "稍后",
|
||||
"Logging & Auditing": "日志 & 审计",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "应用程序向外展示的图标",
|
||||
"MFA items": "MFA 项",
|
||||
@ -244,7 +249,7 @@
|
||||
"Method": "方法",
|
||||
"Model": "模型",
|
||||
"Model - Tooltip": "Casbin的访问控制模型",
|
||||
"Models": "模型",
|
||||
"Models": "Casbin模型",
|
||||
"Name": "名称",
|
||||
"Name - Tooltip": "唯一的、字符串式的ID",
|
||||
"None": "无",
|
||||
@ -327,6 +332,7 @@
|
||||
"Updated time": "更新时间",
|
||||
"User": "用户",
|
||||
"User - Tooltip": "请确保用户名正确",
|
||||
"User Management": "用户管理",
|
||||
"User containers": "用户池",
|
||||
"User type": "用户类型",
|
||||
"User type - Tooltip": "用户所属的标签,默认为\"normal-user\"",
|
||||
@ -481,6 +487,7 @@
|
||||
"Currency - Tooltip": "如USD(美元),CNY(人民币)等",
|
||||
"Download Invoice": "下载发票",
|
||||
"Edit Payment": "编辑付款",
|
||||
"Failed reason": "失败原因",
|
||||
"Individual": "个人",
|
||||
"Invoice URL": "发票URL",
|
||||
"Invoice URL - Tooltip": "发票的下载地址URL",
|
||||
@ -514,6 +521,7 @@
|
||||
"Product - Tooltip": "商品名称",
|
||||
"Result": "结果",
|
||||
"Return to Website": "返回原网站",
|
||||
"The payment has been canceled": "付款已取消",
|
||||
"The payment has failed": "支付失败",
|
||||
"The payment is still under processing": "支付正在处理",
|
||||
"Type - Tooltip": "商品购买时的支付方式",
|
||||
@ -608,14 +616,20 @@
|
||||
"Access key - Tooltip": "Access key",
|
||||
"Agent ID": "Agent ID",
|
||||
"Agent ID - Tooltip": "Agent ID",
|
||||
"Api Key": "Api Key",
|
||||
"Api Key - Tooltip": "Api Key - Tooltip",
|
||||
"App ID": "App ID",
|
||||
"App ID - Tooltip": "App ID",
|
||||
"App key": "App key",
|
||||
"App key - Tooltip": "App key",
|
||||
"App secret": "App secret",
|
||||
"AppSecret - Tooltip": "App secret",
|
||||
"Auth Key": "Auth Key",
|
||||
"Auth Key - Tooltip": "Auth Key - Tooltip",
|
||||
"Auth URL": "Auth URL",
|
||||
"Auth URL - Tooltip": "Auth URL",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL - Tooltip",
|
||||
"Bucket": "存储桶",
|
||||
"Bucket - Tooltip": "Bucket名称",
|
||||
"Can not parse metadata": "无法解析元数据",
|
||||
@ -649,6 +663,7 @@
|
||||
"Enable QR code - Tooltip": "是否允许扫描二维码登录",
|
||||
"Endpoint": "地域节点 (外网)",
|
||||
"Endpoint (Intranet)": "地域节点 (内网)",
|
||||
"Endpoint - Tooltip": "Endpoint - Tooltip",
|
||||
"From address": "发件人地址",
|
||||
"From address - Tooltip": "邮件里发件人的邮箱地址",
|
||||
"From name": "发件人名称",
|
||||
@ -674,9 +689,17 @@
|
||||
"Please use WeChat and scan the QR code to sign in": "请使用微信扫描二维码登录",
|
||||
"Port": "端口",
|
||||
"Port - Tooltip": "请确保端口号打开",
|
||||
"Private Key": "Private Key",
|
||||
"Private Key - Tooltip": "Private Key - Tooltip",
|
||||
"Project Id": "Project Id",
|
||||
"Project Id - Tooltip": "Project Id - Tooltip",
|
||||
"Prompted": "注册后提醒绑定",
|
||||
"Provider URL": "提供商URL",
|
||||
"Provider URL - Tooltip": "提供商网址配置对应的URL,该字段仅用来方便跳转,在Casdoor平台中未使用",
|
||||
"Public key": "Public key",
|
||||
"Public key - Tooltip": "Public key - Tooltip",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Region - Tooltip",
|
||||
"Region ID": "地域ID",
|
||||
"Region ID - Tooltip": "提供商服务所属的地域ID",
|
||||
"Region endpoint for Internet": "地域节点 (外网)",
|
||||
@ -701,6 +724,8 @@
|
||||
"Secret key - Tooltip": "用于服务端调用验证码提供商API进行验证",
|
||||
"Send Testing Email": "发送测试邮件",
|
||||
"Send Testing SMS": "发送测试短信",
|
||||
"Sender Id": "Sender Id",
|
||||
"Sender Id - Tooltip": "Sender Id - Tooltip",
|
||||
"Sender number": "Sender number",
|
||||
"Sender number - Tooltip": "Sender number - Tooltip",
|
||||
"Sign Name": "签名名称",
|
||||
@ -815,7 +840,8 @@
|
||||
"Error text": "错误信息",
|
||||
"Error text - Tooltip": "错误信息",
|
||||
"Is hashed": "是否参与哈希计算",
|
||||
"Is read-only": "Is read-only",
|
||||
"Is key": "是否为主键",
|
||||
"Is read-only": "是否只读",
|
||||
"Is read-only - Tooltip": "Is read-only - Tooltip",
|
||||
"New Syncer": "添加同步器",
|
||||
"Sync interval": "同步间隔",
|
||||
|
@ -33,11 +33,11 @@ class PolicyTable extends React.Component {
|
||||
}
|
||||
|
||||
count = 0;
|
||||
pageSize = 10;
|
||||
pageSize = 100;
|
||||
|
||||
getIndex(index) {
|
||||
// Need to be used in all place when modify table. Parameter is the row index in table, need to calculate the index in dataSource.
|
||||
return index + (this.state.page - 1) * 10;
|
||||
return index + (this.state.page - 1) * this.pageSize;
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
@ -165,7 +165,7 @@ class PolicyTable extends React.Component {
|
||||
renderTable(table) {
|
||||
const columns = [
|
||||
{
|
||||
title: "Rule Type",
|
||||
title: i18next.t("adapter:Rule type"),
|
||||
dataIndex: "Ptype",
|
||||
width: "100px",
|
||||
// render: (text, record, index) => {
|
||||
@ -270,8 +270,9 @@ class PolicyTable extends React.Component {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Option",
|
||||
key: "option",
|
||||
title: i18next.t("general:Action"),
|
||||
dataIndex: "",
|
||||
key: "op",
|
||||
width: "100px",
|
||||
render: (text, record, index) => {
|
||||
const editable = this.isEditing(index);
|
||||
@ -304,7 +305,6 @@ class PolicyTable extends React.Component {
|
||||
onChange: (page) => this.setState({
|
||||
page: page,
|
||||
}),
|
||||
disabled: this.state.editingIndex !== "" || Setting.builtInObject({owner: this.props.owner, name: this.props.name}),
|
||||
current: this.state.page,
|
||||
}}
|
||||
columns={columns} dataSource={table} rowKey="key" size="middle" bordered
|
||||
|
2449
web/yarn.lock
2449
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user