Compare commits

...

32 Commits

Author SHA1 Message Date
131820e34e feat: add application.ForcedRedirectOrigin 2025-03-24 13:42:35 +08:00
2fcbf7cf6c feat: fix apps page grid style (#3679) 2025-03-22 18:19:14 +08:00
14ade8b7e4 feat: fix provider test API's missing owner and name args for auth (#3676) 2025-03-22 17:53:20 +08:00
a11fe59704 feat: support widget items config in org (#3674) 2025-03-21 23:00:07 +08:00
af55d0547f feat: improve frontend i18n strings 2025-03-21 21:03:29 +08:00
81102f8298 feat: fix permission update bug when both org and model are modified (#3671) 2025-03-20 09:05:27 +08:00
141372cb86 feat: support face ID provider (#3666) 2025-03-19 22:57:35 +08:00
15a037ca74 feat: increase frontend build memory to 4096 in Dockerfile (#3672)
297.8 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
2025-03-19 10:40:34 +08:00
73c680d56f feat: avoid using body in GET requests for AirwallexClient payment provider (#3669) 2025-03-18 20:04:15 +08:00
aafc16e4f4 feat: fix dynamic width of navbar UI (#3664) 2025-03-16 16:12:58 +08:00
7be026dd1f feat: Support for selecting existing users or scanning a QR code when logging into Dingtalk (#3660) 2025-03-13 21:49:07 +08:00
3e7938e5f6 feat: don't panic when provider not found in Login() API (#3659) 2025-03-13 21:35:51 +08:00
30789138e2 feat: fix faceId loop error caused by async (#3651) 2025-03-11 21:03:04 +08:00
9610ce5b8c feat: can add faceId by uploading images (#3641) 2025-03-09 01:29:25 +08:00
a39a311d2f feat: fix webhook bug in RecordEx JSON (#3642) 2025-03-08 00:20:59 +08:00
08e41ab762 feat: can specify user fields in webhook edit page (#3635) 2025-03-04 14:16:16 +08:00
85ca318e2f feat: can assign default group during signup (#3633) 2025-03-02 22:55:51 +08:00
9032865e60 feat: support mobile background for login page (#3629) 2025-03-01 23:01:15 +08:00
5692522ee0 feat: update user language when the language changed on login page (#3628) 2025-03-01 22:28:20 +08:00
cb1882e589 feat: fix MFA bug, revert PR: "feat: don't send verification code if failed signin limit is reached" (#3627) 2025-03-01 12:58:28 +08:00
41d9422687 feat: increase username limit to 255 chars 2025-03-01 00:44:34 +08:00
3297db688b feat: support shared cert in GetCert() API 2025-02-28 23:02:13 +08:00
cc82d292f0 feat: set frontend origin to 7001 if in dev mode (#3615) 2025-02-26 22:35:50 +08:00
f2e3037bc5 feat: don't send verification code if failed signin limit is reached (#3616) 2025-02-26 22:34:14 +08:00
d986a4a9e0 feat: fix bug that initialize group children as empty array instead of empty string (#3620) 2025-02-26 08:50:09 +08:00
2df3878c15 feat: fix bug that group.HaveChildren is never set to false bug Something isn't working (#3609) 2025-02-22 01:46:35 +08:00
24ab8880cc feat: fix bug that organization might be nil in some case and cause nil point error (#3608) 2025-02-21 23:43:30 +08:00
f26b4853c5 feat: bump Go version to go 1.18 (#3599) 2025-02-21 13:10:17 +08:00
d78e8e9776 feat: fix LDAP filter condition will return nil if error happened (#3604) 2025-02-21 13:09:39 +08:00
d61f9a1856 feat: update antd from 5.2.3 to 5.24.1 (#3593) 2025-02-18 20:54:10 +08:00
aa52af02b3 feat: fix style props of Editor (#3590) 2025-02-17 13:39:49 +08:00
2a5722e45b feat: add detail sidebar for record list page, improve token list page (#3589) 2025-02-16 22:01:25 +08:00
112 changed files with 3135 additions and 2922 deletions

View File

@ -1,7 +1,7 @@
FROM --platform=$BUILDPLATFORM node:18.19.0 AS FRONT
WORKDIR /web
COPY ./web .
RUN yarn install --frozen-lockfile --network-timeout 1000000 && yarn run build
RUN yarn install --frozen-lockfile --network-timeout 1000000 && NODE_OPTIONS="--max-old-space-size=4096" yarn run build
FROM --platform=$BUILDPLATFORM golang:1.20.12 AS BACK

View File

@ -249,6 +249,10 @@ func (c *ApiController) Signup() {
user.Groups = []string{invitation.SignupGroup}
}
if application.DefaultGroup != "" && user.Groups == nil {
user.Groups = []string{application.DefaultGroup}
}
affected, err := object.AddUser(user)
if err != nil {
c.ResponseError(err.Error())

View File

@ -29,6 +29,7 @@ import (
"github.com/casdoor/casdoor/captcha"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/form"
"github.com/casdoor/casdoor/i18n"
"github.com/casdoor/casdoor/idp"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/proxy"
@ -402,11 +403,27 @@ func (c *ApiController) Login() {
return
}
if err := object.CheckFaceId(user, authForm.FaceId, c.GetAcceptLanguage()); err != nil {
c.ResponseError(err.Error(), nil)
return
faceIdProvider, err := object.GetFaceIdProviderByApplication(util.GetId(application.Owner, application.Name), "false", c.GetAcceptLanguage())
if err != nil {
c.ResponseError(err.Error())
}
if faceIdProvider == nil {
if err := object.CheckFaceId(user, authForm.FaceId, c.GetAcceptLanguage()); err != nil {
c.ResponseError(err.Error(), nil)
return
}
} else {
ok, err := user.CheckUserFace(authForm.FaceIdImage, faceIdProvider)
if err != nil {
c.ResponseError(err.Error(), nil)
}
if !ok {
c.ResponseError(i18n.Translate(c.GetAcceptLanguage(), "check:Face data does not exist, cannot log in"))
return
}
}
} else if authForm.Password == "" {
if user, err = object.GetUserByFields(authForm.Organization, authForm.Username); err != nil {
c.ResponseError(err.Error(), nil)
@ -598,6 +615,9 @@ func (c *ApiController) Login() {
c.ResponseError(err.Error())
return
}
if provider == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The provider: %s does not exist"), authForm.Provider))
}
providerItem := application.GetProviderItem(provider.Name)
if !providerItem.IsProviderVisible() {
@ -986,6 +1006,18 @@ func (c *ApiController) Login() {
}
}
if authForm.Language != "" {
user := c.getCurrentUser()
if user != nil {
user.Language = authForm.Language
_, err = object.UpdateUser(user.GetId(), user, []string{"language"}, user.IsAdmin)
if err != nil {
c.ResponseError(err.Error())
return
}
}
}
c.Data["json"] = resp
c.ServeJSON()
}

81
faceId/aliyun.go Normal file
View File

@ -0,0 +1,81 @@
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package faceId
import (
"strings"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
facebody20191230 "github.com/alibabacloud-go/facebody-20191230/v5/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
)
type AliyunFaceIdProvider struct {
AccessKey string
AccessSecret string
Endpoint string
QualityScoreThreshold float32
}
func NewAliyunFaceIdProvider(accessKey string, accessSecret string, endPoint string) *AliyunFaceIdProvider {
return &AliyunFaceIdProvider{
AccessKey: accessKey,
AccessSecret: accessSecret,
Endpoint: endPoint,
QualityScoreThreshold: 0.65,
}
}
func (provider *AliyunFaceIdProvider) Check(base64ImageA string, base64ImageB string) (bool, error) {
config := openapi.Config{
AccessKeyId: tea.String(provider.AccessKey),
AccessKeySecret: tea.String(provider.AccessSecret),
}
config.Endpoint = tea.String(provider.Endpoint)
client, err := facebody20191230.NewClient(&config)
if err != nil {
return false, err
}
compareFaceRequest := &facebody20191230.CompareFaceRequest{
QualityScoreThreshold: tea.Float32(provider.QualityScoreThreshold),
ImageDataA: tea.String(strings.Replace(base64ImageA, "data:image/png;base64,", "", -1)),
ImageDataB: tea.String(strings.Replace(base64ImageB, "data:image/png;base64,", "", -1)),
}
runtime := &util.RuntimeOptions{}
defer func() {
if r := tea.Recover(recover()); r != nil {
err = r
}
}()
result, err := client.CompareFaceWithOptions(compareFaceRequest, runtime)
if err != nil {
return false, err
}
if result == nil {
return false, nil
}
if *result.Body.Data.Thresholds[0] < *result.Body.Data.Confidence {
return true, nil
}
return false, nil
}

23
faceId/provider.go Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package faceId
type FaceIdProvider interface {
Check(base64ImageA string, base64ImageB string) (bool, error)
}
func GetFaceIdProvider(typ string, clientId string, clientSecret string, endPoint string) FaceIdProvider {
return NewAliyunFaceIdProvider(clientId, clientSecret, endPoint)
}

View File

@ -34,6 +34,7 @@ type AuthForm struct {
Phone string `json:"phone"`
Affiliation string `json:"affiliation"`
IdCard string `json:"idCard"`
Language string `json:"language"`
Region string `json:"region"`
InvitationCode string `json:"invitationCode"`
@ -67,7 +68,8 @@ type AuthForm struct {
Plan string `json:"plan"`
Pricing string `json:"pricing"`
FaceId []float64 `json:"faceId"`
FaceId []float64 `json:"faceId"`
FaceIdImage []string `json:"faceIdImage"`
}
func GetAuthFormFieldValue(form *AuthForm, fieldName string) (bool, string) {

189
go.mod
View File

@ -1,10 +1,14 @@
module github.com/casdoor/casdoor
go 1.16
go 1.18
require (
github.com/Masterminds/squirrel v1.5.3
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.4
github.com/alibabacloud-go/facebody-20191230/v5 v5.1.2
github.com/alibabacloud-go/tea v1.3.2
github.com/alibabacloud-go/tea-utils/v2 v2.0.7
github.com/aws/aws-sdk-go v1.45.5
github.com/beego/beego v1.12.12
github.com/beevik/etree v1.1.0
@ -18,7 +22,6 @@ require (
github.com/casvisor/casvisor-go-sdk v1.4.0
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
github.com/denisenkom/go-mssqldb v0.9.0
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
github.com/elimity-com/scim v0.0.0-20230426070224-941a5eac92f3
github.com/fogleman/gg v1.3.0
github.com/go-asn1-ber/asn1-ber v1.5.5
@ -46,7 +49,6 @@ require (
github.com/russellhaering/gosaml2 v0.9.0
github.com/russellhaering/goxmldsig v1.2.0
github.com/sendgrid/sendgrid-go v3.14.0+incompatible
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
@ -54,20 +56,193 @@ require (
github.com/stripe/stripe-go/v74 v74.29.0
github.com/tealeg/xlsx v1.0.5
github.com/thanhpk/randstr v1.0.4
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/xorm-io/builder v0.3.13
github.com/xorm-io/core v0.7.4
github.com/xorm-io/xorm v1.1.6
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.32.0
golang.org/x/net v0.34.0
golang.org/x/oauth2 v0.17.0
golang.org/x/text v0.21.0
google.golang.org/api v0.150.0
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0
layeh.com/radius v0.0.0-20221205141417-e7fbddd11d68
maunium.net/go/mautrix v0.16.0
modernc.org/sqlite v1.18.2
)
require (
cloud.google.com/go v0.110.8 // indirect
cloud.google.com/go/compute v1.23.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.3 // indirect
cloud.google.com/go/storage v1.35.1 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
github.com/Azure/azure-storage-blob-go v0.15.0 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20221121042443-a3fd332d56d9 // indirect
github.com/SherClockHolmes/webpush-go v1.2.0 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
github.com/alibabacloud-go/darabonba-number v1.0.4 // indirect
github.com/alibabacloud-go/debug v1.0.1 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 // indirect
github.com/alibabacloud-go/tea-fileform v1.1.1 // indirect
github.com/alibabacloud-go/tea-oss-sdk v1.1.3 // indirect
github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect
github.com/alibabacloud-go/tea-utils v1.3.6 // indirect
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.62.545 // indirect
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible // indirect
github.com/aliyun/credentials-go v1.3.10 // indirect
github.com/apistd/uni-go-sdk v0.0.2 // indirect
github.com/atc0005/go-teams-notify/v2 v2.6.1 // indirect
github.com/baidubce/bce-sdk-go v0.9.156 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blinkbean/dingtalk v0.0.0-20210905093040-7d935c0f7e19 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/bwmarrin/discordgo v0.27.1 // indirect
github.com/casdoor/casdoor-go-sdk v0.50.0 // indirect
github.com/casdoor/go-reddit/v2 v2.1.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/dghubble/oauth1 v0.7.2 // indirect
github.com/dghubble/sling v1.4.0 // indirect
github.com/di-wu/parser v0.2.2 // indirect
github.com/di-wu/xsd-datetime v1.0.0 // indirect
github.com/drswork/go-twitter v0.0.0-20221107160839-dea1b6ed53d7 // indirect
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-lark/lark v1.9.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-webauthn/revoke v0.1.6 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gomodule/redigo v2.0.0+incompatible // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/go-tpm v0.3.3 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gregdel/pushover v1.2.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/line/line-bot-sdk-go v7.8.0+incompatible // indirect
github.com/markbates/going v1.0.0 // indirect
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-ieproxy v0.0.1 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mileusna/viber v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect
github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7 // indirect
github.com/pingcap/tidb/parser v0.0.0-20221126021158-6b02a5d8ba7d // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.30.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/qiniu/go-sdk/v7 v7.12.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rs/zerolog v1.30.0 // indirect
github.com/scim2/filter-parser/v2 v2.2.0 // indirect
github.com/sendgrid/rest v2.6.9+incompatible // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/slack-go/slack v0.12.3 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.744 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.0.744 // indirect
github.com/tidwall/gjson v1.16.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.4.0 // indirect
github.com/twilio/twilio-go v1.13.0 // indirect
github.com/ucloud/ucloud-sdk-go v0.22.5 // indirect
github.com/utahta/go-linenotify v0.5.0 // indirect
github.com/volcengine/volc-sdk-golang v1.0.117 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.mau.fi/util v0.0.0-20230805171708-199bf3eec776 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.19.1 // indirect
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad // indirect
golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/uint128 v1.1.1 // indirect
maunium.net/go/maulogger/v2 v2.4.1 // indirect
modernc.org/cc/v3 v3.37.0 // indirect
modernc.org/ccgo/v3 v3.16.9 // indirect
modernc.org/libc v1.18.0 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.3.0 // indirect
modernc.org/opt v0.1.1 // indirect
modernc.org/strutil v1.1.3 // indirect
modernc.org/token v1.0.1 // indirect
)

1718
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Uživatelské jméno nemůže být emailová adresa",
"Username cannot contain white spaces": "Uživatelské jméno nemůže obsahovat mezery",
"Username cannot start with a digit": "Uživatelské jméno nemůže začínat číslicí",
"Username is too long (maximum is 39 characters).": "Uživatelské jméno je příliš dlouhé (maximálně 39 znaků).",
"Username is too long (maximum is 255 characters).": "Uživatelské jméno je příliš dlouhé (maximálně 255 znaků).",
"Username must have at least 2 characters": "Uživatelské jméno musí mít alespoň 2 znaky",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Zadali jste špatné heslo nebo kód příliš mnohokrát, prosím počkejte %d minut a zkuste to znovu",
"Your region is not allow to signup by phone": "Vaše oblast neumožňuje registraci pomocí telefonu",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Benutzername kann keine E-Mail-Adresse sein",
"Username cannot contain white spaces": "Benutzername darf keine Leerzeichen enthalten",
"Username cannot start with a digit": "Benutzername darf nicht mit einer Ziffer beginnen",
"Username is too long (maximum is 39 characters).": "Benutzername ist zu lang (das Maximum beträgt 39 Zeichen).",
"Username is too long (maximum is 255 characters).": "Benutzername ist zu lang (das Maximum beträgt 255 Zeichen).",
"Username must have at least 2 characters": "Benutzername muss mindestens 2 Zeichen lang sein",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Sie haben zu oft das falsche Passwort oder den falschen Code eingegeben. Bitte warten Sie %d Minuten und versuchen Sie es erneut",
"Your region is not allow to signup by phone": "Ihre Region ist nicht berechtigt, sich telefonisch anzumelden",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Nombre de usuario no puede ser una dirección de correo electrónico",
"Username cannot contain white spaces": "Nombre de usuario no puede contener espacios en blanco",
"Username cannot start with a digit": "El nombre de usuario no puede empezar con un dígito",
"Username is too long (maximum is 39 characters).": "El nombre de usuario es demasiado largo (el máximo es de 39 caracteres).",
"Username is too long (maximum is 255 characters).": "El nombre de usuario es demasiado largo (el máximo es de 255 caracteres).",
"Username must have at least 2 characters": "Nombre de usuario debe tener al menos 2 caracteres",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Has ingresado la contraseña o código incorrecto demasiadas veces, por favor espera %d minutos e intenta de nuevo",
"Your region is not allow to signup by phone": "Tu región no está permitida para registrarse por teléfono",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "نام کاربری نمی‌تواند یک آدرس ایمیل باشد",
"Username cannot contain white spaces": "نام کاربری نمی‌تواند حاوی فاصله باشد",
"Username cannot start with a digit": "نام کاربری نمی‌تواند با یک رقم شروع شود",
"Username is too long (maximum is 39 characters).": "نام کاربری بیش از حد طولانی است (حداکثر ۳۹ کاراکتر).",
"Username is too long (maximum is 255 characters).": "نام کاربری بیش از حد طولانی است (حداکثر ۳۹ کاراکتر).",
"Username must have at least 2 characters": "نام کاربری باید حداقل ۲ کاراکتر داشته باشد",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "شما رمز عبور یا کد اشتباه را بیش از حد وارد کرده‌اید، لطفاً %d دقیقه صبر کنید و دوباره تلاش کنید",
"Your region is not allow to signup by phone": "منطقه شما اجازه ثبت‌نام با تلفن را ندارد",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Nom d'utilisateur ne peut pas être une adresse e-mail",
"Username cannot contain white spaces": "Nom d'utilisateur ne peut pas contenir d'espaces blancs",
"Username cannot start with a digit": "Nom d'utilisateur ne peut pas commencer par un chiffre",
"Username is too long (maximum is 39 characters).": "Nom d'utilisateur est trop long (maximum de 39 caractères).",
"Username is too long (maximum is 255 characters).": "Nom d'utilisateur est trop long (maximum de 255 caractères).",
"Username must have at least 2 characters": "Le nom d'utilisateur doit comporter au moins 2 caractères",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Vous avez entré le mauvais mot de passe ou code plusieurs fois, veuillez attendre %d minutes et réessayer",
"Your region is not allow to signup by phone": "Votre région n'est pas autorisée à s'inscrire par téléphone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username tidak bisa menjadi alamat email",
"Username cannot contain white spaces": "Username tidak boleh mengandung spasi",
"Username cannot start with a digit": "Username tidak dapat dimulai dengan angka",
"Username is too long (maximum is 39 characters).": "Nama pengguna terlalu panjang (maksimum 39 karakter).",
"Username is too long (maximum is 255 characters).": "Nama pengguna terlalu panjang (maksimum 255 karakter).",
"Username must have at least 2 characters": "Nama pengguna harus memiliki setidaknya 2 karakter",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Anda telah memasukkan kata sandi atau kode yang salah terlalu banyak kali, mohon tunggu selama %d menit dan coba lagi",
"Your region is not allow to signup by phone": "Wilayah Anda tidak diizinkan untuk mendaftar melalui telepon",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "ユーザー名には電子メールアドレスを使用できません",
"Username cannot contain white spaces": "ユーザ名にはスペースを含めることはできません",
"Username cannot start with a digit": "ユーザー名は数字で始めることはできません",
"Username is too long (maximum is 39 characters).": "ユーザー名が長すぎます(最大39文字)。",
"Username is too long (maximum is 255 characters).": "ユーザー名が長すぎます(最大255文字)。",
"Username must have at least 2 characters": "ユーザー名は少なくとも2文字必要です",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "あなたは間違ったパスワードまたはコードを何度も入力しました。%d 分間待ってから再度お試しください",
"Your region is not allow to signup by phone": "あなたの地域は電話でサインアップすることができません",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "사용자 이름은 이메일 주소가 될 수 없습니다",
"Username cannot contain white spaces": "사용자 이름에는 공백이 포함될 수 없습니다",
"Username cannot start with a digit": "사용자 이름은 숫자로 시작할 수 없습니다",
"Username is too long (maximum is 39 characters).": "사용자 이름이 너무 깁니다 (최대 39자).",
"Username is too long (maximum is 255 characters).": "사용자 이름이 너무 깁니다 (최대 255자).",
"Username must have at least 2 characters": "사용자 이름은 적어도 2개의 문자가 있어야 합니다",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "올바르지 않은 비밀번호나 코드를 여러 번 입력했습니다. %d분 동안 기다리신 후 다시 시도해주세요",
"Your region is not allow to signup by phone": "당신의 지역은 전화로 가입할 수 없습니다",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "O nome de usuário não pode começar com um dígito",
"Username is too long (maximum is 39 characters).": "Nome de usuário é muito longo (máximo é 39 caracteres).",
"Username is too long (maximum is 255 characters).": "Nome de usuário é muito longo (máximo é 255 caracteres).",
"Username must have at least 2 characters": "Nome de usuário deve ter pelo menos 2 caracteres",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Имя пользователя не может быть адресом электронной почты",
"Username cannot contain white spaces": "Имя пользователя не может содержать пробелы",
"Username cannot start with a digit": "Имя пользователя не может начинаться с цифры",
"Username is too long (maximum is 39 characters).": "Имя пользователя слишком длинное (максимальная длина - 39 символов).",
"Username is too long (maximum is 255 characters).": "Имя пользователя слишком длинное (максимальная длина - 255 символов).",
"Username must have at least 2 characters": "Имя пользователя должно содержать не менее 2 символов",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Вы ввели неправильный пароль или код слишком много раз, пожалуйста, подождите %d минут и попробуйте снова",
"Your region is not allow to signup by phone": "Ваш регион не разрешает регистрацию по телефону",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Používateľské meno nemôže byť e-mailová adresa",
"Username cannot contain white spaces": "Používateľské meno nemôže obsahovať medzery",
"Username cannot start with a digit": "Používateľské meno nemôže začínať číslicou",
"Username is too long (maximum is 39 characters).": "Používateľské meno je príliš dlhé (maximum je 39 znakov).",
"Username is too long (maximum is 255 characters).": "Používateľské meno je príliš dlhé (maximum je 255 znakov).",
"Username must have at least 2 characters": "Používateľské meno musí mať aspoň 2 znaky",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Zadali ste nesprávne heslo alebo kód príliš veľa krát, prosím, počkajte %d minút a skúste to znova",
"Your region is not allow to signup by phone": "Váš región neumožňuje registráciu cez telefón",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Kullanıcı adı bir e-mail adresi olamaz",
"Username cannot contain white spaces": "Kullanıcı adı boşluk karakteri içeremez",
"Username cannot start with a digit": "Kullanıcı adı rakamla başlayamaz",
"Username is too long (maximum is 39 characters).": "Kullanıcı adı çok uzun (en fazla 39 karakter olmalı).",
"Username is too long (maximum is 255 characters).": "Kullanıcı adı çok uzun (en fazla 255 karakter olmalı).",
"Username must have at least 2 characters": "Kullanıcı adı en az iki karakterden oluşmalı",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Çok fazla hatalı şifre denemesi yaptınız. %d dakika kadar bekleyip yeniden giriş yapmayı deneyebilirsiniz.",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username is too long (maximum is 255 characters).": "Username is too long (maximum is 255 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "Tên người dùng không thể là địa chỉ email",
"Username cannot contain white spaces": "Tên người dùng không thể chứa khoảng trắng",
"Username cannot start with a digit": "Tên người dùng không thể bắt đầu bằng chữ số",
"Username is too long (maximum is 39 characters).": "Tên đăng nhập quá dài (tối đa là 39 ký tự).",
"Username is too long (maximum is 255 characters).": "Tên đăng nhập quá dài (tối đa là 255 ký tự).",
"Username must have at least 2 characters": "Tên đăng nhập phải có ít nhất 2 ký tự",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Bạn đã nhập sai mật khẩu hoặc mã quá nhiều lần, vui lòng đợi %d phút và thử lại",
"Your region is not allow to signup by phone": "Vùng của bạn không được phép đăng ký bằng điện thoại",

View File

@ -67,7 +67,7 @@
"Username cannot be an email address": "用户名不可以是邮箱地址",
"Username cannot contain white spaces": "用户名禁止包含空格",
"Username cannot start with a digit": "用户名禁止使用数字开头",
"Username is too long (maximum is 39 characters).": "用户名过长(最大允许长度为39个字符)",
"Username is too long (maximum is 255 characters).": "用户名过长(最大允许长度为255个字符)",
"Username must have at least 2 characters": "用户名至少要有2个字符",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "密码错误次数已达上限,请在 %d 分后重试",
"Your region is not allow to signup by phone": "所在地区不支持手机号注册",

View File

@ -434,7 +434,7 @@
"isTopGroup": true,
"title": "",
"key": "",
"children": "",
"children": [],
"isEnabled": true
}
],

View File

@ -185,12 +185,9 @@ func buildUserFilterCondition(filter interface{}) (builder.Cond, error) {
attr := string(f.AttributeDesc())
if attr == ldapMemberOfAttr {
groupId := string(f.AssertionValue())
users, err := object.GetGroupUsers(groupId)
if err != nil {
return nil, err
}
var names []string
groupId := string(f.AssertionValue())
users := object.GetGroupUsersWithoutError(groupId)
for _, user := range users {
names = append(names, user.Name)
}
@ -249,7 +246,7 @@ func buildSafeCondition(filter interface{}) builder.Cond {
condition, err := buildUserFilterCondition(filter)
if err != nil {
log.Printf("err = %v", err.Error())
return nil
return builder.And(builder.Expr("1 != 1"))
}
return condition
}

View File

@ -71,6 +71,7 @@ type Application struct {
Description string `xorm:"varchar(100)" json:"description"`
Organization string `xorm:"varchar(100)" json:"organization"`
Cert string `xorm:"varchar(100)" json:"cert"`
DefaultGroup string `xorm:"varchar(100)" json:"defaultGroup"`
HeaderHtml string `xorm:"mediumtext" json:"headerHtml"`
EnablePassword bool `json:"enablePassword"`
EnableSignUp bool `json:"enableSignUp"`
@ -97,29 +98,31 @@ type Application struct {
IsShared bool `json:"isShared"`
IpRestriction string `json:"ipRestriction"`
ClientId string `xorm:"varchar(100)" json:"clientId"`
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
RedirectUris []string `xorm:"varchar(1000)" json:"redirectUris"`
TokenFormat string `xorm:"varchar(100)" json:"tokenFormat"`
TokenSigningMethod string `xorm:"varchar(100)" json:"tokenSigningMethod"`
TokenFields []string `xorm:"varchar(1000)" json:"tokenFields"`
ExpireInHours int `json:"expireInHours"`
RefreshExpireInHours int `json:"refreshExpireInHours"`
SignupUrl string `xorm:"varchar(200)" json:"signupUrl"`
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
ForgetUrl string `xorm:"varchar(200)" json:"forgetUrl"`
AffiliationUrl string `xorm:"varchar(100)" json:"affiliationUrl"`
IpWhitelist string `xorm:"varchar(200)" json:"ipWhitelist"`
TermsOfUse string `xorm:"varchar(100)" json:"termsOfUse"`
SignupHtml string `xorm:"mediumtext" json:"signupHtml"`
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
ThemeData *ThemeData `xorm:"json" json:"themeData"`
FooterHtml string `xorm:"mediumtext" json:"footerHtml"`
FormCss string `xorm:"text" json:"formCss"`
FormCssMobile string `xorm:"text" json:"formCssMobile"`
FormOffset int `json:"formOffset"`
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
ClientId string `xorm:"varchar(100)" json:"clientId"`
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
RedirectUris []string `xorm:"varchar(1000)" json:"redirectUris"`
ForcedRedirectOrigin string `xorm:"varchar(100)" json:"forcedRedirectOrigin"`
TokenFormat string `xorm:"varchar(100)" json:"tokenFormat"`
TokenSigningMethod string `xorm:"varchar(100)" json:"tokenSigningMethod"`
TokenFields []string `xorm:"varchar(1000)" json:"tokenFields"`
ExpireInHours int `json:"expireInHours"`
RefreshExpireInHours int `json:"refreshExpireInHours"`
SignupUrl string `xorm:"varchar(200)" json:"signupUrl"`
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
ForgetUrl string `xorm:"varchar(200)" json:"forgetUrl"`
AffiliationUrl string `xorm:"varchar(100)" json:"affiliationUrl"`
IpWhitelist string `xorm:"varchar(200)" json:"ipWhitelist"`
TermsOfUse string `xorm:"varchar(100)" json:"termsOfUse"`
SignupHtml string `xorm:"mediumtext" json:"signupHtml"`
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
ThemeData *ThemeData `xorm:"json" json:"themeData"`
FooterHtml string `xorm:"mediumtext" json:"footerHtml"`
FormCss string `xorm:"text" json:"formCss"`
FormCssMobile string `xorm:"text" json:"formCssMobile"`
FormOffset int `json:"formOffset"`
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
FormBackgroundUrlMobile string `xorm:"varchar(200)" json:"formBackgroundUrlMobile"`
FailedSigninLimit int `json:"failedSigninLimit"`
FailedSigninFrozenTime int `json:"failedSigninFrozenTime"`
@ -539,7 +542,7 @@ func GetMaskedApplication(application *Application, userId string) *Application
providerItems := []*ProviderItem{}
for _, providerItem := range application.Providers {
if providerItem.Provider != nil && (providerItem.Provider.Category == "OAuth" || providerItem.Provider.Category == "Web3" || providerItem.Provider.Category == "Captcha" || providerItem.Provider.Category == "SAML") {
if providerItem.Provider != nil && (providerItem.Provider.Category == "OAuth" || providerItem.Provider.Category == "Web3" || providerItem.Provider.Category == "Captcha" || providerItem.Provider.Category == "SAML" || providerItem.Provider.Category == "Face ID") {
providerItems = append(providerItems, providerItem)
}
}

View File

@ -146,7 +146,12 @@ func getCertByName(name string) (*Cert, error) {
func GetCert(id string) (*Cert, error) {
owner, name := util.GetOwnerAndNameFromId(id)
return getCert(owner, name)
cert, err := getCert(owner, name)
if cert == nil && owner != "admin" {
return getCert("admin", name)
} else {
return cert, err
}
}
func UpdateCert(id string, cert *Cert) (bool, error) {

View File

@ -517,8 +517,8 @@ func CheckLoginPermission(userId string, application *Application) (bool, error)
func CheckUsername(username string, lang string) string {
if username == "" {
return i18n.Translate(lang, "check:Empty username.")
} else if len(username) > 39 {
return i18n.Translate(lang, "check:Username is too long (maximum is 39 characters).")
} else if len(username) > 255 {
return i18n.Translate(lang, "check:Username is too long (maximum is 255 characters).")
}
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex
@ -533,8 +533,8 @@ func CheckUsername(username string, lang string) string {
func CheckUsernameWithEmail(username string, lang string) string {
if username == "" {
return i18n.Translate(lang, "check:Empty username.")
} else if len(username) > 39 {
return i18n.Translate(lang, "check:Username is too long (maximum is 39 characters).")
} else if len(username) > 255 {
return i18n.Translate(lang, "check:Username is too long (maximum is 255 characters).")
}
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex

View File

@ -83,19 +83,23 @@ func GetPaginationGroups(owner string, offset, limit int, field, value, sortFiel
func GetGroupsHaveChildrenMap(groups []*Group) (map[string]*Group, error) {
groupsHaveChildren := []*Group{}
resultMap := make(map[string]*Group)
groupMap := map[string]*Group{}
groupIds := []string{}
for _, group := range groups {
groupMap[group.Name] = group
groupIds = append(groupIds, group.Name)
groupIds = append(groupIds, group.ParentId)
if !group.IsTopGroup {
groupIds = append(groupIds, group.ParentId)
}
}
err := ormer.Engine.Cols("owner", "name", "parent_id", "display_name").Distinct("parent_id").In("parent_id", groupIds).Find(&groupsHaveChildren)
if err != nil {
return nil, err
}
for _, group := range groups {
resultMap[group.Name] = group
for _, group := range groupsHaveChildren {
resultMap[group.ParentId] = groupMap[group.ParentId]
}
return resultMap, nil
}
@ -302,7 +306,10 @@ func GetPaginationGroupUsers(groupId string, offset, limit int, field, value, so
func GetGroupUsers(groupId string) ([]*User, error) {
users := []*User{}
owner, _ := util.GetOwnerAndNameFromId(groupId)
owner, _, err := util.GetOwnerAndNameFromIdWithError(groupId)
if err != nil {
return nil, err
}
names, err := userEnforcer.GetUserNamesByGroupName(groupId)
if err != nil {
return nil, err
@ -314,6 +321,11 @@ func GetGroupUsers(groupId string) ([]*User, error) {
return users, nil
}
func GetGroupUsersWithoutError(groupId string) []*User {
users, _ := GetGroupUsers(groupId)
return users
}
func ExtendGroupWithUsers(group *Group) error {
if group == nil {
return nil

View File

@ -77,6 +77,7 @@ func getOriginFromHostInternal(host string) (string, string) {
return origin, origin
}
isDev := conf.GetConfigString("runmode") == "dev"
// "door.casdoor.com"
protocol := "https://"
if !strings.Contains(host, ".") {
@ -87,7 +88,7 @@ func getOriginFromHostInternal(host string) (string, string) {
protocol = "http://"
}
if host == "localhost:8000" {
if host == "localhost:8000" && isDev {
return fmt.Sprintf("%s%s", protocol, "localhost:7001"), fmt.Sprintf("%s%s", protocol, "localhost:8000")
} else {
return fmt.Sprintf("%s%s", protocol, host), fmt.Sprintf("%s%s", protocol, host)

View File

@ -80,7 +80,8 @@ type Organization struct {
UseEmailAsUsername bool `json:"useEmailAsUsername"`
EnableTour bool `json:"enableTour"`
IpRestriction string `json:"ipRestriction"`
NavItems []string `xorm:"varchar(500)" json:"navItems"`
NavItems []string `xorm:"varchar(1000)" json:"navItems"`
WidgetItems []string `xorm:"varchar(1000)" json:"widgetItems"`
MfaItems []*MfaItem `xorm:"varchar(300)" json:"mfaItems"`
AccountItems []*AccountItem `xorm:"varchar(5000)" json:"accountItems"`
@ -227,6 +228,7 @@ func UpdateOrganization(id string, organization *Organization, isGlobalAdmin boo
if !isGlobalAdmin {
organization.NavItems = org.NavItems
organization.WidgetItems = org.WidgetItems
}
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()

View File

@ -148,7 +148,7 @@ func UpdatePermission(id string, permission *Permission) (bool, error) {
}
if permission.ResourceType == "Application" && permission.Model != "" {
model, err := GetModelEx(util.GetId(owner, permission.Model))
model, err := GetModelEx(util.GetId(permission.Owner, permission.Model))
if err != nil {
return false, err
} else if model == nil {

View File

@ -384,6 +384,44 @@ func GetCaptchaProviderByApplication(applicationId, isCurrentProvider, lang stri
return nil, nil
}
func GetFaceIdProviderByOwnerName(applicationId, lang string) (*Provider, error) {
owner, name := util.GetOwnerAndNameFromId(applicationId)
provider := Provider{Owner: owner, Name: name, Category: "Face ID"}
existed, err := ormer.Engine.Get(&provider)
if err != nil {
return nil, err
}
if !existed {
return nil, fmt.Errorf(i18n.Translate(lang, "provider:the provider: %s does not exist"), applicationId)
}
return &provider, nil
}
func GetFaceIdProviderByApplication(applicationId, isCurrentProvider, lang string) (*Provider, error) {
if isCurrentProvider == "true" {
return GetFaceIdProviderByOwnerName(applicationId, lang)
}
application, err := GetApplication(applicationId)
if err != nil {
return nil, err
}
if application == nil || len(application.Providers) == 0 {
return nil, fmt.Errorf(i18n.Translate(lang, "provider:Invalid application id"))
}
for _, provider := range application.Providers {
if provider.Provider == nil {
continue
}
if provider.Provider.Category == "Face ID" {
return GetFaceIdProviderByOwnerName(util.GetId(provider.Provider.Owner, provider.Provider.Name), lang)
}
}
return nil, nil
}
func providerChangeTrigger(oldName string, newName string) error {
session := ormer.Engine.NewSession()
defer session.Close()

View File

@ -15,13 +15,17 @@
package object
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
"reflect"
"strconv"
"strings"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/faceId"
"github.com/casdoor/casdoor/proxy"
"github.com/casdoor/casdoor/util"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/xorm-io/builder"
@ -48,7 +52,7 @@ func InitUserManager() {
type User struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
Name string `xorm:"varchar(255) notnull pk" json:"name"`
CreatedTime string `xorm:"varchar(100) index" json:"createdTime"`
UpdatedTime string `xorm:"varchar(100)" json:"updatedTime"`
DeletedTime string `xorm:"varchar(100)" json:"deletedTime"`
@ -244,6 +248,7 @@ type MfaAccount struct {
type FaceId struct {
Name string `xorm:"varchar(100) notnull pk" json:"name"`
FaceIdData []float64 `json:"faceIdData"`
ImageUrl string `json:"ImageUrl"`
}
func GetUserFieldStringValue(user *User, fieldName string) (bool, string, error) {
@ -1179,6 +1184,40 @@ func (user *User) IsGlobalAdmin() bool {
return user.Owner == "built-in"
}
func (user *User) CheckUserFace(faceIdImage []string, provider *Provider) (bool, error) {
faceIdChecker := faceId.GetFaceIdProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.Endpoint)
httpClient := proxy.DefaultHttpClient
errList := []error{}
for _, userFaceId := range user.FaceIds {
if userFaceId.ImageUrl != "" {
imgResp, err := httpClient.Get(userFaceId.ImageUrl)
if err != nil {
continue
}
imgByte, err := io.ReadAll(imgResp.Body)
if err != nil {
continue
}
base64Img := base64.StdEncoding.EncodeToString(imgByte)
for _, imgBase64 := range faceIdImage {
isSuccess, err := faceIdChecker.Check(imgBase64, base64Img)
if err != nil {
errList = append(errList, err)
continue
}
if isSuccess {
return true, nil
}
}
}
}
if len(errList) > 0 {
return false, errList[0]
}
return false, nil
}
func GenerateIdForNewUser(application *Application) (string, error) {
if application == nil || application.GetSignupItemRule("ID") != "Incremental" {
return util.GenerateId(), nil

View File

@ -38,6 +38,7 @@ type Webhook struct {
ContentType string `xorm:"varchar(100)" json:"contentType"`
Headers []*Header `xorm:"mediumtext" json:"headers"`
Events []string `xorm:"varchar(1000)" json:"events"`
TokenFields []string `xorm:"varchar(1000)" json:"tokenFields"`
IsUserExtended bool `json:"isUserExtended"`
SingleOrgOnly bool `json:"singleOrgOnly"`
IsEnabled bool `json:"isEnabled"`

View File

@ -17,6 +17,7 @@ package object
import (
"io"
"net/http"
"reflect"
"strings"
"github.com/casdoor/casdoor/util"
@ -25,17 +26,43 @@ import (
func sendWebhook(webhook *Webhook, record *casvisorsdk.Record, extendedUser *User) (int, string, error) {
client := &http.Client{}
userMap := make(map[string]interface{})
var body io.Reader
type RecordEx struct {
casvisorsdk.Record
ExtendedUser *User `xorm:"-" json:"extendedUser"`
}
recordEx := &RecordEx{
Record: *record,
ExtendedUser: extendedUser,
}
if webhook.TokenFields != nil && len(webhook.TokenFields) > 0 && extendedUser != nil {
userValue := reflect.ValueOf(extendedUser).Elem()
body := strings.NewReader(util.StructToJson(recordEx))
for _, field := range webhook.TokenFields {
userField := userValue.FieldByName(field)
if userField.IsValid() {
newfield := util.SnakeToCamel(util.CamelToSnakeCase(field))
userMap[newfield] = userField.Interface()
}
}
type RecordEx struct {
casvisorsdk.Record
ExtendedUser map[string]interface{} `json:"extendedUser"`
}
recordEx := &RecordEx{
Record: *record,
ExtendedUser: userMap,
}
body = strings.NewReader(util.StructToJson(recordEx))
} else {
type RecordEx struct {
casvisorsdk.Record
ExtendedUser *User `xorm:"-" json:"extendedUser"`
}
recordEx := &RecordEx{
Record: *record,
ExtendedUser: extendedUser,
}
body = strings.NewReader(util.StructToJson(recordEx))
}
req, err := http.NewRequest(webhook.Method, webhook.Url, body)
if err != nil {

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
@ -180,7 +181,11 @@ func (c *AirwallexClient) authRequest(method, url string, body interface{}) (map
return nil, err
}
b, _ := json.Marshal(body)
req, _ := http.NewRequest(method, url, bytes.NewBuffer(b))
var reqBody io.Reader
if method != "GET" {
reqBody = bytes.NewBuffer(b)
}
req, _ := http.NewRequest(method, url, reqBody)
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := c.client.Do(req)

View File

@ -106,11 +106,14 @@ func getOrganizationThemeCookieFromUrlPath(ctx *context.Context, urlPath string)
}
organizationThemeCookie := &OrganizationThemeCookie{
application.ThemeData,
application.Logo,
application.FooterHtml,
organization.Favicon,
organization.DisplayName,
ThemeData: application.ThemeData,
LogoUrl: application.Logo,
FooterHtml: application.FooterHtml,
}
if organization != nil {
organizationThemeCookie.Favicon = organization.Favicon
organizationThemeCookie.DisplayName = organization.DisplayName
}
return organizationThemeCookie, nil

View File

@ -3,8 +3,8 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@ant-design/cssinjs": "^1.10.1",
"@ant-design/icons": "^4.7.0",
"@ant-design/cssinjs": "^1.23.0",
"@ant-design/icons": "^5.6.1",
"@craco/craco": "^6.4.5",
"@crowdin/cli": "^3.7.10",
"@ctrl/tinycolor": "^3.5.0",
@ -23,8 +23,8 @@
"@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",
"antd": "5.24.1",
"antd-token-previewer": "^2.0.8",
"buffer": "^6.0.3",
"codemirror": "^6.0.1",
"copy-to-clipboard": "^3.3.1",

View File

@ -327,7 +327,7 @@ class App extends Component {
isAiAssistantOpen: false,
});
}}
visible={this.state.isAiAssistantOpen}
open={this.state.isAiAssistantOpen}
>
<iframe id="iframeHelper" title={"iframeHelper"} src={`${Conf.AiAssistantUrl}/?isRaw=1`} width="100%" height="100%" scrolling="no" frameBorder="no" />
</Drawer>

View File

@ -58,6 +58,16 @@ img {
}
}
.org-select {
display: flex;
position: relative;
transform: translateY(50%);
margin: 0 10px !important;
float: right;
min-width: 120px;
max-width: 180px;
}
.rightDropDown {
display: flex;
align-items: center;

View File

@ -13,8 +13,8 @@
// limitations under the License.
import React from "react";
import {Button, Card, Col, ConfigProvider, Input, InputNumber, Popover, Radio, Result, Row, Select, Switch, Upload} from "antd";
import {CopyOutlined, LinkOutlined, UploadOutlined} from "@ant-design/icons";
import {Button, Card, Col, ConfigProvider, Input, InputNumber, Popover, Radio, Result, Row, Select, Space, Switch, Upload} from "antd";
import {CopyOutlined, HolderOutlined, LinkOutlined, UploadOutlined, UsergroupAddOutlined} from "@ant-design/icons";
import * as ApplicationBackend from "./backend/ApplicationBackend";
import * as CertBackend from "./backend/CertBackend";
import * as Setting from "./Setting";
@ -36,6 +36,7 @@ import ThemeEditor from "./common/theme/ThemeEditor";
import SigninTable from "./table/SigninTable";
import Editor from "./common/Editor";
import * as GroupBackend from "./backend/GroupBackend";
const {Option} = Select;
@ -116,6 +117,7 @@ class ApplicationEditPage extends React.Component {
UNSAFE_componentWillMount() {
this.getApplication();
this.getOrganizations();
this.getGroups();
}
getApplication() {
@ -167,6 +169,17 @@ class ApplicationEditPage extends React.Component {
});
}
getGroups() {
GroupBackend.getGroups(this.state.organizationName)
.then((res) => {
if (res.status === "ok") {
this.setState({
groups: res.data,
});
}
});
}
getCerts(application) {
let owner = application.organization;
if (application.isShared) {
@ -397,6 +410,16 @@ class ApplicationEditPage extends React.Component {
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("application:Forced redirect origin"), i18next.t("general:Forced redirect origin - Tooltip"))} :
</Col>
<Col span={22} >
<Input prefix={<LinkOutlined />} value={this.state.application.forcedRedirectOrigin} onChange={e => {
this.updateApplicationField("forcedRedirectOrigin", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("application:Token format"), i18next.t("application:Token format - Tooltip"))} :
@ -469,6 +492,31 @@ class ApplicationEditPage extends React.Component {
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("ldap:Default group"), i18next.t("ldap:Default group - Tooltip"))} :
</Col>
<Col span={22}>
<Select virtual={false} style={{width: "100%"}} value={this.state.application.defaultGroup ?? []} onChange={(value => {
this.updateApplicationField("defaultGroup", value);
})}
>
<Option key={""} value={""}>
<Space>
{i18next.t("general:Default")}
</Space>
</Option>
{
this.state.groups?.map((group) => <Option key={group.name} value={`${group.owner}/${group.name}`}>
<Space>
{group.type === "Physical" ? <UsergroupAddOutlined /> : <HolderOutlined />}
{group.displayName}
</Space>
</Option>)
}
</Select>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 19 : 2}>
{Setting.getLabel(i18next.t("application:Enable signup"), i18next.t("application:Enable signup - Tooltip"))} :
@ -804,6 +852,33 @@ class ApplicationEditPage extends React.Component {
</Row>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("application:Background URL Mobile"), i18next.t("application:Background URL Mobile - Tooltip"))} :
</Col>
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
</Col>
<Col span={22} >
<Input prefix={<LinkOutlined />} value={this.state.application.formBackgroundUrlMobile} onChange={e => {
this.updateApplicationField("formBackgroundUrlMobile", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{i18next.t("general:Preview")}:
</Col>
<Col span={22} >
<a target="_blank" rel="noreferrer" href={this.state.application.formBackgroundUrlMobile}>
<img src={this.state.application.formBackgroundUrlMobile} alt={this.state.application.formBackgroundUrlMobile} height={90} style={{marginBottom: "20px"}} />
</a>
</Col>
</Row>
</Col>
</Row>
<Row>
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("application:Custom CSS"), i18next.t("application:Custom CSS - Tooltip"))} :

View File

@ -73,7 +73,7 @@ class BaseListPage extends React.Component {
this.fetch({pagination});
}
getColumnSearchProps = dataIndex => ({
getColumnSearchProps = (dataIndex, customRender = null) => ({
filterDropdown: ({setSelectedKeys, selectedKeys, confirm, clearFilters}) => (
<div style={{padding: 8}}>
<Input
@ -121,13 +121,15 @@ class BaseListPage extends React.Component {
record[dataIndex]
? record[dataIndex].toString().toLowerCase().includes(value.toLowerCase())
: "",
onFilterDropdownOpenChange: visible => {
if (visible) {
setTimeout(() => this.searchInput.select(), 100);
}
filterDropdownProps: {
onOpenChange: visible => {
if (visible) {
setTimeout(() => this.searchInput.select(), 100);
}
},
},
render: text =>
this.state.searchedColumn === dataIndex ? (
render: (text, record, index) => {
const highlightContent = this.state.searchedColumn === dataIndex ? (
<Highlighter
highlightStyle={{backgroundColor: "#ffc069", padding: 0}}
searchWords={[this.state.searchText]}
@ -136,7 +138,10 @@ class BaseListPage extends React.Component {
/>
) : (
text
),
);
return customRender ? customRender({text, record, index}, highlightContent) : highlightContent;
},
});
handleSearch = (selectedKeys, confirm, dataIndex) => {
@ -170,7 +175,7 @@ class BaseListPage extends React.Component {
const steps = TourConfig.getSteps();
steps.map((item, index) => {
if (!index) {
item.target = () => document.querySelector("table");
item.target = () => document.querySelector(".ant-table");
} else {
item.target = () => document.getElementById(item.id) || null;
}

View File

@ -19,8 +19,6 @@ import {Tabs} from "antd";
import i18next from "i18next";
import Editor from "./common/Editor";
const {TabPane} = Tabs;
const CasbinEditor = ({model, onModelTextChange}) => {
const [activeKey, setActiveKey] = useState("advanced");
const iframeRef = useRef(null);
@ -66,10 +64,15 @@ const CasbinEditor = ({model, onModelTextChange}) => {
return (
<div style={{height: "100%", width: "100%", display: "flex", flexDirection: "column"}}>
<Tabs activeKey={activeKey} onChange={handleTabChange} style={{flex: "0 0 auto", marginTop: "-10px"}}>
<TabPane tab={i18next.t("model:Basic Editor")} key="basic" />
<TabPane tab={i18next.t("model:Advanced Editor")} key="advanced" />
</Tabs>
<Tabs
activeKey={activeKey}
onChange={handleTabChange}
style={{flex: "0 0 auto", marginTop: "-10px"}}
items={[
{key: "basic", label: i18next.t("model:Basic Editor")},
{key: "advanced", label: i18next.t("model:Advanced Editor")},
]}
/>
<div style={{flex: "1 1 auto", overflow: "hidden"}}>
{activeKey === "advanced" ? (
<IframeEditor

View File

@ -109,7 +109,7 @@ class EntryPage extends React.Component {
<React.Fragment>
<CustomHead headerHtml={this.state.application?.headerHtml} />
<div className={`${isDarkMode ? "loginBackgroundDark" : "loginBackground"}`}
style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${this.state.application?.formBackgroundUrl})`}}>
style={{backgroundImage: Setting.inIframe() ? null : (Setting.isMobile() ? `url(${this.state.application?.formBackgroundUrlMobile})` : `url(${this.state.application?.formBackgroundUrl})`)}}>
<Spin size="large" spinning={this.state.application === undefined && this.state.pricing === undefined} tip={i18next.t("login:Loading")}
style={{width: "100%", margin: "0 auto", position: "absolute"}} />
<Switch>

View File

@ -14,7 +14,7 @@
import React from "react";
import {Link} from "react-router-dom";
import {Button, Table} from "antd";
import {Button, Table, Tooltip} from "antd";
import moment from "moment";
import * as Setting from "./Setting";
import * as GroupBackend from "./backend/GroupBackend";
@ -202,12 +202,16 @@ class GroupListPage extends BaseListPage {
return (
<div>
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/groups/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
<PopconfirmModal
disabled={record.haveChildren}
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
onConfirm={() => this.deleteGroup(index)}
>
</PopconfirmModal>
{
record.haveChildren ? <Tooltip placement="topLeft" title={i18next.t("group:You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -> [Groups] page")}>
<Button disabled type="primary" danger>{i18next.t("general:Delete")}</Button>
</Tooltip> :
<PopconfirmModal
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
onConfirm={() => this.deleteGroup(index)}
>
</PopconfirmModal>
}
</div>
);
},

View File

@ -114,7 +114,7 @@ class InvitationEditPage extends React.Component {
const selectedOrganization = Setting.getArrayItem(this.state.organizations, "name", this.state.invitation.owner);
defaultApplication = selectedOrganization.defaultApplication;
if (!defaultApplication) {
Setting.showMessage("error", i18next.t("invitation:You need to specify a default application for ") + selectedOrganization.name);
Setting.showMessage("error", i18next.t("invitation:You need to first specify a default application for organization: ") + selectedOrganization.name);
return;
}
}

View File

@ -95,8 +95,9 @@ import TransactionEditPage from "./TransactionEditPage";
import VerificationListPage from "./VerificationListPage";
function ManagementPage(props) {
const [menuVisible, setMenuVisible] = useState(false);
const navItems = props.account?.organization?.navItems;
const widgetItems = props.account?.organization?.widgetItems;
function logout() {
AuthBackend.logout()
@ -175,6 +176,35 @@ function ManagementPage(props) {
);
}
function navItemsIsAll() {
return !Array.isArray(navItems) || !!navItems?.includes("all");
}
function widgetItemsIsAll() {
return !Array.isArray(widgetItems) || !!widgetItems?.includes("all");
}
function renderWidgets() {
const widgets = [
Setting.getItem(<ThemeSelect themeAlgorithm={props.themeAlgorithm} onChange={props.setLogoAndThemeAlgorithm} />, "theme"),
Setting.getItem(<LanguageSelect languages={props.account.organization.languages} />, "language"),
Setting.getItem(Conf.AiAssistantUrl?.trim() && (
<Tooltip title="Click to open AI assistant">
<div className="select-box" onClick={props.openAiAssistant}>
<DeploymentUnitOutlined style={{fontSize: "24px"}} />
</div>
</Tooltip>
), "ai-assistant"),
Setting.getItem(<OpenTour />, "tour"),
];
if (widgetItemsIsAll()) {
return widgets.map(item => item.label);
}
return widgets.filter(item => widgetItems.includes(item.key)).map(item => item.label);
}
function renderAccountMenu() {
if (props.account === undefined) {
return null;
@ -188,29 +218,16 @@ function ManagementPage(props) {
return (
<React.Fragment>
{renderRightDropdown()}
<ThemeSelect
themeAlgorithm={props.themeAlgorithm}
onChange={props.setLogoAndThemeAlgorithm} />
<LanguageSelect languages={props.account.organization.languages} />
{
Conf.AiAssistantUrl?.trim() && (
<Tooltip title="Click to open AI assistant">
<div className="select-box" onClick={props.openAiAssistant}>
<DeploymentUnitOutlined style={{fontSize: "24px"}} />
</div>
</Tooltip>
)
}
<OpenTour />
{renderWidgets()}
{Setting.isAdminUser(props.account) && (props.uri.indexOf("/trees") === -1) &&
<OrganizationSelect
initValue={Setting.getOrganization()}
withAll={true}
style={{marginRight: "20px", width: "180px", display: !Setting.isMobile() ? "flex" : "none"}}
className="org-select"
style={{display: Setting.isMobile() ? "none" : "flex"}}
onChange={(value) => {
Setting.setOrganization(value);
}}
className="select-box"
/>
}
</React.Fragment>
@ -323,13 +340,7 @@ function ManagementPage(props) {
}
}
const navItems = props.account.organization.navItems;
if (!Array.isArray(navItems)) {
return res;
}
if (navItems.includes("all")) {
if (navItemsIsAll()) {
return res;
}
@ -443,8 +454,6 @@ function ManagementPage(props) {
return Setting.isMobile() || window.location.pathname.startsWith("/trees");
}
const menuStyleRight = Setting.isAdminUser(props.account) && !Setting.isMobile() ? "calc(180px + 280px)" : "320px";
const onClose = () => {
setMenuVisible(false);
};
@ -456,34 +465,40 @@ function ManagementPage(props) {
return (
<React.Fragment>
<EnableMfaNotification account={props.account} />
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: props.themeAlgorithm.includes("dark") ? "black" : "white"}} >
{props.requiredEnableMfa || (Setting.isMobile() ?
<React.Fragment>
<Drawer title={i18next.t("general:Close")} placement="left" visible={menuVisible} onClose={onClose}>
<Menu
items={getMenuItems()}
mode={"inline"}
selectedKeys={[props.selectedMenuKey]}
style={{lineHeight: "64px"}}
onClick={onClose}
>
</Menu>
</Drawer>
<Button icon={<BarsOutlined />} onClick={showMenu} type="text">
{i18next.t("general:Menu")}
</Button>
</React.Fragment> :
<Menu
onClick={onClose}
items={getMenuItems()}
mode={"horizontal"}
selectedKeys={[props.selectedMenuKey]}
style={{position: "absolute", left: 0, right: menuStyleRight, backgroundColor: props.themeAlgorithm.includes("dark") ? "black" : "white"}}
/>
)}
<Header style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: "0", marginBottom: "4px", backgroundColor: props.themeAlgorithm.includes("dark") ? "black" : "white"}} >
{
renderAccountMenu()
props.requiredEnableMfa || (Setting.isMobile() ? (
<React.Fragment>
<Drawer title={i18next.t("general:Close")} placement="left" open={menuVisible} onClose={onClose}>
<Menu
items={getMenuItems()}
mode={"inline"}
selectedKeys={[props.selectedMenuKey]}
style={{lineHeight: "64px"}}
onClick={onClose}
>
</Menu>
</Drawer>
<Button icon={<BarsOutlined />} onClick={showMenu} type="text">
{i18next.t("general:Menu")}
</Button>
</React.Fragment>
) : (
// Padding 1px for Menu Item Highlight border
<div style={{flex: 1, overflow: "hidden", paddingBottom: "1px"}}>
<Menu
onClick={onClose}
items={getMenuItems()}
mode={"horizontal"}
selectedKeys={[props.selectedMenuKey]}
style={{backgroundColor: props.themeAlgorithm.includes("dark") ? "black" : "white"}}
/>
</div>
))
}
<div style={{flexShrink: 0}}>
{renderAccountMenu()}
</div>
</Header>
<Content style={{display: "flex", flexDirection: "column"}} >
{isWithoutCard() ?

View File

@ -27,6 +27,7 @@ import AccountTable from "./table/AccountTable";
import ThemeEditor from "./common/theme/ThemeEditor";
import MfaTable from "./table/MfaTable";
import {NavItemTree} from "./common/NavItemTree";
import {WidgetItemTree} from "./common/WidgetItemTree";
const {Option} = Select;
@ -537,7 +538,7 @@ class OrganizationEditPage extends React.Component {
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Navbar items"), i18next.t("general:Navbar items - Tooltip"))} :
{Setting.getLabel(i18next.t("organization:Navbar items"), i18next.t("organization:Navbar items - Tooltip"))} :
</Col>
<Col span={22} >
<NavItemTree
@ -550,6 +551,21 @@ class OrganizationEditPage extends React.Component {
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("organization:Widget items"), i18next.t("organization:Widget items - Tooltip"))} :
</Col>
<Col span={22} >
<WidgetItemTree
disabled={!Setting.isAdminUser(this.props.account)}
checkedKeys={this.state.organization.widgetItems ?? ["all"]}
defaultExpandedKeys={["all"]}
onCheck={(checked, _) => {
this.updateOrganizationField("widgetItems", checked);
}}
/>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("organization:Account items"), i18next.t("organization:Account items - Tooltip"))} :

View File

@ -113,8 +113,8 @@ class PermissionListPage extends BaseListPage {
return (
<Upload {...props}>
<Button id="upload-button" type="primary" size="small">
<UploadOutlined /> {i18next.t("user:Upload (.xlsx)")}
<Button icon={<UploadOutlined />} id="upload-button" type="primary" size="small">
{i18next.t("user:Upload (.xlsx)")}
</Button></Upload>
);
}

View File

@ -288,10 +288,8 @@ class ProviderEditPage extends React.Component {
default:
if (provider.type === "Aliyun Captcha") {
return Setting.getLabel(i18next.t("provider:Scene"), i18next.t("provider:Scene - Tooltip"));
} else if (provider.type === "WeChat Pay") {
} else if (provider.type === "WeChat Pay" || provider.type === "CUCloud") {
return Setting.getLabel(i18next.t("provider:App ID"), i18next.t("provider:App ID - Tooltip"));
} else if (provider.type === "CUCloud") {
return Setting.getLabel(i18next.t("provider:Account ID"), i18next.t("provider:Account ID - Tooltip"));
} else {
return Setting.getLabel(i18next.t("provider:Client ID 2"), i18next.t("provider:Client ID 2 - Tooltip"));
}
@ -389,8 +387,8 @@ class ProviderEditPage extends React.Component {
text = i18next.t("provider:App Key");
tooltip = i18next.t("provider:App Key - Tooltip");
} else if (provider.type === "CUCloud") {
text = i18next.t("provider:Topic name");
tooltip = i18next.t("provider:Topic name - Tooltip");
text = "Topic name";
tooltip = "Topic name - Tooltip";
}
}
@ -567,6 +565,8 @@ class ProviderEditPage extends React.Component {
this.updateProviderField("type", "MetaMask");
} else if (value === "Notification") {
this.updateProviderField("type", "Telegram");
} else if (value === "Face ID") {
this.updateProviderField("type", "Alibaba Cloud Facebody");
}
})}>
{
@ -580,6 +580,7 @@ class ProviderEditPage extends React.Component {
{id: "SMS", name: "SMS"},
{id: "Storage", name: "Storage"},
{id: "Web3", name: "Web3"},
{id: "Face ID", name: "Face ID"},
]
.sort((a, b) => a.name.localeCompare(b.name))
.map((providerCategory, index) => <Option key={index} value={providerCategory.id}>{providerCategory.name}</Option>)
@ -901,7 +902,7 @@ class ProviderEditPage extends React.Component {
</Row>
)
}
{this.state.provider.category === "Storage" || ["Custom HTTP SMS", "Custom HTTP Email", "SendGrid", "CUCloud"].includes(this.state.provider.type) ? (
{["Face ID", "Storage"].includes(this.state.provider.category) || ["Custom HTTP SMS", "Custom HTTP Email", "SendGrid", "CUCloud"].includes(this.state.provider.type) ? (
<div>
{["Local File System", "CUCloud"].includes(this.state.provider.type) ? null : (
<Row style={{marginTop: "20px"}} >
@ -915,7 +916,7 @@ class ProviderEditPage extends React.Component {
</Col>
</Row>
)}
{["Custom HTTP SMS", "SendGrid", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology", "Casdoor", "CUCloud"].includes(this.state.provider.type) ? null : (
{["Custom HTTP SMS", "SendGrid", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology", "Casdoor", "CUCloud", "Alibaba Cloud Facebody"].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"))} :
@ -927,7 +928,7 @@ class ProviderEditPage extends React.Component {
</Col>
</Row>
)}
{["Custom HTTP SMS", "SendGrid", "Local File System", "CUCloud"].includes(this.state.provider.type) ? null : (
{["Custom HTTP SMS", "SendGrid", "Local File System", "CUCloud", "Alibaba Cloud Facebody"].includes(this.state.provider.type) ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={2}>
{["Casdoor"].includes(this.state.provider.type) ?
@ -941,7 +942,7 @@ class ProviderEditPage extends React.Component {
</Col>
</Row>
)}
{["Custom HTTP SMS", "SendGrid", "CUCloud"].includes(this.state.provider.type) ? null : (
{["Custom HTTP SMS", "SendGrid", "CUCloud", "Alibaba Cloud Facebody"].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"))} :
@ -953,7 +954,7 @@ class ProviderEditPage extends React.Component {
</Col>
</Row>
)}
{["Custom HTTP SMS", "SendGrid", "Synology", "Casdoor", "CUCloud"].includes(this.state.provider.type) ? null : (
{["Custom HTTP SMS", "SendGrid", "Synology", "Casdoor", "CUCloud", "Alibaba Cloud Facebody"].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"))} :
@ -1280,7 +1281,7 @@ class ProviderEditPage extends React.Component {
}} />
</Col>
<Col span={16} >
<Button type="primary" loading={this.state.metadataLoading} onClick={() => {this.fetchSamlMetadata();}}>{i18next.t("general:Request")}</Button>
<Button style={{marginLeft: "10px"}} type="primary" loading={this.state.metadataLoading} onClick={() => {this.fetchSamlMetadata();}}>{i18next.t("general:Request")}</Button>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >

View File

@ -14,12 +14,12 @@
import React from "react";
import {Link} from "react-router-dom";
import {Switch, Table} from "antd";
import {Button, Descriptions, Drawer, Switch, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as RecordBackend from "./backend/RecordBackend";
import i18next from "i18next";
import moment from "moment";
import BaseListPage from "./BaseListPage";
import Editor from "./common/Editor";
class RecordListPage extends BaseListPage {
UNSAFE_componentWillMount() {
@ -28,21 +28,6 @@ class RecordListPage extends BaseListPage {
this.fetch({pagination});
}
newRecord() {
return {
owner: "built-in",
name: "1234",
id: "1234",
clientIp: "::1",
timestamp: moment().format(),
organization: "built-in",
username: "admin",
requestUri: "/api/get-account",
action: "login",
isTriggered: false,
};
}
renderTable(records) {
let columns = [
{
@ -65,16 +50,13 @@ class RecordListPage extends BaseListPage {
title: i18next.t("general:Client IP"),
dataIndex: "clientIp",
key: "clientIp",
width: "100px",
width: "120px",
sorter: true,
...this.getColumnSearchProps("clientIp"),
render: (text, record, index) => {
return (
<a target="_blank" rel="noreferrer" href={`https://db-ip.com/${text}`}>
{text}
</a>
);
},
...this.getColumnSearchProps("clientIp", (row, highlightContent) => (
<a target="_blank" rel="noreferrer" href={`https://db-ip.com/${row.text}`}>
{highlightContent}
</a>
)),
},
{
title: i18next.t("general:Timestamp"),
@ -120,28 +102,28 @@ class RecordListPage extends BaseListPage {
title: i18next.t("general:Method"),
dataIndex: "method",
key: "method",
width: "110px",
width: "100px",
sorter: true,
filterMultiple: false,
filters: [
{text: "GET", value: "GET"},
{text: "HEAD", value: "HEAD"},
{text: "POST", value: "POST"},
{text: "PUT", value: "PUT"},
{text: "DELETE", value: "DELETE"},
{text: "CONNECT", value: "CONNECT"},
{text: "OPTIONS", value: "OPTIONS"},
{text: "TRACE", value: "TRACE"},
{text: "PATCH", value: "PATCH"},
],
"GET", "HEAD", "POST", "PUT", "DELETE",
"CONNECT", "OPTIONS", "TRACE", "PATCH",
].map(el => ({text: el, value: el})),
},
{
title: i18next.t("general:Request URI"),
dataIndex: "requestUri",
key: "requestUri",
// width: "300px",
width: "200px",
sorter: true,
...this.getColumnSearchProps("requestUri"),
ellipsis: {
showTitle: false,
},
...this.getColumnSearchProps("requestUri", (row, highlightContent) => (
<Tooltip placement="topLeft" title={row.text}>
{highlightContent}
</Tooltip>
)),
},
{
title: i18next.t("user:Language"),
@ -155,7 +137,7 @@ class RecordListPage extends BaseListPage {
title: i18next.t("record:Status code"),
dataIndex: "statusCode",
key: "statusCode",
width: "90px",
width: "120px",
sorter: true,
...this.getColumnSearchProps("statusCode"),
},
@ -163,16 +145,26 @@ class RecordListPage extends BaseListPage {
title: i18next.t("record:Response"),
dataIndex: "response",
key: "response",
width: "90px",
width: "220px",
sorter: true,
...this.getColumnSearchProps("response"),
ellipsis: {
showTitle: false,
},
...this.getColumnSearchProps("response", (row, highlightContent) => (
<Tooltip placement="topLeft" title={row.text}>
{highlightContent}
</Tooltip>
)),
},
{
title: i18next.t("record:Object"),
dataIndex: "object",
key: "object",
width: "90px",
width: "200px",
sorter: true,
ellipsis: {
showTitle: false,
},
...this.getColumnSearchProps("object"),
},
{
@ -191,7 +183,7 @@ class RecordListPage extends BaseListPage {
title: i18next.t("record:Is triggered"),
dataIndex: "isTriggered",
key: "isTriggered",
width: "140px",
width: "120px",
sorter: true,
fixed: (Setting.isMobile()) ? "false" : "right",
render: (text, record, index) => {
@ -204,6 +196,24 @@ class RecordListPage extends BaseListPage {
);
},
},
{
title: i18next.t("general:Action"),
dataIndex: "action",
key: "action",
width: "80px",
sorter: true,
fixed: "right",
render: (text, record, index) => (
<Button type="link" onClick={() => {
this.setState({
detailRecord: record,
detailShow: true,
});
}}>
{i18next.t("general:Detail")}
</Button>
),
},
];
if (Setting.isLocalAdminUser(this.props.account)) {
@ -220,7 +230,7 @@ class RecordListPage extends BaseListPage {
return (
<div>
<Table scroll={{x: "max-content"}} columns={columns} dataSource={records} rowKey="id" size="middle" bordered pagination={paginationProps}
<Table scroll={{x: "100%"}} columns={columns} dataSource={records} rowKey="id" size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Records")}&nbsp;&nbsp;&nbsp;&nbsp;
@ -229,10 +239,79 @@ class RecordListPage extends BaseListPage {
loading={this.state.loading}
onChange={this.handleTableChange}
/>
{/* TODO: Should be packaged as a component after confirm it run correctly.*/}
<Drawer
title={i18next.t("general:Detail")}
width={Setting.isMobile() ? "100%" : 640}
placement="right"
destroyOnClose
onClose={() => this.setState({detailShow: false})}
open={this.state.detailShow}
>
<Descriptions bordered size="small" column={1} layout={Setting.isMobile() ? "vertical" : "horizontal"} style={{padding: "12px", height: "100%", overflowY: "auto"}}>
<Descriptions.Item label={i18next.t("general:ID")}>{this.getDetailField("id")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("general:Client IP")}>{this.getDetailField("clientIp")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("general:Timestamp")}>{this.getDetailField("createdTime")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("general:Organization")}>
<Link to={`/organizations/${this.getDetailField("organization")}`}>
{this.getDetailField("organization")}
</Link>
</Descriptions.Item>
<Descriptions.Item label={i18next.t("general:User")}>
<Link to={`/users/${this.getDetailField("organization")}/${this.getDetailField("user")}`}>
{this.getDetailField("user")}
</Link>
</Descriptions.Item>
<Descriptions.Item label={i18next.t("general:Method")}>{this.getDetailField("method")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("general:Request URI")}>{this.getDetailField("requestUri")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("user:Language")}>{this.getDetailField("language")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("record:Status code")}>{this.getDetailField("statusCode")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("general:Action")}>{this.getDetailField("action")}</Descriptions.Item>
<Descriptions.Item label={i18next.t("record:Response")}>
<Editor
value={this.getDetailField("response")}
fillHeight
fillWidth
maxWidth={this.getEditorMaxWidth()}
dark
readOnly
/>
</Descriptions.Item>
<Descriptions.Item label={i18next.t("record:Object")}>
<Editor
value={this.jsonStrFormatter(this.getDetailField("object"))}
lang="json"
fillHeight
fillWidth
maxWidth={this.getEditorMaxWidth()}
dark
readOnly
/>
</Descriptions.Item>
</Descriptions>
</Drawer>
</div>
);
}
getEditorMaxWidth = () => {
return Setting.isMobile() ? window.innerWidth - 60 : 475;
};
jsonStrFormatter = str => {
try {
return JSON.stringify(JSON.parse(str), null, 2);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
return str;
}
};
getDetailField = dataIndex => {
return this.state.detailRecord ? this.state.detailRecord?.[dataIndex] ?? "" : "";
};
fetch = (params = {}) => {
let field = params.searchedColumn, value = params.searchText;
const sortField = params.sortField, sortOrder = params.sortOrder;
@ -255,6 +334,8 @@ class RecordListPage extends BaseListPage {
},
searchText: params.searchText,
searchedColumn: params.searchedColumn,
detailShow: false,
detailRecord: null,
});
} else {
if (res.data.includes("Please login first")) {

View File

@ -106,8 +106,8 @@ class RoleListPage extends BaseListPage {
return (
<Upload {...props}>
<Button type="primary" size="small">
<UploadOutlined /> {i18next.t("user:Upload (.xlsx)")}
<Button icon={<UploadOutlined />} type="primary" size="small">
{i18next.t("user:Upload (.xlsx)")}
</Button>
</Upload>
);

View File

@ -416,6 +416,12 @@ export const OtherProviderInfo = {
url: "https://www.cucloud.cn/",
},
},
"Face ID": {
"Alibaba Cloud Facebody": {
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
url: "https://vision.aliyun.com/facebody",
},
},
};
export function initCountries() {
@ -1150,6 +1156,10 @@ export function getProviderTypeOptions(category) {
{id: "Viber", name: "Viber"},
{id: "CUCloud", name: "CUCloud"},
]);
} else if (category === "Face ID") {
return ([
{id: "Alibaba Cloud Facebody", name: "Alibaba Cloud Facebody"},
]);
} else {
return [];
}

View File

@ -153,7 +153,7 @@ class TokenListPage extends BaseListPage {
title: i18next.t("token:Authorization code"),
dataIndex: "code",
key: "code",
// width: '150px',
width: "180px",
sorter: true,
...this.getColumnSearchProps("code"),
render: (text, record, index) => {
@ -164,7 +164,7 @@ class TokenListPage extends BaseListPage {
title: i18next.t("token:Access token"),
dataIndex: "accessToken",
key: "accessToken",
// width: '150px',
width: "220px",
sorter: true,
ellipsis: true,
...this.getColumnSearchProps("accessToken"),
@ -225,7 +225,7 @@ class TokenListPage extends BaseListPage {
return (
<div>
<Table scroll={{x: "max-content"}} columns={columns} dataSource={tokens} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
<Table scroll={{x: "100%"}} columns={columns} dataSource={tokens} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
title={() => (
<div>
{i18next.t("general:Tokens")}&nbsp;&nbsp;&nbsp;&nbsp;

View File

@ -1054,6 +1054,7 @@ class UserEditPage extends React.Component {
<FaceIdTable
title={i18next.t("user:Face IDs")}
table={this.state.user.faceIds}
{...this.props}
onUpdateTable={(table) => {this.updateUserField("faceIds", table);}}
/>
</Col>

View File

@ -188,8 +188,8 @@ class UserListPage extends BaseListPage {
return (
<Upload {...props}>
<Button id="upload-button" type="primary" size="small">
<UploadOutlined /> {i18next.t("user:Upload (.xlsx)")}
<Button icon={<UploadOutlined />} id="upload-button" type="primary" size="small">
{i18next.t("user:Upload (.xlsx)")}
</Button>
</Upload>
);

View File

@ -174,7 +174,16 @@ class WebhookEditPage extends React.Component {
renderWebhook() {
const preview = Setting.deepCopy(previewTemplate);
if (this.state.webhook.isUserExtended) {
preview["extendedUser"] = userTemplate;
if (this.state.webhook.tokenFields && this.state.webhook.tokenFields.length !== 0) {
const extendedUser = {};
this.state.webhook.tokenFields.forEach(field => {
const fieldTrans = field.replace(field[0], field[0].toLowerCase());
extendedUser[fieldTrans] = userTemplate[fieldTrans];
});
preview["extendedUser"] = extendedUser;
} else {
preview["extendedUser"] = userTemplate;
}
}
const previewText = JSON.stringify(preview, null, 2);
@ -295,6 +304,18 @@ class WebhookEditPage extends React.Component {
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("webhook:Extended user fields"), i18next.t("webhook:Extended user fields - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} mode="tags" showSearch style={{width: "100%"}} value={this.state.webhook.tokenFields} onChange={(value => {this.updateWebhookField("tokenFields", value);})}>
{
Setting.getUserCommonFields().map((item, index) => <Option key={index} value={item}>{item}</Option>)
}
</Select>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Preview"), i18next.t("general:Preview - Tooltip"))} :

View File

@ -471,9 +471,12 @@ class ForgetPage extends React.Component {
<React.Fragment>
<CustomGithubCorner />
<div className="forget-content" style={{padding: Setting.isMobile() ? "0" : null, boxShadow: Setting.isMobile() ? "none" : null}}>
<Button type="text" style={{position: "relative", left: Setting.isMobile() ? "10px" : "-90px", top: 0}} size={"large"} onClick={() => {this.stepBack();}}>
<ArrowLeftOutlined style={{fontSize: "24px"}} />
</Button>
<Button type="text"
style={{position: "relative", left: Setting.isMobile() ? "10px" : "-90px", top: 0}}
icon={<ArrowLeftOutlined style={{fontSize: "24px"}} />}
size={"large"}
onClick={() => {this.stepBack();}}
/>
<Row>
<Col span={24} style={{justifyContent: "center"}}>
<Row>

View File

@ -37,6 +37,7 @@ import RedirectForm from "../common/RedirectForm";
import {RequiredMfa} from "./mfa/MfaAuthVerifyForm";
import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
import * as ProviderButton from "./ProviderButton";
const FaceRecognitionCommonModal = lazy(() => import("../common/modal/FaceRecognitionCommonModal"));
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
class LoginPage extends React.Component {
@ -61,6 +62,7 @@ class LoginPage extends React.Component {
isTermsOfUseVisible: false,
termsOfUseContent: "",
orgChoiceMode: new URLSearchParams(props.location?.search).get("orgChoiceMode") ?? null,
userLang: null,
};
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
@ -262,6 +264,13 @@ class LoginPage extends React.Component {
onUpdateApplication(application) {
this.props.onUpdateApplication(application);
for (const idx in application.providers) {
const provider = application.providers[idx];
if (provider.provider?.category === "Face ID") {
this.setState({haveFaceIdProvider: true});
break;
}
}
}
parseOffset(offset) {
@ -415,6 +424,7 @@ class LoginPage extends React.Component {
login(values) {
// here we are supposed to determine whether Casdoor is working as an OAuth server or CAS server
values["language"] = this.state.userLang ?? "";
if (this.state.type === "cas") {
// CAS
const casParams = Util.getCasParameters();
@ -530,9 +540,11 @@ class LoginPage extends React.Component {
return null;
}
const resultItemKey = `${application.organization}_${application.name}_${signinItem.name}`;
if (signinItem.name === "Logo") {
return (
<div className="login-logo-box">
<div key={resultItemKey} className="login-logo-box">
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{
Setting.renderHelmet(application)
@ -544,7 +556,7 @@ class LoginPage extends React.Component {
);
} else if (signinItem.name === "Back button") {
return (
<div className="back-button">
<div key={resultItemKey} className="back-button">
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{
this.renderBackButton()
@ -562,14 +574,14 @@ class LoginPage extends React.Component {
}
return (
<div className="login-languages">
<div key={resultItemKey} className="login-languages">
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<LanguageSelect languages={application.organizationObj.languages} />
<LanguageSelect languages={application.organizationObj.languages} onClick={key => {this.setState({userLang: key});}} />
</div>
);
} else if (signinItem.name === "Signin methods") {
return (
<div>
<div key={resultItemKey}>
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{this.renderMethodChoiceBox()}
</div>
@ -577,7 +589,7 @@ class LoginPage extends React.Component {
;
} else if (signinItem.name === "Username") {
return (
<div>
<div key={resultItemKey}>
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<Form.Item
name="username"
@ -654,14 +666,14 @@ class LoginPage extends React.Component {
);
} else if (signinItem.name === "Password") {
return (
<div>
<div key={resultItemKey}>
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{this.renderPasswordOrCodeInput(signinItem)}
</div>
);
} else if (signinItem.name === "Forgot password?") {
return (
<div>
<div key={resultItemKey}>
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<div className="login-forget-password">
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
@ -679,7 +691,7 @@ class LoginPage extends React.Component {
return AgreementModal.isAgreementRequired(application) ? AgreementModal.renderAgreementFormItem(application, true, {}, this) : null;
} else if (signinItem.name === "Login button") {
return (
<Form.Item className="login-button-box">
<Form.Item key={resultItemKey} className="login-button-box">
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<Button
type="primary"
@ -694,19 +706,25 @@ class LoginPage extends React.Component {
</Button>
{
this.state.loginMethod === "faceId" ?
<Suspense fallback={null}>
<FaceRecognitionModal
visible={this.state.openFaceRecognitionModal}
onOk={(faceId) => {
const values = this.state.values;
values["faceId"] = faceId;
this.state.haveFaceIdProvider ? <Suspense fallback={null}><FaceRecognitionCommonModal visible={this.state.openFaceRecognitionModal} onOk={(FaceIdImage) => {
const values = this.state.values;
values["FaceIdImage"] = FaceIdImage;
this.login(values);
this.setState({openFaceRecognitionModal: false});
}} onCancel={() => this.setState({openFaceRecognitionModal: false})} /></Suspense> :
<Suspense fallback={null}>
<FaceRecognitionModal
visible={this.state.openFaceRecognitionModal}
onOk={(faceId) => {
const values = this.state.values;
values["faceId"] = faceId;
this.login(values);
this.setState({openFaceRecognitionModal: false});
}}
onCancel={() => this.setState({openFaceRecognitionModal: false})}
/>
</Suspense>
this.login(values);
this.setState({openFaceRecognitionModal: false});
}}
onCancel={() => this.setState({openFaceRecognitionModal: false})}
/>
</Suspense>
:
<>
</>
@ -723,13 +741,13 @@ class LoginPage extends React.Component {
}
return (
<div>
<div key={resultItemKey}>
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<Form.Item>
{
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map((providerItem, id) => {
return (
<span key ={id} onClick={(e) => {
<span key={id} onClick={(e) => {
const agreementChecked = this.form.current.getFieldValue("agreement");
if (agreementChecked !== undefined && typeof agreementChecked === "boolean" && !agreementChecked) {
@ -752,11 +770,11 @@ class LoginPage extends React.Component {
);
} else if (signinItem.name.startsWith("Text ") || signinItem?.isCustom) {
return (
<div dangerouslySetInnerHTML={{__html: signinItem.customCss}} />
<div key={resultItemKey} dangerouslySetInnerHTML={{__html: signinItem.customCss}} />
);
} else if (signinItem.name === "Signup link") {
return (
<div style={{width: "100%"}} className="login-signup-link">
<div key={resultItemKey} style={{width: "100%"}} className="login-signup-link">
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{this.renderFooter(application, signinItem)}
</div>
@ -803,7 +821,6 @@ class LoginPage extends React.Component {
<Form
name="normal_login"
initialValues={{
organization: application.organization,
application: application.name,
autoSignin: true,

View File

@ -387,7 +387,8 @@ export function getAuthUrl(application, provider, method, code) {
}
let endpoint = authInfo[provider.type].endpoint;
let redirectUri = `${window.location.origin}/callback`;
const redirectOrigin = application.forcedRedirectOrigin ? application.forcedRedirectOrigin : window.location.origin;
let redirectUri = `${redirectOrigin}/callback`;
let scope = authInfo[provider.type].scope;
const isShortState = (provider.type === "WeChat" && navigator.userAgent.includes("MicroMessenger")) || (provider.type === "Twitter");
const state = Util.getStateFromQueryParams(application.name, provider.name, method, isShortState);
@ -398,7 +399,7 @@ export function getAuthUrl(application, provider, method, code) {
endpoint = endpoint.replace("common", provider.domain);
}
} else if (provider.type === "Apple") {
redirectUri = `${window.location.origin}/api/callback`;
redirectUri = `${redirectOrigin}/api/callback`;
} else if (provider.type === "Google" && provider.disableSsl) {
scope += "+https://www.googleapis.com/auth/user.phonenumbers.read";
}
@ -420,13 +421,13 @@ export function getAuthUrl(application, provider, method, code) {
} else if (provider.type === "AzureADB2C") {
return `https://${provider.domain}.b2clogin.com/${provider.domain}.onmicrosoft.com/${provider.appId}/oauth2/v2.0/authorize?client_id=${provider.clientId}&nonce=defaultNonce&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&response_type=code&state=${state}&prompt=login`;
} else if (provider.type === "DingTalk") {
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&prompt=consent&state=${state}`;
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&prompt=login%20consent&state=${state}`;
} else if (provider.type === "WeChat") {
if (navigator.userAgent.includes("MicroMessenger")) {
return `${authInfo[provider.type].mpEndpoint}?appid=${provider.clientId2}&redirect_uri=${redirectUri}&state=${state}&scope=${authInfo[provider.type].mpScope}&response_type=code#wechat_redirect`;
} else {
if (provider.clientId2 && provider?.disableSsl && provider?.signName === "media") {
return `${window.location.origin}/callback?state=${state}&code=${"wechat_oa:" + code}`;
return `${redirectOrigin}/callback?state=${state}&code=${"wechat_oa:" + code}`;
}
return `${endpoint}?appid=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&state=${state}#wechat_redirect`;
}
@ -469,7 +470,7 @@ export function getAuthUrl(application, provider, method, code) {
} else if (provider.type === "Apple") {
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code%20id_token&scope=${scope}&response_mode=form_post`;
} else if (provider.type === "Steam") {
return `${endpoint}?openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.realm=${window.location.origin}&openid.return_to=${redirectUri}?state=${state}`;
return `${endpoint}?openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.realm=${redirectOrigin}&openid.return_to=${redirectUri}?state=${state}`;
} else if (provider.type === "Okta") {
return `${provider.domain}/v1/authorize?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
} else if (provider.type === "Douyin" || provider.type === "TikTok") {

View File

@ -167,25 +167,35 @@ const Dashboard = (props) => {
};
myChart.setOption(option);
const cardStyles = {
body: {
width: Setting.isMobile() ? "340px" : "100%",
height: Setting.isMobile() ? "100px" : "150px",
display: "flex",
alignItems: "center",
justifyContent: "center",
},
};
return (
<Row id="statistic" gutter={80} justify={"center"}>
<Col span={50} style={{marginBottom: "10px"}}>
<Card bordered={false} bodyStyle={{width: Setting.isMobile() ? "340px" : "100%", height: Setting.isMobile() ? "100px" : "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
<Card variant="borderless" styles={cardStyles}>
<Statistic title={i18next.t("home:Total users")} fontSize="100px" value={dashboardData.userCounts[30]} valueStyle={{fontSize: "30px"}} style={{width: "200px", paddingLeft: "10px"}} />
</Card>
</Col>
<Col span={50} style={{marginBottom: "10px"}}>
<Card bordered={false} bodyStyle={{width: Setting.isMobile() ? "340px" : "100%", height: Setting.isMobile() ? "100px" : "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
<Card variant="borderless" styles={cardStyles}>
<Statistic title={i18next.t("home:New users today")} fontSize="100px" value={dashboardData.userCounts[30] - dashboardData.userCounts[30 - 1]} valueStyle={{fontSize: "30px"}} prefix={<ArrowUpOutlined />} style={{width: "200px", paddingLeft: "10px"}} />
</Card>
</Col>
<Col span={50} style={{marginBottom: "10px"}}>
<Card bordered={false} bodyStyle={{width: Setting.isMobile() ? "340px" : "100%", height: Setting.isMobile() ? "100px" : "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
<Card variant="borderless" styles={cardStyles}>
<Statistic title={i18next.t("home:New users past 7 days")} value={dashboardData.userCounts[30] - dashboardData.userCounts[30 - 7]} valueStyle={{fontSize: "30px"}} prefix={<ArrowUpOutlined />} style={{width: "200px", paddingLeft: "10px"}} />
</Card>
</Col>
<Col span={50} style={{marginBottom: "10px"}}>
<Card bordered={false} bodyStyle={{width: Setting.isMobile() ? "340px" : "100%", height: Setting.isMobile() ? "100px" : "150px", display: "flex", alignItems: "center", justifyContent: "center"}}>
<Card variant="borderless" styles={cardStyles}>
<Statistic title={i18next.t("home:New users past 30 days")} value={dashboardData.userCounts[30] - dashboardData.userCounts[30 - 30]} valueStyle={{fontSize: "30px"}} prefix={<ArrowUpOutlined />} style={{width: "200px", paddingLeft: "10px"}} />
</Card>
</Col>

View File

@ -31,12 +31,12 @@ const GridCards = (props) => {
return (
Setting.isMobile() ? (
<Card bodyStyle={{padding: 0}}>
<Card styles={{body: {padding: 0}}}>
{items.map(item => <SingleCard key={item.link} logo={item.logo} link={item.link} title={item.name} desc={item.description} isSingle={items.length === 1} />)}
</Card>
) : (
<div style={{margin: "0 15px"}}>
<Row>
<div style={{width: "100%", padding: "0 100px"}}>
<Row style={{justifyContent: "center"}}>
{items.map(item => <SingleCard logo={item.logo} link={item.link} title={item.name} desc={item.description} time={item.createdTime} isSingle={items.length === 1} key={item.name} />)}
</Row>
</div>

View File

@ -18,10 +18,33 @@ import {materialDark} from "@uiw/codemirror-theme-material";
import {langs} from "@uiw/codemirror-extensions-langs";
export const Editor = (props) => {
const fillHeight = props.fillHeight ? {
height: "100%",
style: {height: "100%"},
} : {};
let style = {};
let height = props.height;
let width = props.width;
const copy2StyleProps = [
"width", "maxWidth", "minWidth",
"height", "maxHeight", "minHeight",
];
if (props.fillHeight) {
height = "100%";
style = {...style, height: "100%"};
}
if (props.fillWidth) {
width = "100%";
style = {...style, width: "100%"};
}
/**
* @uiw/react-codemirror style props sucha as "height" "width"
* may need to be configured with "style" in some scenarios to take effect
*/
copy2StyleProps.forEach(el => {
if (["number", "string"].includes(typeof props[el])) {
style = {...style, [el]: props[el]};
}
});
if (props.style) {
style = {...style, ...props.style};
}
let extensions = [];
switch (props.lang) {
case "javascript":
@ -37,13 +60,18 @@ export const Editor = (props) => {
case "xml":
extensions = [langs.xml()];
break;
case "json":
extensions = [langs.json()];
break;
}
return (
<CodeMirror
value={props.value}
height={props.height}
{...fillHeight}
{...props}
width={width}
height={height}
style={style}
readOnly={props.readOnly}
theme={props.dark ? materialDark : "light"}
extensions={extensions}

View File

@ -2,7 +2,7 @@ import i18next from "i18next";
import {Tree} from "antd";
import React from "react";
export const NavItemTree = ({disable, checkedKeys, defaultExpandedKeys, onCheck}) => {
export const NavItemTree = ({disabled, checkedKeys, defaultExpandedKeys, onCheck}) => {
const NavItemNodes = [
{
title: i18next.t("organization:All"),
@ -86,7 +86,7 @@ export const NavItemTree = ({disable, checkedKeys, defaultExpandedKeys, onCheck}
return (
<Tree
disabled={disable}
disabled={disabled}
checkable
checkedKeys={checkedKeys}
defaultExpandedKeys={defaultExpandedKeys}

View File

@ -51,6 +51,8 @@ function testEmailProvider(provider, email = "") {
receivers: email === "" ? ["TestSmtpServer"] : [email],
provider: provider.name,
providerObject: provider,
owner: provider.owner,
name: provider.name,
};
return fetch(`${Setting.ServerUrl}/api/send-email`, {

View File

@ -16,7 +16,7 @@ import * as Setting from "../Setting";
import i18next from "i18next";
export function sendTestNotification(provider) {
testNotificationProvider(provider.content, provider.name)
testNotificationProvider(provider)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully sent"));
@ -29,12 +29,14 @@ export function sendTestNotification(provider) {
});
}
function testNotificationProvider(content, name) {
function testNotificationProvider(provider) {
const notificationForm = {
content: content,
content: provider.content,
owner: provider.owner,
name: provider.name,
};
return fetch(`${Setting.ServerUrl}/api/send-notification?provider=${name}`, {
return fetch(`${Setting.ServerUrl}/api/send-notification?provider=${provider.name}`, {
method: "POST",
credentials: "include",
body: JSON.stringify(notificationForm),

View File

@ -33,6 +33,8 @@ function testSmsProvider(provider, phone = "") {
const SmsForm = {
content: "123456",
receivers: [phone],
owner: provider.owner,
name: provider.name,
};
return fetch(`${Setting.ServerUrl}/api/send-sms?provider=` + provider.name, {

View File

@ -0,0 +1,29 @@
import i18next from "i18next";
import {Tree} from "antd";
import React from "react";
export const WidgetItemTree = ({disabled, checkedKeys, defaultExpandedKeys, onCheck}) => {
const WidgetItemNodes = [
{
title: i18next.t("organization:All"),
key: "all",
children: [
{title: i18next.t("general:Tour"), key: "tour"},
{title: i18next.t("general:AI Assistant"), key: "ai-assistant"},
{title: i18next.t("user:Language"), key: "language"},
{title: i18next.t("theme:Theme"), key: "theme"},
],
},
];
return (
<Tree
disabled={disabled}
checkable
checkedKeys={checkedKeys}
defaultExpandedKeys={defaultExpandedKeys}
onCheck={onCheck}
treeData={WidgetItemNodes}
/>
);
};

View File

@ -0,0 +1,177 @@
// Copyright 2025 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {Button, Modal, Progress, message} from "antd";
import React, {useState} from "react";
import i18next from "i18next";
const FaceRecognitionCommonModal = (props) => {
const {visible, onOk, onCancel} = props;
const videoRef = React.useRef();
const canvasRef = React.useRef();
const [percent, setPercent] = useState(0);
const mediaStreamRef = React.useRef(null);
const [isCameraCaptured, setIsCameraCaptured] = useState(false);
const [capturedImageArray, setCapturedImageArray] = useState([]);
React.useEffect(() => {
if (isCameraCaptured) {
let count = 0;
let count2 = 0;
const interval = setInterval(() => {
count++;
if (videoRef.current) {
videoRef.current.srcObject = mediaStreamRef.current;
videoRef.current.play();
const interval2 = setInterval(() => {
if (!visible) {
clearInterval(interval);
setPercent(0);
}
count2++;
if (count2 >= 8) {
clearInterval(interval2);
setPercent(0);
onOk(capturedImageArray);
} else if (count2 > 3) {
setPercent((count2 - 4) * 20);
const canvas = document.createElement("canvas");
canvas.width = videoRef.current.videoWidth;
canvas.height = videoRef.current.videoHeight;
const context = canvas.getContext("2d");
context.drawImage(videoRef.current, 0, 0, canvas.width, canvas.height);
const b64 = canvas.toDataURL("image/png");
capturedImageArray.push(b64);
setCapturedImageArray(capturedImageArray);
}
}, 1000);
clearInterval(interval);
}
if (count >= 30) {
clearInterval(interval);
}
}, 100);
} else {
mediaStreamRef.current?.getTracks().forEach(track => track.stop());
if (videoRef.current) {
videoRef.current.srcObject = null;
}
}
}, [isCameraCaptured]);
React.useEffect(() => {
if (visible) {
navigator.mediaDevices
.getUserMedia({video: {facingMode: "user"}})
.then((stream) => {
mediaStreamRef.current = stream;
setIsCameraCaptured(true);
}).catch((error) => {
handleCameraError(error);
});
} else {
setIsCameraCaptured(false);
setCapturedImageArray([]);
}
}, [visible]);
const handleCameraError = (error) => {
if (error instanceof DOMException) {
if (error.name === "NotFoundError" || error.name === "DevicesNotFoundError") {
message.error(i18next.t("login:Please ensure that you have a camera device for facial recognition"));
} else if (error.name === "NotAllowedError" || error.name === "PermissionDeniedError") {
message.error(i18next.t("login:Please provide permission to access the camera"));
} else if (error.name === "NotReadableError" || error.name === "TrackStartError") {
message.error(i18next.t("login:The camera is currently in use by another webpage"));
} else if (error.name === "TypeError") {
message.error(i18next.t("login:Please load the webpage using HTTPS, otherwise the camera cannot be accessed"));
} else {
message.error(error.message);
}
}
};
return <div>
<Modal
closable={false}
maskClosable={false}
title={i18next.t("login:Face Recognition")}
width={350}
footer={[
<Button key="ok" type={"primary"} disabled={capturedImageArray.length === 0} onClick={() => {
onOk(capturedImageArray);
}}>
Ok
</Button>,
<Button key="back" onClick={onCancel}>
Cancel
</Button>,
]}
destroyOnClose={true}
open={visible}>
<Progress percent={percent} />
<div style={{
marginTop: "20px",
marginBottom: "50px",
justifyContent: "center",
alignContent: "center",
position: "relative",
flexDirection: "column",
}}>
{
<div style={{display: "flex", justifyContent: "center", alignContent: "center"}}>
<video
ref={videoRef}
style={{
borderRadius: "50%",
height: "220px",
verticalAlign: "middle",
width: "220px",
objectFit: "cover",
}}
></video>
<div style={{
position: "absolute",
width: "240px",
height: "240px",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
}}>
<svg width="240" height="240" fill="none">
<circle
strokeDasharray="700"
strokeDashoffset={700 - 6.9115 * percent}
strokeWidth="4"
cx="120"
cy="120"
r="110"
stroke="#5734d3"
transform="rotate(-90, 120, 120)"
strokeLinecap="round"
style={{transition: "all .2s linear"}}
></circle>
</svg>
</div>
<canvas ref={canvasRef} style={{position: "absolute"}} />
</div>
}
</div>
</Modal>
</div>;
};
export default FaceRecognitionCommonModal;

View File

@ -14,11 +14,12 @@
import * as faceapi from "face-api.js";
import React, {useState} from "react";
import {Button, Modal, Progress, Spin, message} from "antd";
import {Button, Modal, Progress, Space, Spin, message} from "antd";
import i18next from "i18next";
import Dragger from "antd/es/upload/Dragger";
const FaceRecognitionModal = (props) => {
const {visible, onOk, onCancel} = props;
const {visible, onOk, onCancel, withImage} = props;
const [modelsLoaded, setModelsLoaded] = React.useState(false);
const [isCameraCaptured, setIsCameraCaptured] = useState(false);
@ -28,6 +29,10 @@ const FaceRecognitionModal = (props) => {
const mediaStreamRef = React.useRef(null);
const [percent, setPercent] = useState(0);
const [files, setFiles] = useState([]);
const [currentFaceId, setCurrentFaceId] = React.useState();
const [currentFaceIndex, setCurrentFaceIndex] = React.useState();
React.useEffect(() => {
const loadModels = async() => {
// const MODEL_URL = process.env.PUBLIC_URL + "/models";
@ -50,6 +55,9 @@ const FaceRecognitionModal = (props) => {
}, []);
React.useEffect(() => {
if (withImage) {
return;
}
if (visible) {
setPercent(0);
if (modelsLoaded) {
@ -75,6 +83,9 @@ const FaceRecognitionModal = (props) => {
}, [visible, modelsLoaded]);
React.useEffect(() => {
if (withImage) {
return;
}
if (isCameraCaptured) {
let count = 0;
const interval = setInterval(() => {
@ -98,6 +109,9 @@ const FaceRecognitionModal = (props) => {
}, [isCameraCaptured]);
const handleStreamVideo = () => {
if (withImage) {
return;
}
let count = 0;
let goodCount = 0;
if (!detection.current) {
@ -148,73 +162,163 @@ const FaceRecognitionModal = (props) => {
}
};
return (
<div>
<Modal
closable={false}
const getBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
};
if (!withImage) {
return (
<div>
<Modal
closable={false}
maskClosable={false}
destroyOnClose={true}
open={visible && isCameraCaptured}
title={i18next.t("login:Face Recognition")}
width={350}
footer={[
<Button key="back" onClick={onCancel}>
Cancel
</Button>,
]}
>
<Progress percent={percent} />
<div style={{
marginTop: "20px",
marginBottom: "50px",
justifyContent: "center",
alignContent: "center",
position: "relative",
flexDirection: "column",
}}>
{
modelsLoaded ?
<div style={{display: "flex", justifyContent: "center", alignContent: "center"}}>
<video
ref={videoRef}
onPlay={handleStreamVideo}
style={{
borderRadius: "50%",
height: "220px",
verticalAlign: "middle",
width: "220px",
objectFit: "cover",
}}
></video>
<div style={{
position: "absolute",
width: "240px",
height: "240px",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
}}>
<svg width="240" height="240" fill="none">
<circle
strokeDasharray="700"
strokeDashoffset={700 - 6.9115 * percent}
strokeWidth="4"
cx="120"
cy="120"
r="110"
stroke="#5734d3"
transform="rotate(-90, 120, 120)"
strokeLinecap="round"
style={{transition: "all .2s linear"}}
></circle>
</svg>
</div>
<canvas ref={canvasRef} style={{position: "absolute"}} />
</div>
:
<div>
<Spin tip={i18next.t("login:Loading")} size="large"
style={{display: "flex", justifyContent: "center", alignContent: "center"}}>
<div className="content" />
</Spin>
</div>
}
</div>
</Modal>
</div>
);
} else {
return <div>
<Modal closable={false}
maskClosable={false}
destroyOnClose={true}
open={visible && isCameraCaptured}
open={visible}
title={i18next.t("login:Face Recognition")}
width={350}
footer={[
<Button key="back" onClick={onCancel}>
Cancel
<Button key="ok" type={"primary"} disabled={!currentFaceId || currentFaceId?.length === 0} onClick={() => {
onOk(Array.from(currentFaceId.descriptor));
}}>
Ok
</Button>,
]}
>
<Progress percent={percent} />
<div style={{marginTop: "20px", marginBottom: "50px", justifyContent: "center", alignContent: "center", position: "relative", flexDirection: "column"}}>
<Button key="back" onClick={onCancel}>
Cancel
</Button>,
]}>
<Space direction={"vertical"} style={{width: "100%"}}>
<Dragger
multiple={true}
defaultFileList={files}
style={{width: "100%"}}
beforeUpload={(file) => {
getBase64(file).then(res => {
file.base64 = res;
files.push(file);
});
setCurrentFaceId([]);
return false;
}}
onRemove={(file) => {
const index = files.indexOf(file);
const newFileList = files.slice();
newFileList.splice(index, 1);
setFiles(newFileList);
setCurrentFaceId([]);
}}
>
<p>{i18next.t("general:Click to Upload")}</p>
</Dragger >
{
modelsLoaded ?
<div style={{display: "flex", justifyContent: "center", alignContent: "center"}}>
<video
ref={videoRef}
onPlay={handleStreamVideo}
style={{
borderRadius: "50%",
height: "220px",
verticalAlign: "middle",
width: "220px",
objectFit: "cover",
}}
></video>
<div style={{
position: "absolute",
width: "240px",
height: "240px",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
}}>
<svg width="240" height="240" fill="none">
<circle
strokeDasharray="700"
strokeDashoffset={700 - 6.9115 * percent}
strokeWidth="4"
cx="120"
cy="120"
r="110"
stroke="#5734d3"
transform="rotate(-90, 120, 120)"
strokeLinecap="round"
style={{transition: "all .2s linear"}}
></circle>
</svg>
</div>
<canvas ref={canvasRef} style={{position: "absolute"}} />
</div>
:
<div>
<Spin tip={i18next.t("login:Loading")} size="large" style={{display: "flex", justifyContent: "center", alignContent: "center"}}>
<div className="content" />
</Spin>
</div>
modelsLoaded ? <Button style={{width: "100%"}} onClick={async() => {
let maxScore = 0;
for (const file of files) {
const fileIndex = files.indexOf(file);
const img = new Image();
img.src = file.base64;
const faceIds = await faceapi.detectAllFaces(img, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceDescriptors();
if (faceIds[0]?.detection.score > 0.9 && faceIds[0]?.detection.score > maxScore) {
maxScore = faceIds[0]?.detection.score;
setCurrentFaceId(faceIds[0]);
setCurrentFaceIndex(fileIndex);
}
}
if (maxScore < 0.9) {
message.error(i18next.t("login:Face recognition failed"));
}
}}> {i18next.t("application:Generate Face ID")}</Button> : null
}
</div>
</Space>
{
currentFaceId && currentFaceId.length !== 0 ? (
<React.Fragment>
<div>{i18next.t("application:Select")}:{files[currentFaceIndex]?.name}</div>
<div><img src={files[currentFaceIndex]?.base64} alt="selected" style={{width: "100%"}} /></div>
</React.Fragment>
) : null
}
</Modal>
</div>
);
</div>;
}
};
export default FaceRecognitionModal;

View File

@ -30,6 +30,7 @@ class LanguageSelect extends React.Component {
this.state = {
classes: props,
languages: props.languages ?? Setting.Countries.map(item => item.key),
onClick: props.onClick,
};
Setting.Countries.forEach((country) => {
@ -50,6 +51,9 @@ class LanguageSelect extends React.Component {
render() {
const languageItems = this.getOrganizationLanguages(this.state.languages);
const onClick = (e) => {
if (typeof this.state.onClick === "function") {
this.state.onClick(e.key);
}
Setting.setLanguage(e.key);
};

View File

@ -70,6 +70,7 @@ function OrganizationSelect(props) {
<Select
options={getOrganizationItems()}
virtual={false}
popupMatchSelectWidth={false}
placeholder={i18next.t("login:Please select an organization")}
value={value}
onChange={handleOnChange}

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Použít stejnou DB jako Casdoor"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Vždy",
"Auto signin": "Automatické přihlášení",
"Auto signin - Tooltip": "Když existuje přihlášená relace v Casdoor, je automaticky použita pro přihlášení na straně aplikace",
"Background URL": "URL pozadí",
"Background URL - Tooltip": "URL obrázku pozadí použitého na přihlašovací stránce",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Velká ikona",
"Binding providers": "Propojení poskytovatelé",
"CSS style": "CSS styl",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Přizpůsobit patičku vaší aplikace",
"Form position": "Pozice formuláře",
"Form position - Tooltip": "Umístění formulářů pro registraci, přihlášení a zapomenuté heslo",
"Generate Face ID": "Generate Face ID",
"Grant types": "Typy grantů",
"Grant types - Tooltip": "Vyberte, které typy grantů jsou povoleny v OAuth protokolu",
"Header HTML": "HTML hlavičky",
@ -189,6 +194,7 @@
"Verify": "Ověřit"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API klíč",
"API key - Tooltip": "API klíč - Tooltip",
"Access key": "Přístupový klíč",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Název tabulky úložiště politiky",
"Adapters": "Adaptéry",
"Add": "Přidat",
"Add Face Id": "Přidat Face Id",
"Add custom item": "Přidat vlastní položku",
"Admin": "Admin",
"Affiliation URL": "URL přidružení",
@ -231,6 +236,7 @@
"Created time": "Čas vytvoření",
"Custom": "Vlastní",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Výchozí",
"Default application": "Výchozí aplikace",
"Default application - Tooltip": "Výchozí aplikace pro uživatele registrované přímo ze stránky organizace",
@ -241,6 +247,7 @@
"Delete": "Smazat",
"Description": "Popis",
"Description - Tooltip": "Podrobný popis pro referenci, Casdoor sám o sobě jej nepoužívá",
"Detail": "详情",
"Disable": "Zakázat",
"Display name": "Zobrazované jméno",
"Display name - Tooltip": "Uživatelsky přívětivé, snadno čitelné jméno zobrazené veřejně v UI",
@ -258,7 +265,6 @@
"Enabled": "Povoleno",
"Enabled successfully": "Úspěšně povoleno",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Nepodařilo se přidat",
"Failed to connect to server": "Nepodařilo se připojit k serveru",
"Failed to delete": "Nepodařilo se smazat",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Telefonní číslo",
"Phone only": "Pouze telefon",
"Phone or Email": "Telefon nebo Email",
"Plain": "Plain",
"Plan": "Plán",
"Plan - Tooltip": "Plán - Tooltip",
"Plans": "Plány",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Skutečné jméno",
"Records": "Záznamy",
"Request": "Request",
"Request URI": "Požadavek URI",
"Resources": "Zdroje",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "Toto je demo stránka pouze pro čtení!",
"Timestamp": "Časové razítko",
"Tokens": "Tokeny",
"Tour": "Tour",
"Transactions": "Transakce",
"Type": "Typ",
"Type - Tooltip": "Typ - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Nadřazená skupina - Tooltip",
"Physical": "Fyzická",
"Show all": "Zobrazit vše",
"Virtual": "Virtuální"
"Virtual": "Virtuální",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "Noví uživatelé za posledních 30 dní",
@ -461,7 +471,8 @@
"Quota": "Kvóta",
"Quota - Tooltip": "Maximální počet uživatelů, kteří se mohou zaregistrovat pomocí tohoto pozvánkového kódu",
"Used count": "Počet použití",
"Used count - Tooltip": "Počet použití tohoto pozvánkového kódu"
"Used count - Tooltip": "Počet použití tohoto pozvánkového kódu",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Váš telefon je",
"preferred": "preferované"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Pokročilý editor",
"Basic Editor": "Základní editor",
@ -610,6 +616,8 @@
"Is profile public": "Je profil veřejný",
"Is profile public - Tooltip": "Po uzavření mohou profilovou stránku uživatele přistupovat pouze globální administrátoři nebo uživatelé ve stejné organizaci",
"Modify rule": "Upravit pravidlo",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "Nová organizace",
"Optional": "Volitelný",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Kolekce štítků dostupných pro uživatele k výběru",
"Use Email as username": "Použít email jako uživatelské jméno",
"Use Email as username - Tooltip": "Použít email jako uživatelské jméno, pokud není při registraci viditelné pole uživatelského jména",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "Zobrazit pravidlo",
"Visible": "Viditelné",
"Website URL": "URL webových stránek",
"Website URL - Tooltip": "Domovská URL organizace. Toto pole se v Casdoor nepoužívá"
"Website URL - Tooltip": "Domovská URL organizace. Toto pole se v Casdoor nepoužívá",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Potvrďte informace na faktuře",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "placený uživatel nemá aktivní předplatné nebo čekající předplatné, prosím vyberte plán k nákupu"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Koupit",
"Buy Product": "Koupit produkt",
@ -757,7 +770,6 @@
"Sold": "Prodáno",
"Sold - Tooltip": "Prodávané množství",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Štítek produktu",
"Test buy page..": "Testovací stránka nákupu..",
"There is no payment channel for this product.": "Pro tento produkt neexistuje žádný platební kanál.",
@ -817,6 +829,8 @@
"Edit Provider": "Upravit poskytovatele",
"Email content": "Obsah emailu",
"Email content - Tooltip": "Obsah emailu",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Název emailu",
"Email title - Tooltip": "Název emailu",
"Endpoint": "Koncový bod",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Text klíče",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Metoda přihlášení, QR kód nebo tiché přihlášení",
"New Provider": "Nový poskytovatel",
"Normal": "Normální",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Upravit Webhook",
"Events": "Události",
"Events - Tooltip": "Události",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Hlavičky",
"Headers - Tooltip": "HTTP hlavičky (klíč-hodnota)",
"Is user extended": "Jsou rozšířená data uživatele",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Immer",
"Auto signin": "Automatische Anmeldung",
"Auto signin - Tooltip": "Wenn eine angemeldete Session in Casdoor vorhanden ist, wird diese automatisch für die Anmeldung auf Anwendungsebene verwendet",
"Background URL": "Background-URL",
"Background URL - Tooltip": "URL des Hintergrundbildes, das auf der Anmeldeseite angezeigt wird",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Formposition",
"Form position - Tooltip": "Position der Anmelde-, Registrierungs- und Passwort-vergessen-Formulare",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant-Typen",
"Grant types - Tooltip": "Wählen Sie aus, welche Grant-Typen im OAuth-Protokoll zulässig sind",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "überprüfen"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Tabellenname des Policy Stores",
"Adapters": "Adapter",
"Add": "Hinzufügen",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Zugehörigkeits-URL",
@ -231,6 +236,7 @@
"Created time": "Erstellte Zeit",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Standard Anwendung",
"Default application - Tooltip": "Standard-Anwendung für Benutzer, die direkt von der Organisationsseite registriert wurden",
@ -241,6 +247,7 @@
"Delete": "Löschen",
"Description": "Beschreibung",
"Description - Tooltip": "Detaillierte Beschreibungsinformationen zur Referenz, Casdoor selbst wird es nicht verwenden",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Anzeigename",
"Display name - Tooltip": "Ein benutzerfreundlicher, leicht lesbarer Name, der öffentlich in der Benutzeroberfläche angezeigt wird",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Fehler beim hinzufügen",
"Failed to connect to server": "Die Verbindung zum Server konnte nicht hergestellt werden",
"Failed to delete": "Konnte nicht gelöscht werden",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Telefonnummer",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Pläne",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Echter Name",
"Records": "Datensätze",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Ressourcen",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "Dies ist eine schreibgeschützte Demo-Seite!",
"Timestamp": "Timestamp",
"Tokens": "Token",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Erweiterter Editor",
"Basic Editor": "Basis-Editor",
@ -610,6 +616,8 @@
"Is profile public": "Ist das Profil öffentlich?",
"Is profile public - Tooltip": "Nach der Schließung können nur globale Administratoren oder Benutzer in der gleichen Organisation auf die Profilseite des Benutzers zugreifen",
"Modify rule": "Regel ändern",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "Neue Organisation",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Sammlung von Tags, die für Benutzer zur Auswahl zur Verfügung stehen",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "Ansichtsregel",
"Visible": "Sichtbar",
"Website URL": "Website-URL",
"Website URL - Tooltip": "Die Homepage-URL der Organisation. Dieses Feld wird in Casdoor nicht verwendet"
"Website URL - Tooltip": "Die Homepage-URL der Organisation. Dieses Feld wird in Casdoor nicht verwendet",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Bestätigen Sie Ihre Rechnungsinformationen",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Kaufen",
"Buy Product": "Produkt kaufen",
@ -757,7 +770,6 @@
"Sold": "Verkauft",
"Sold - Tooltip": "Menge verkauft",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag des Produkts",
"Test buy page..": "Testkaufseite.",
"There is no payment channel for this product.": "Es gibt keinen Zahlungskanal für dieses Produkt.",
@ -817,6 +829,8 @@
"Edit Provider": "Provider bearbeiten",
"Email content": "Email-Inhalt",
"Email content - Tooltip": "Inhalt der E-Mail",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email-Titel",
"Email title - Tooltip": "Betreff der E-Mail",
"Endpoint": "Endpunkt",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadaten",
"Metadata - Tooltip": "SAML-Metadaten",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Anmeldeverfahren, QR-Code oder Silent-Login",
"New Provider": "Neuer Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Webhook bearbeiten",
"Events": "Ereignisse",
"Events - Tooltip": "Ereignisse",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Überschriften",
"Headers - Tooltip": "HTTP-Header (Schlüssel-Wert-Paare)",
"Is user extended": "Wurde der Benutzer erweitert?",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use the same DB as Casdoor"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "Detail",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "The maximum number of users that can register using this invitation code",
"Used count": "Used count",
"Used count - Tooltip": "The number of times this invitation code has been used"
"Used count - Tooltip": "The number of times this invitation code has been used",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "siempre",
"Auto signin": "Inicio de sesión automático",
"Auto signin - Tooltip": "Cuando existe una sesión iniciada en Casdoor, se utiliza automáticamente para el inicio de sesión del lado de la aplicación",
"Background URL": "URL de fondo",
"Background URL - Tooltip": "URL de la imagen de fondo utilizada en la página de inicio de sesión",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Posición de la Forma",
"Form position - Tooltip": "Ubicación de los formularios de registro, inicio de sesión y olvido de contraseña",
"Generate Face ID": "Generate Face ID",
"Grant types": "Tipos de subvenciones",
"Grant types - Tooltip": "Selecciona cuáles tipos de subvenciones están permitidas en el protocolo OAuth",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verificar"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Nombre de la tabla de la tienda de políticas",
"Adapters": "Adaptadores",
"Add": "Añadir",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "URL de afiliación",
@ -231,6 +236,7 @@
"Created time": "Tiempo creado",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Aplicación predeterminada",
"Default application - Tooltip": "Aplicación predeterminada para usuarios registrados directamente desde la página de la organización",
@ -241,6 +247,7 @@
"Delete": "Eliminar",
"Description": "Descripción",
"Description - Tooltip": "Información detallada de descripción para referencia, Casdoor en sí no la utilizará",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Nombre de pantalla",
"Display name - Tooltip": "Un nombre fácil de usar y leer que se muestra públicamente en la interfaz de usuario",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "No se pudo agregar",
"Failed to connect to server": "No se pudo conectar al servidor",
"Failed to delete": "No se pudo eliminar",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Número de teléfono",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Planes",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Nombre real",
"Records": "Registros",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Recursos",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "¡Este es un sitio de demostración solo de lectura!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Administrador",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Editor avanzado",
"Basic Editor": "Editor básico",
@ -610,6 +616,8 @@
"Is profile public": "Es el perfil público",
"Is profile public - Tooltip": "Después de estar cerrado, solo los administradores globales o usuarios de la misma organización pueden acceder a la página de perfil del usuario",
"Modify rule": "Modificar regla",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "Nueva organización",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Colección de etiquetas disponibles para que los usuarios elijan",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "Regla de visualización",
"Visible": "Visible - Visible",
"Website URL": "URL del sitio web",
"Website URL - Tooltip": "La URL de la página de inicio de la organización. Este campo no se usa en Casdoor"
"Website URL - Tooltip": "La URL de la página de inicio de la organización. Este campo no se usa en Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirma la información de tu factura",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Comprar",
"Buy Product": "Comprar producto",
@ -757,7 +770,6 @@
"Sold": "Vendido",
"Sold - Tooltip": "Cantidad vendida",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Etiqueta de producto",
"Test buy page..": "Página de compra de prueba.",
"There is no payment channel for this product.": "No hay canal de pago para este producto.",
@ -817,6 +829,8 @@
"Edit Provider": "Editar proveedor",
"Email content": "Contenido de correo electrónico",
"Email content - Tooltip": "Contenido del correo electrónico",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Título del correo electrónico",
"Email title - Tooltip": "Título del correo electrónico",
"Endpoint": "Punto final",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadatos",
"Metadata - Tooltip": "Metadatos SAML",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Método de inicio de sesión, código QR o inicio de sesión silencioso",
"New Provider": "Nuevo proveedor",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Editar Webhook",
"Events": "Eventos",
"Events - Tooltip": "Eventos",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Encabezados",
"Headers - Tooltip": "Encabezados de HTTP (pares de clave-valor)",
"Is user extended": "¿Está el usuario extendido?",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "استفاده از همان پایگاه داده به عنوان Casdoor"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "همیشه",
"Auto signin": "ورود خودکار",
"Auto signin - Tooltip": "هنگامی که یک جلسه ورود در Casdoor وجود دارد، به‌طور خودکار برای ورود به برنامه استفاده می‌شود",
"Background URL": "آدرس پس‌زمینه",
"Background URL - Tooltip": "آدرس تصویر پس‌زمینه استفاده شده در صفحه ورود",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "آیکون بزرگ",
"Binding providers": "اتصال ارائه‌دهندگان",
"CSS style": "استایل CSS",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "پاورقی برنامه خود را سفارشی کنید",
"Form position": "موقعیت فرم",
"Form position - Tooltip": "مکان فرم‌های ثبت‌نام، ورود و فراموشی رمز عبور",
"Generate Face ID": "Generate Face ID",
"Grant types": "نوع‌های اعطا",
"Grant types - Tooltip": "انتخاب کنید کدام نوع‌های اعطا در پروتکل OAuth مجاز هستند",
"Header HTML": "HTML سربرگ",
@ -189,6 +194,7 @@
"Verify": "تأیید"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "کلید API",
"API key - Tooltip": "کلید API - راهنمای ابزار",
"Access key": "کلید دسترسی",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "نام جدول فروشگاه سیاست",
"Adapters": "آداپتورها",
"Add": "افزودن",
"Add Face Id": "افزودن Face Id",
"Add custom item": "افزودن مورد سفارشی",
"Admin": "مدیر",
"Affiliation URL": "آدرس وابستگی",
@ -231,6 +236,7 @@
"Created time": "زمان ایجاد",
"Custom": "سفارشی",
"Dashboard": "داشبورد",
"Data": "Data",
"Default": "پیش‌فرض",
"Default application": "برنامه پیش‌فرض",
"Default application - Tooltip": "برنامه پیش‌فرض برای کاربرانی که مستقیماً از صفحه سازمان ثبت‌نام می‌کنند",
@ -241,6 +247,7 @@
"Delete": "حذف",
"Description": "توضیحات",
"Description - Tooltip": "اطلاعات توضیحات دقیق برای مرجع، خود Casdoor از آن استفاده نمی‌کند",
"Detail": "详情",
"Disable": "غیرفعال",
"Display name": "نام نمایشی",
"Display name - Tooltip": "نام کاربرپسند و قابل خواندن آسان که به‌صورت عمومی در رابط کاربری نمایش داده می‌شود",
@ -258,7 +265,6 @@
"Enabled": "فعال شده",
"Enabled successfully": "با موفقیت فعال شد",
"Enforcers": "Enforcerها",
"FaceIdData": "داده‌های FaceId",
"Failed to add": "عدم موفقیت در افزودن",
"Failed to connect to server": "عدم موفقیت در اتصال به سرور",
"Failed to delete": "عدم موفقیت در حذف",
@ -344,6 +350,7 @@
"Phone - Tooltip": "شماره تلفن",
"Phone only": "فقط تلفن",
"Phone or Email": "تلفن یا ایمیل",
"Plain": "Plain",
"Plan": "طرح",
"Plan - Tooltip": "طرح - راهنمای ابزار",
"Plans": "طرح‌ها",
@ -362,6 +369,7 @@
"QR code is too large": "کد QR بیش از حد بزرگ است",
"Real name": "نام واقعی",
"Records": "سوابق",
"Request": "Request",
"Request URI": "آدرس URI درخواست",
"Resources": "منابع",
"Role": "نقش",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "این یک سایت دمو فقط خواندنی است!",
"Timestamp": "مهر زمان",
"Tokens": "توکن‌ها",
"Tour": "Tour",
"Transactions": "تراکنش‌ها",
"Type": "نوع",
"Type - Tooltip": "نوع - راهنمای ابزار",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "گروه والد - راهنمای ابزار",
"Physical": "فیزیکی",
"Show all": "نمایش همه",
"Virtual": "مجازی"
"Virtual": "مجازی",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "کاربران جدید در ۳۰ روز گذشته",
@ -461,7 +471,8 @@
"Quota": "سهمیه",
"Quota - Tooltip": "حداکثر تعداد کاربرانی که می‌توانند با استفاده از این کد دعوت ثبت‌نام کنند",
"Used count": "تعداد استفاده شده",
"Used count - Tooltip": "تعداد دفعات استفاده از این کد دعوت"
"Used count - Tooltip": "تعداد دفعات استفاده از این کد دعوت",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "مدیر",
@ -586,11 +597,6 @@
"Your phone is": "تلفن شما",
"preferred": "مورد علاقه"
},
"mfaAccount": {
"Account Name": "نام حساب",
"Issuer": "صادرکننده",
"Secret Key": "کلید مخفی"
},
"model": {
"Advanced Editor": "ویرایشگر پیشرفته",
"Basic Editor": "ویرایشگر ابتدایی",
@ -610,6 +616,8 @@
"Is profile public": "پروفایل عمومی است",
"Is profile public - Tooltip": "پس از بسته شدن، فقط مدیران جهانی یا کاربران در همان سازمان می‌توانند به صفحه پروفایل کاربر دسترسی داشته باشند",
"Modify rule": "قانون اصلاح",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "سازمان جدید",
"Optional": "اختیاری",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "مجموعه‌ای از برچسب‌های موجود برای انتخاب کاربران",
"Use Email as username": "استفاده از ایمیل به‌عنوان نام کاربری",
"Use Email as username - Tooltip": "اگر فیلد نام کاربری در ثبت‌نام قابل مشاهده نباشد، از ایمیل به‌عنوان نام کاربری استفاده کنید",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "قانون مشاهده",
"Visible": "قابل مشاهده",
"Website URL": "آدرس وب‌سایت",
"Website URL - Tooltip": "آدرس صفحه اصلی سازمان. این فیلد در Casdoor استفاده نمی‌شود"
"Website URL - Tooltip": "آدرس صفحه اصلی سازمان. این فیلد در Casdoor استفاده نمی‌شود",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "اطلاعات فاکتور خود را تأیید کنید",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "کاربر پرداختی اشتراک فعال یا در انتظار ندارد، لطفاً یک طرح برای خرید انتخاب کنید"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "خرید",
"Buy Product": "خرید محصول",
@ -757,7 +770,6 @@
"Sold": "فروخته شده",
"Sold - Tooltip": "تعداد فروخته شده",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "برچسب محصول",
"Test buy page..": "صفحه تست خرید..",
"There is no payment channel for this product.": "برای این محصول کانال پرداختی وجود ندارد.",
@ -817,6 +829,8 @@
"Edit Provider": "ویرایش ارائه‌دهنده",
"Email content": "محتوای ایمیل",
"Email content - Tooltip": "محتوای ایمیل",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "عنوان ایمیل",
"Email title - Tooltip": "عنوان ایمیل",
"Endpoint": "نقطه پایانی",
@ -844,6 +858,8 @@
"Key text - Tooltip": "متن کلید",
"Metadata": "فراداده",
"Metadata - Tooltip": "فراداده SAML",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "روش ورود، کد QR یا ورود بی‌صدا",
"New Provider": "ارائه‌دهنده جدید",
"Normal": "عادی",
@ -1244,6 +1260,8 @@
"Edit Webhook": "ویرایش Webhook",
"Events": "رویدادها",
"Events - Tooltip": "رویدادها",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "هدرها",
"Headers - Tooltip": "هدرهای HTTP (کلید-مقدار)",
"Is user extended": "کاربر گسترش یافته است",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Toujours",
"Auto signin": "Connexion automatique",
"Auto signin - Tooltip": "Lorsqu'une session connectée existe dans Casdoor, elle est automatiquement utilisée pour la connexion côté application",
"Background URL": "URL de fond",
"Background URL - Tooltip": "L'URL de l'image d'arrière-plan utilisée sur la page de connexion",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Fournisseurs liés",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Position du formulaire",
"Form position - Tooltip": "Emplacement des formulaires d'inscription, de connexion et de récupération de mot de passe",
"Generate Face ID": "Generate Face ID",
"Grant types": "Types d'autorisation",
"Grant types - Tooltip": "Sélectionnez les types d'autorisations autorisés dans le protocole OAuth",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Vérifier"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "Clé API",
"API key - Tooltip": "Clé API - Info-bulle",
"Access key": "Clé d'accès",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Nom de la table du magasin de règle",
"Adapters": "Adaptateurs",
"Add": "Ajouter",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Administration",
"Affiliation URL": "URL d'affiliation",
@ -231,6 +236,7 @@
"Created time": "Date de création",
"Custom": "Personnalisée",
"Dashboard": "Tableau de bord",
"Data": "Data",
"Default": "Par défaut",
"Default application": "Application par défaut",
"Default application - Tooltip": "Application par défaut pour les comptes enregistrés directement depuis la page de l'organisation",
@ -241,6 +247,7 @@
"Delete": "Supprimer",
"Description": "Description",
"Description - Tooltip": "Description détaillée pour référence, Casdoor ne l'utilisera pas en soi",
"Detail": "详情",
"Disable": "Désactiver",
"Display name": "Nom d'affichage",
"Display name - Tooltip": "Un nom convivial et facilement lisible affiché publiquement dans l'interface utilisateur",
@ -258,7 +265,6 @@
"Enabled": "Activé",
"Enabled successfully": "Activé avec succès",
"Enforcers": "Exécuteurs",
"FaceIdData": "FaceIdData",
"Failed to add": "Échec d'ajout",
"Failed to connect to server": "Échec de la connexion au serveur",
"Failed to delete": "Échec de la suppression",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Numéro de téléphone",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Offre",
"Plan - Tooltip": "Offre - Infobulle",
"Plans": "Offres",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Nom complet",
"Records": "Enregistrements",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Ressources",
"Role": "Rôle",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "Ceci est un site de démonstration en lecture seule !",
"Timestamp": "Timestamp",
"Tokens": "Jetons",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Infobulle",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Groupe parent - Infobulle",
"Physical": "Physique",
"Show all": "Tout afficher",
"Virtual": "Virtuel"
"Virtual": "Virtuel",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "Comptes créés dans les 30 derniers jours",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Compte d'administration",
@ -586,11 +597,6 @@
"Your phone is": "Votre téléphone est",
"preferred": "préféré"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Éditeur avancé",
"Basic Editor": "Éditeur de base",
@ -610,6 +616,8 @@
"Is profile public": "Est-ce que le profil est public ?",
"Is profile public - Tooltip": "Après sa fermeture, seuls les administrateurs et administratrices globales ou les comptes de la même organisation peuvent accéder à la page de profil de l'utilisateur",
"Modify rule": "Règle de modification",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "Nouvelle organisation",
"Optional": "Optionnel",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection d'étiquettes disponibles pour les comptes",
"Use Email as username": "Utiliser l'e-mail comme identifiant",
"Use Email as username - Tooltip": "Utiliser l'adresse e-mail comme identifiant pour les comptes lorsque l'identifiant ne fait pas partie des champs d'inscription",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "Règle de visibilité",
"Visible": "Visible",
"Website URL": "URL du site web",
"Website URL - Tooltip": "URL du site web l'organisation. Ce champ n'est pas utilisé dans Casdoor"
"Website URL - Tooltip": "URL du site web l'organisation. Ce champ n'est pas utilisé dans Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirmez les informations de votre facture",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Acheter",
"Buy Product": "Acheter un produit",
@ -757,7 +770,6 @@
"Sold": "Vendu",
"Sold - Tooltip": "Quantité vendue",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Étiquette de produit",
"Test buy page..": "Page d'achat de test.",
"There is no payment channel for this product.": "Il n'y a aucun canal de paiement pour ce produit.",
@ -817,6 +829,8 @@
"Edit Provider": "Modifier le fournisseur",
"Email content": "Contenu de l'e-mail",
"Email content - Tooltip": "Contenu de l'e-mail",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Titre de l'email",
"Email title - Tooltip": "Titre de l'email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Métadonnées",
"Metadata - Tooltip": "Métadonnées SAML",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Méthode de connexion, code QR ou connexion silencieuse",
"New Provider": "Nouveau fournisseur",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Modifier le Webhook",
"Events": "Événements",
"Events - Tooltip": "Événements",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "En-têtes",
"Headers - Tooltip": "En-têtes HTTP (paires clé-valeur)",
"Is user extended": "Inclure les champs étendus",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Selalu",
"Auto signin": "Masuk otomatis",
"Auto signin - Tooltip": "Ketika sesi masuk yang terdaftar ada di Casdoor, secara otomatis digunakan untuk masuk ke sisi aplikasi",
"Background URL": "URL latar belakang",
"Background URL - Tooltip": "URL dari gambar latar belakang yang digunakan di halaman login",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Posisi formulir",
"Form position - Tooltip": "Tempat pendaftaran, masuk, dan lupa kata sandi",
"Generate Face ID": "Generate Face ID",
"Grant types": "Jenis-jenis hibah",
"Grant types - Tooltip": "Pilih jenis hibah apa yang diperbolehkan dalam protokol OAuth",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Memverifikasi"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Nama tabel dari penyimpanan kebijakan",
"Adapters": "Adaptor",
"Add": "Tambahkan",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "URL Afiliasi",
@ -231,6 +236,7 @@
"Created time": "Waktu dibuat",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Aplikasi default",
"Default application - Tooltip": "Aplikasi default untuk pengguna yang terdaftar langsung dari halaman organisasi",
@ -241,6 +247,7 @@
"Delete": "Hapus",
"Description": "Deskripsi",
"Description - Tooltip": "Informasi deskripsi terperinci untuk referensi, Casdoor itu sendiri tidak akan menggunakannya",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Nama tampilan",
"Display name - Tooltip": "Sebuah nama yang mudah digunakan dan mudah dibaca yang ditampilkan secara publik di UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Gagal menambahkan",
"Failed to connect to server": "Gagal terhubung ke server",
"Failed to delete": "Gagal menghapus",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Nomor telepon",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Rencana",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Nama asli",
"Records": "Catatan",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Sumber daya",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "Ini adalah situs demo hanya untuk dibaca saja!",
"Timestamp": "Timestamp",
"Tokens": "Token-token",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Editor lanjutan",
"Basic Editor": "Editor dasar",
@ -610,6 +616,8 @@
"Is profile public": "Apakah profilnya publik?",
"Is profile public - Tooltip": "Setelah ditutup, hanya administrator global atau pengguna di organisasi yang sama yang dapat mengakses halaman profil pengguna",
"Modify rule": "Mengubah aturan",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "Organisasi baru",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Kumpulan tag yang tersedia bagi pengguna untuk dipilih",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "Aturan tampilan",
"Visible": "Terlihat",
"Website URL": "URL situs web",
"Website URL - Tooltip": "URL halaman utama organisasi. Bidang ini tidak digunakan di Casdoor"
"Website URL - Tooltip": "URL halaman utama organisasi. Bidang ini tidak digunakan di Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Konfirmasikan informasi tagihan Anda",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Beli",
"Buy Product": "Beli Produk",
@ -757,7 +770,6 @@
"Sold": "Terjual",
"Sold - Tooltip": "Jumlah terjual",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag produk",
"Test buy page..": "Halaman pembelian uji coba.",
"There is no payment channel for this product.": "Tidak ada saluran pembayaran untuk produk ini.",
@ -817,6 +829,8 @@
"Edit Provider": "Ubah Penyedia Layanan",
"Email content": "Konten Email",
"Email content - Tooltip": "Isi Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Judul Email",
"Email title - Tooltip": "Judul email",
"Endpoint": "Titik akhir",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata: data yang menjelaskan atau memberikan informasi tentang data atau informasi digital lainnya, seperti informasi mengenai sumber data, format, waktu pembuatan, penulis, dan informasi lainnya yang dapat membantu dalam pengelolaan dan pemrosesan data",
"Metadata - Tooltip": "Metadata SAML",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Metode login, kode QR atau login tanpa suara",
"New Provider": "Penyedia Baru",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Mengedit Webhook",
"Events": "Acara-acara",
"Events - Tooltip": "Acara-acara",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "Header HTTP (pasangan kunci-nilai)",
"Is user extended": "Apakah pengguna diperpanjang?",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Sempre",
"Auto signin": "Accesso automatico",
"Auto signin - Tooltip": "Quando una sessione esiste in Casdoor, viene utilizzata automaticamente per il login lato applicazione",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "常に",
"Auto signin": "自動サインイン",
"Auto signin - Tooltip": "Casdoorにログインセッションが存在する場合、アプリケーション側のログインに自動的に使用されます",
"Background URL": "背景URL",
"Background URL - Tooltip": "ログインページで使用される背景画像のURL",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "フォームのポジション",
"Form position - Tooltip": "登録、ログイン、パスワード忘れフォームの位置",
"Generate Face ID": "Generate Face ID",
"Grant types": "グラント種類",
"Grant types - Tooltip": "OAuthプロトコルで許可されているグラントタイプを選択してください",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "検証"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "ポリシー・ストアのテーブル名",
"Adapters": "アダプター",
"Add": "追加",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "所属するURL",
@ -231,6 +236,7 @@
"Created time": "作成された時間",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "デフォルトアプリケーション",
"Default application - Tooltip": "組織ページから直接登録されたユーザーのデフォルトアプリケーション",
@ -241,6 +247,7 @@
"Delete": "削除",
"Description": "説明",
"Description - Tooltip": "参照用の詳細な説明情報です。Casdoor自体はそれを使用しません",
"Detail": "详情",
"Disable": "Disable",
"Display name": "表示名",
"Display name - Tooltip": "UIで公開されている使いやすく読みやすい名前",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "追加できませんでした",
"Failed to connect to server": "サーバーに接続できませんでした",
"Failed to delete": "削除に失敗しました",
@ -344,6 +350,7 @@
"Phone - Tooltip": "電話番号",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "プラン",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "本名",
"Records": "記録",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "リソース",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "これは読み取り専用のデモサイトです!",
"Timestamp": "Timestamp",
"Tokens": "トークン",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "管理者",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "プロフィールは公開されていますか?",
"Is profile public - Tooltip": "閉鎖された後、グローバル管理者または同じ組織のユーザーだけがユーザーのプロファイルページにアクセスできます",
"Modify rule": "ルールを変更する",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "新しい組織",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "ユーザーが選択できるタグのコレクション",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "ビュールール",
"Visible": "見える",
"Website URL": "ウェブサイトのURL",
"Website URL - Tooltip": "組織のホームページのURL。このフィールドはCasdoorでは使用されません"
"Website URL - Tooltip": "組織のホームページのURL。このフィールドはCasdoorでは使用されません",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "請求書の情報を確認してください",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "購入",
"Buy Product": "製品を購入する",
@ -757,7 +770,6 @@
"Sold": "売れました",
"Sold - Tooltip": "販売数量",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "製品のタグ",
"Test buy page..": "テスト購入ページ。",
"There is no payment channel for this product.": "この製品には支払いチャネルがありません。",
@ -817,6 +829,8 @@
"Edit Provider": "編集プロバイダー",
"Email content": "Eメールの内容",
"Email content - Tooltip": "メールの内容",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "電子メールのタイトル",
"Email title - Tooltip": "メールのタイトル",
"Endpoint": "エンドポイント",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "メタデータ",
"Metadata - Tooltip": "SAMLのメタデータ",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "ログイン方法、QRコードまたはサイレントログイン",
"New Provider": "新しい提供者",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Webhookを編集",
"Events": "イベント",
"Events - Tooltip": "イベント",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "ヘッダー",
"Headers - Tooltip": "HTTPヘッダーキー値ペア",
"Is user extended": "ユーザーが拡張されましたか?",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "항상",
"Auto signin": "자동 로그인",
"Auto signin - Tooltip": "카스도어에 로그인된 세션이 존재할 때, 애플리케이션 쪽 로그인에 자동으로 사용됩니다",
"Background URL": "배경 URL",
"Background URL - Tooltip": "로그인 페이지에서 사용된 배경 이미지의 URL",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "양식 위치",
"Form position - Tooltip": "가입, 로그인 및 비밀번호 재설정 양식의 위치",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types: 부여 유형",
"Grant types - Tooltip": "OAuth 프로토콜에서 허용되는 그란트 유형을 선택하십시오",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "검증하다"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "정책 저장소의 테이블 이름",
"Adapters": "어댑터",
"Add": "추가하다",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "소속 URL",
@ -231,6 +236,7 @@
"Created time": "작성한 시간",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "기본 애플리케이션",
"Default application - Tooltip": "조직 페이지에서 직접 등록한 사용자의 기본 응용 프로그램",
@ -241,6 +247,7 @@
"Delete": "삭제하기",
"Description": "설명",
"Description - Tooltip": "참고용으로 자세한 설명 정보가 제공됩니다. Casdoor 자체는 사용하지 않습니다",
"Detail": "详情",
"Disable": "Disable",
"Display name": "디스플레이 이름",
"Display name - Tooltip": "UI에서 공개적으로 표시되는 사용자 친화적이고 쉽게 읽을 수 있는 이름",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "추가하지 못했습니다",
"Failed to connect to server": "서버에 연결하지 못했습니다",
"Failed to delete": "삭제에 실패했습니다",
@ -344,6 +350,7 @@
"Phone - Tooltip": "전화 번호",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "플랜",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "실명",
"Records": "기록",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "자원",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "이것은 읽기 전용 데모 사이트입니다!",
"Timestamp": "Timestamp",
"Tokens": "토큰",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "고급 편집기",
"Basic Editor": "기본 편집기",
@ -610,6 +616,8 @@
"Is profile public": "프로필이 공개적으로 되어 있나요?",
"Is profile public - Tooltip": "닫힌 후에는 전역 관리자 또는 동일한 조직의 사용자만 사용자 프로필 페이지에 액세스할 수 있습니다",
"Modify rule": "규칙 수정",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "새로운 조직",
"Optional": "선택사항",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "사용자가 선택할 수 있는 태그 컬렉션",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "보기 규칙",
"Visible": "보이는",
"Website URL": "웹사이트 URL",
"Website URL - Tooltip": "조직의 홈페이지 URL입니다. 이 필드는 Casdoor에서 사용되지 않습니다"
"Website URL - Tooltip": "조직의 홈페이지 URL입니다. 이 필드는 Casdoor에서 사용되지 않습니다",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "송장 정보를 확인하세요",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "구매하다",
"Buy Product": "제품을 구입하세요",
@ -757,7 +770,6 @@
"Sold": "팔렸습니다",
"Sold - Tooltip": "판매량",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "제품 태그",
"Test buy page..": "시험 구매 페이지.",
"There is no payment channel for this product.": "이 제품에 대한 결제 채널이 없습니다.",
@ -817,6 +829,8 @@
"Edit Provider": "이전 공급 업체 편집",
"Email content": "이메일 내용",
"Email content - Tooltip": "이메일 내용",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "이메일 제목",
"Email title - Tooltip": "이메일 제목",
"Endpoint": "엔드포인트",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "메타 데이터",
"Metadata - Tooltip": "SAML 메타데이터",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "로그인 방법, QR 코드 또는 음성 로그인",
"New Provider": "새로운 공급 업체",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Webhook 편집",
"Events": "이벤트",
"Events - Tooltip": "이벤트",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "헤더들",
"Headers - Tooltip": "HTTP 헤더 (키-값 쌍)",
"Is user extended": "사용자가 확장되었습니까?",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

View File

@ -17,11 +17,15 @@
"Use same DB - Tooltip": "Use same DB - Tooltip"
},
"application": {
"Add Face ID": "Add Face ID",
"Add Face ID with Image": "Add Face ID with Image",
"Always": "Always",
"Auto signin": "Auto signin",
"Auto signin - Tooltip": "When a logged-in session exists in Casdoor, it is automatically used for application-side login",
"Background URL": "Background URL",
"Background URL - Tooltip": "URL of the background image used in the login page",
"Background URL Mobile": "Background URL Mobile",
"Background URL Mobile - Tooltip": "Background URL Mobile - Tooltip",
"Big icon": "Big icon",
"Binding providers": "Binding providers",
"CSS style": "CSS style",
@ -63,6 +67,7 @@
"Footer HTML - Tooltip": "Custom the footer of your application",
"Form position": "Form position",
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Generate Face ID": "Generate Face ID",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Header HTML": "Header HTML",
@ -189,6 +194,7 @@
"Verify": "Verify"
},
"general": {
"AI Assistant": "AI Assistant",
"API key": "API key",
"API key - Tooltip": "API key - Tooltip",
"Access key": "Access key",
@ -201,7 +207,6 @@
"Adapter - Tooltip": "Table name of the policy store",
"Adapters": "Adapters",
"Add": "Add",
"Add Face Id": "Add Face Id",
"Add custom item": "Add custom item",
"Admin": "Admin",
"Affiliation URL": "Affiliation URL",
@ -231,6 +236,7 @@
"Created time": "Created time",
"Custom": "Custom",
"Dashboard": "Dashboard",
"Data": "Data",
"Default": "Default",
"Default application": "Default application",
"Default application - Tooltip": "Default application for users registered directly from the organization page",
@ -241,6 +247,7 @@
"Delete": "Delete",
"Description": "Description",
"Description - Tooltip": "Detailed description information for reference, Casdoor itself will not use it",
"Detail": "详情",
"Disable": "Disable",
"Display name": "Display name",
"Display name - Tooltip": "A user-friendly, easily readable name displayed publicly in the UI",
@ -258,7 +265,6 @@
"Enabled": "Enabled",
"Enabled successfully": "Enabled successfully",
"Enforcers": "Enforcers",
"FaceIdData": "FaceIdData",
"Failed to add": "Failed to add",
"Failed to connect to server": "Failed to connect to server",
"Failed to delete": "Failed to delete",
@ -344,6 +350,7 @@
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plain": "Plain",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@ -362,6 +369,7 @@
"QR code is too large": "QR code is too large",
"Real name": "Real name",
"Records": "Records",
"Request": "Request",
"Request URI": "Request URI",
"Resources": "Resources",
"Role": "Role",
@ -412,6 +420,7 @@
"This is a read-only demo site!": "This is a read-only demo site!",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
"Tour": "Tour",
"Transactions": "Transactions",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
@ -442,7 +451,8 @@
"Parent group - Tooltip": "Parent group - Tooltip",
"Physical": "Physical",
"Show all": "Show all",
"Virtual": "Virtual"
"Virtual": "Virtual",
"You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page": "You need to delete all subgroups first. You can view the subgroups in the left group tree of the [Organizations] -\u003e [Groups] page"
},
"home": {
"New users past 30 days": "New users past 30 days",
@ -461,7 +471,8 @@
"Quota": "Quota",
"Quota - Tooltip": "Quota - Tooltip",
"Used count": "Used count",
"Used count - Tooltip": "Used count - Tooltip"
"Used count - Tooltip": "Used count - Tooltip",
"You need to first specify a default application for organization: ": "You need to first specify a default application for organization: "
},
"ldap": {
"Admin": "Admin",
@ -586,11 +597,6 @@
"Your phone is": "Your phone is",
"preferred": "preferred"
},
"mfaAccount": {
"Account Name": "Account Name",
"Issuer": "Issuer",
"Secret Key": "Secret Key"
},
"model": {
"Advanced Editor": "Advanced Editor",
"Basic Editor": "Basic Editor",
@ -610,6 +616,8 @@
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "After being closed, only global administrators or users in the same organization can access the user's profile page",
"Modify rule": "Modify rule",
"Navbar items": "Navbar items",
"Navbar items - Tooltip": "Navbar items - Tooltip",
"New Organization": "New Organization",
"Optional": "Optional",
"Password expire days": "Password expire days",
@ -622,10 +630,14 @@
"Tags - Tooltip": "Collection of tags available for users to choose from",
"Use Email as username": "Use Email as username",
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
"User types": "User types",
"User types - Tooltip": "User types - Tooltip",
"View rule": "View rule",
"Visible": "Visible",
"Website URL": "Website URL",
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor"
"Website URL - Tooltip": "The homepage URL of the organization. This field is not used in Casdoor",
"Widget items": "Widget items",
"Widget items - Tooltip": "Widget items - Tooltip"
},
"payment": {
"Confirm your invoice information": "Confirm your invoice information",
@ -728,6 +740,7 @@
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "paid-user do not have active subscription or pending subscription, please select a plan to buy"
},
"product": {
"AirWallex": "AirWallex",
"Alipay": "Alipay",
"Buy": "Buy",
"Buy Product": "Buy Product",
@ -757,7 +770,6 @@
"Sold": "Sold",
"Sold - Tooltip": "Quantity sold",
"Stripe": "Stripe",
"AirWallex": "AirWallex",
"Tag - Tooltip": "Tag of product",
"Test buy page..": "Test buy page..",
"There is no payment channel for this product.": "There is no payment channel for this product.",
@ -817,6 +829,8 @@
"Edit Provider": "Edit Provider",
"Email content": "Email content",
"Email content - Tooltip": "Content of the Email",
"Email regex": "Email regex",
"Email regex - Tooltip": "Email regex - Tooltip",
"Email title": "Email title",
"Email title - Tooltip": "Title of the email",
"Endpoint": "Endpoint",
@ -844,6 +858,8 @@
"Key text - Tooltip": "Key text - Tooltip",
"Metadata": "Metadata",
"Metadata - Tooltip": "SAML metadata",
"Metadata url": "Metadata url",
"Metadata url - Tooltip": "Metadata url - Tooltip",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
@ -1244,6 +1260,8 @@
"Edit Webhook": "Edit Webhook",
"Events": "Events",
"Events - Tooltip": "Events",
"Extended user fields": "Extended user fields",
"Extended user fields - Tooltip": "Extended user fields - Tooltip",
"Headers": "Headers",
"Headers - Tooltip": "HTTP headers (key-value pairs)",
"Is user extended": "Is user extended",

Some files were not shown because too many files have changed in this diff Show More