forked from casdoor/casdoor
Compare commits
41 Commits
v2.295.0
...
copilot/ex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22d287f7a8 | ||
|
|
4e1c56e3cd | ||
|
|
f48eccae98 | ||
|
|
b4049e6cf4 | ||
|
|
91c17b4092 | ||
|
|
2cac433b9f | ||
|
|
ac21a6b3c9 | ||
|
|
1731b74fa0 | ||
|
|
6e1e5dd569 | ||
|
|
b183359daf | ||
|
|
3cb9df3723 | ||
|
|
9d1e5c10d0 | ||
|
|
ef84c4b0b4 | ||
|
|
5a108bd921 | ||
|
|
ac671ec1ee | ||
|
|
7814caf2ab | ||
|
|
f966f4a0f9 | ||
|
|
a4b1a068a8 | ||
|
|
362797678d | ||
|
|
7879e1bf09 | ||
|
|
c246f102c9 | ||
|
|
37d1c4910c | ||
|
|
3bcde7cb7c | ||
|
|
6a90d21941 | ||
|
|
80b4c0b1a7 | ||
|
|
eb5a422026 | ||
|
|
f7bd70e0a3 | ||
|
|
5e7dbe4b56 | ||
|
|
bd1fca2f32 | ||
|
|
3d4cc42f1f | ||
|
|
1836cab44d | ||
|
|
75b18635f7 | ||
|
|
47cd44c7ce | ||
|
|
090ca97dcd | ||
|
|
bed01b31f1 | ||
|
|
c8f8f88d85 | ||
|
|
7acb303995 | ||
|
|
2607f8d3e5 | ||
|
|
481db33e58 | ||
|
|
f556c7e11f | ||
|
|
f590992f28 |
@@ -59,6 +59,7 @@ p, *, *, GET, /api/get-qrcode, *, *
|
||||
p, *, *, GET, /api/get-webhook-event, *, *
|
||||
p, *, *, GET, /api/get-captcha-status, *, *
|
||||
p, *, *, *, /api/login/oauth, *, *
|
||||
p, *, *, POST, /api/oauth/register, *, *
|
||||
p, *, *, GET, /api/get-application, *, *
|
||||
p, *, *, GET, /api/get-organization-applications, *, *
|
||||
p, *, *, GET, /api/get-user, *, *
|
||||
|
||||
@@ -323,7 +323,7 @@ func (c *ApiController) Signup() {
|
||||
|
||||
// If OAuth parameters are present, generate OAuth code and return it
|
||||
if clientId != "" && responseType == ResponseTypeCode {
|
||||
code, err := object.GetOAuthCode(userId, clientId, "", "password", responseType, redirectUri, scope, state, nonce, codeChallenge, c.Ctx.Request.Host, c.GetAcceptLanguage())
|
||||
code, err := object.GetOAuthCode(userId, clientId, "", "password", responseType, redirectUri, scope, state, nonce, codeChallenge, "", c.Ctx.Request.Host, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error(), nil)
|
||||
return
|
||||
@@ -688,6 +688,51 @@ func (c *ApiController) GetCaptcha() {
|
||||
applicationId := c.Ctx.Input.Query("applicationId")
|
||||
isCurrentProvider := c.Ctx.Input.Query("isCurrentProvider")
|
||||
|
||||
// When isCurrentProvider == "true", the frontend passes a provider ID instead of an application ID.
|
||||
// In that case, skip application lookup and rule evaluation, and just return the provider config.
|
||||
shouldSkipCaptcha := false
|
||||
|
||||
if isCurrentProvider != "true" {
|
||||
application, err := object.GetApplication(applicationId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), applicationId))
|
||||
return
|
||||
}
|
||||
|
||||
// Check the CAPTCHA rule to determine if CAPTCHA should be shown
|
||||
clientIp := util.GetClientIpFromRequest(c.Ctx.Request)
|
||||
|
||||
// For Internet-Only rule, we can determine on the backend if CAPTCHA should be shown
|
||||
// For other rules (Dynamic, Always), we need to return the CAPTCHA config
|
||||
for _, providerItem := range application.Providers {
|
||||
if providerItem.Provider == nil || providerItem.Provider.Category != "Captcha" {
|
||||
continue
|
||||
}
|
||||
|
||||
// For "None" rule, skip CAPTCHA
|
||||
if providerItem.Rule == "None" || providerItem.Rule == "" {
|
||||
shouldSkipCaptcha = true
|
||||
} else if providerItem.Rule == "Internet-Only" {
|
||||
// For Internet-Only rule, check if the client is from intranet
|
||||
if !util.IsInternetIp(clientIp) {
|
||||
// Client is from intranet, skip CAPTCHA
|
||||
shouldSkipCaptcha = true
|
||||
}
|
||||
}
|
||||
|
||||
break // Only check the first CAPTCHA provider
|
||||
}
|
||||
|
||||
if shouldSkipCaptcha {
|
||||
c.ResponseOk(Captcha{Type: "none"})
|
||||
return
|
||||
}
|
||||
}
|
||||
captchaProvider, err := object.GetCaptchaProviderByApplication(applicationId, isCurrentProvider, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
|
||||
@@ -161,12 +161,13 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
nonce := c.Ctx.Input.Query("nonce")
|
||||
challengeMethod := c.Ctx.Input.Query("code_challenge_method")
|
||||
codeChallenge := c.Ctx.Input.Query("code_challenge")
|
||||
resource := c.Ctx.Input.Query("resource")
|
||||
|
||||
if challengeMethod != "S256" && challengeMethod != "null" && challengeMethod != "" {
|
||||
c.ResponseError(c.T("auth:Challenge method should be S256"))
|
||||
return
|
||||
}
|
||||
code, err := object.GetOAuthCode(userId, clientId, form.Provider, form.SigninMethod, responseType, redirectUri, scope, state, nonce, codeChallenge, c.Ctx.Request.Host, c.GetAcceptLanguage())
|
||||
code, err := object.GetOAuthCode(userId, clientId, form.Provider, form.SigninMethod, responseType, redirectUri, scope, state, nonce, codeChallenge, resource, c.Ctx.Request.Host, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error(), nil)
|
||||
return
|
||||
|
||||
74
controllers/oauth_dcr.go
Normal file
74
controllers/oauth_dcr.go
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
)
|
||||
|
||||
// DynamicClientRegister
|
||||
// @Title DynamicClientRegister
|
||||
// @Tag OAuth API
|
||||
// @Description Register a new OAuth 2.0 client dynamically (RFC 7591)
|
||||
// @Param organization query string false "The organization name (defaults to built-in)"
|
||||
// @Param body body object.DynamicClientRegistrationRequest true "Client registration request"
|
||||
// @Success 201 {object} object.DynamicClientRegistrationResponse
|
||||
// @Failure 400 {object} object.DcrError
|
||||
// @router /api/oauth/register [post]
|
||||
func (c *ApiController) DynamicClientRegister() {
|
||||
var req object.DynamicClientRegistrationRequest
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
|
||||
if err != nil {
|
||||
c.Ctx.Output.Status = http.StatusBadRequest
|
||||
c.Data["json"] = object.DcrError{
|
||||
Error: "invalid_client_metadata",
|
||||
ErrorDescription: "invalid request body: " + err.Error(),
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// Get organization from query parameter or default to built-in
|
||||
organization := c.Ctx.Input.Query("organization")
|
||||
if organization == "" {
|
||||
organization = "built-in"
|
||||
}
|
||||
|
||||
// Register the client
|
||||
response, dcrErr, err := object.RegisterDynamicClient(&req, organization)
|
||||
if err != nil {
|
||||
c.Ctx.Output.Status = http.StatusInternalServerError
|
||||
c.Data["json"] = object.DcrError{
|
||||
Error: "server_error",
|
||||
ErrorDescription: err.Error(),
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
if dcrErr != nil {
|
||||
c.Ctx.Output.Status = http.StatusBadRequest
|
||||
c.Data["json"] = dcrErr
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// Return 201 Created
|
||||
c.Ctx.Output.Status = http.StatusCreated
|
||||
c.Data["json"] = response
|
||||
c.ServeJSON()
|
||||
}
|
||||
@@ -176,6 +176,7 @@ func (c *ApiController) GetOAuthToken() {
|
||||
subjectToken := c.Ctx.Input.Query("subject_token")
|
||||
subjectTokenType := c.Ctx.Input.Query("subject_token_type")
|
||||
audience := c.Ctx.Input.Query("audience")
|
||||
resource := c.Ctx.Input.Query("resource")
|
||||
|
||||
if clientId == "" && clientSecret == "" {
|
||||
clientId, clientSecret, _ = c.Ctx.Request.BasicAuth()
|
||||
@@ -231,6 +232,9 @@ func (c *ApiController) GetOAuthToken() {
|
||||
if audience == "" {
|
||||
audience = tokenRequest.Audience
|
||||
}
|
||||
if resource == "" {
|
||||
resource = tokenRequest.Resource
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +279,7 @@ func (c *ApiController) GetOAuthToken() {
|
||||
}
|
||||
|
||||
host := c.Ctx.Request.Host
|
||||
token, err := object.GetOAuthToken(grantType, clientId, clientSecret, code, verifier, scope, nonce, username, password, host, refreshToken, tag, avatar, c.GetAcceptLanguage(), subjectToken, subjectTokenType, audience)
|
||||
token, err := object.GetOAuthToken(grantType, clientId, clientSecret, code, verifier, scope, nonce, username, password, host, refreshToken, tag, avatar, c.GetAcceptLanguage(), subjectToken, subjectTokenType, audience, resource)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
||||
@@ -30,4 +30,5 @@ type TokenRequest struct {
|
||||
SubjectToken string `json:"subject_token"`
|
||||
SubjectTokenType string `json:"subject_token_type"`
|
||||
Audience string `json:"audience"`
|
||||
Resource string `json:"resource"` // RFC 8707 Resource Indicator
|
||||
}
|
||||
|
||||
@@ -151,39 +151,14 @@ func (c *ApiController) SendVerificationCode() {
|
||||
return
|
||||
}
|
||||
|
||||
provider, err := object.GetCaptchaProviderByApplication(vform.ApplicationId, "false", c.GetAcceptLanguage())
|
||||
application, err := object.GetApplication(vform.ApplicationId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if provider != nil {
|
||||
if vform.CaptchaType != provider.Type {
|
||||
c.ResponseError(c.T("verification:Turing test failed."))
|
||||
return
|
||||
}
|
||||
|
||||
if provider.Type != "Default" {
|
||||
vform.ClientSecret = provider.ClientSecret
|
||||
}
|
||||
|
||||
if vform.CaptchaType != "none" {
|
||||
if captchaProvider := captcha.GetCaptchaProvider(vform.CaptchaType); captchaProvider == nil {
|
||||
c.ResponseError(c.T("general:don't support captchaProvider: ") + vform.CaptchaType)
|
||||
return
|
||||
} else if isHuman, err := captchaProvider.VerifyCaptcha(vform.CaptchaToken, provider.ClientId, vform.ClientSecret, provider.ClientId2); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
} else if !isHuman {
|
||||
c.ResponseError(c.T("verification:Turing test failed."))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
application, err := object.GetApplication(vform.ApplicationId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), vform.ApplicationId))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -214,6 +189,7 @@ func (c *ApiController) SendVerificationCode() {
|
||||
}
|
||||
|
||||
var user *object.User
|
||||
// Try to resolve user for CAPTCHA rule checking
|
||||
// checkUser != "", means method is ForgetVerification
|
||||
if vform.CheckUser != "" {
|
||||
owner := application.Organization
|
||||
@@ -231,18 +207,86 @@ func (c *ApiController) SendVerificationCode() {
|
||||
c.ResponseError(c.T("check:The user is forbidden to sign in, please contact the administrator"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// mfaUserSession != "", means method is MfaAuthVerification
|
||||
if mfaUserSession := c.getMfaUserSession(); mfaUserSession != "" {
|
||||
} else if mfaUserSession := c.getMfaUserSession(); mfaUserSession != "" {
|
||||
// mfaUserSession != "", means method is MfaAuthVerification
|
||||
user, err = object.GetUser(mfaUserSession)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if vform.Method == ResetVerification {
|
||||
// For reset verification, get the current logged-in user
|
||||
user = c.getCurrentUser()
|
||||
} else if vform.Method == LoginVerification {
|
||||
// For login verification, try to find user by email/phone for CAPTCHA check
|
||||
// This is a preliminary lookup; the actual validation happens later in the switch statement
|
||||
if vform.Type == object.VerifyTypeEmail && util.IsEmailValid(vform.Dest) {
|
||||
user, err = object.GetUserByEmail(organization.Name, vform.Dest)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if vform.Type == object.VerifyTypePhone {
|
||||
// Prefer resolving the user directly by phone, consistent with the later login switch,
|
||||
// so that Dynamic CAPTCHA is not skipped due to missing/invalid country code.
|
||||
user, err = object.GetUserByPhone(organization.Name, vform.Dest)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine username for CAPTCHA check
|
||||
username := ""
|
||||
if user != nil {
|
||||
username = user.Name
|
||||
} else if vform.CheckUser != "" {
|
||||
username = vform.CheckUser
|
||||
}
|
||||
|
||||
// Check if CAPTCHA should be enabled based on the rule (Dynamic/Always/Internet-Only)
|
||||
enableCaptcha, err := object.CheckToEnableCaptcha(application, organization.Name, username, clientIp)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Only verify CAPTCHA if it should be enabled
|
||||
if enableCaptcha {
|
||||
captchaProvider, err := object.GetCaptchaProviderByApplication(vform.ApplicationId, "false", c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if captchaProvider != nil {
|
||||
if vform.CaptchaType != captchaProvider.Type {
|
||||
c.ResponseError(c.T("verification:Turing test failed."))
|
||||
return
|
||||
}
|
||||
|
||||
if captchaProvider.Type != "Default" {
|
||||
vform.ClientSecret = captchaProvider.ClientSecret
|
||||
}
|
||||
|
||||
if vform.CaptchaType != "none" {
|
||||
if captchaService := captcha.GetCaptchaProvider(vform.CaptchaType); captchaService == nil {
|
||||
c.ResponseError(c.T("general:don't support captchaProvider: ") + vform.CaptchaType)
|
||||
return
|
||||
} else if isHuman, err := captchaService.VerifyCaptcha(vform.CaptchaToken, captchaProvider.ClientId, vform.ClientSecret, captchaProvider.ClientId2); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
} else if !isHuman {
|
||||
c.ResponseError(c.T("verification:Turing test failed."))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendResp := errors.New("invalid dest type")
|
||||
var provider *object.Provider
|
||||
|
||||
switch vform.Type {
|
||||
case object.VerifyTypeEmail:
|
||||
|
||||
45
controllers/wellknown_oauth_prm.go
Normal file
45
controllers/wellknown_oauth_prm.go
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/casdoor/casdoor/object"
|
||||
)
|
||||
|
||||
// GetOauthProtectedResourceMetadata
|
||||
// @Title GetOauthProtectedResourceMetadata
|
||||
// @Tag OAuth 2.0 API
|
||||
// @Description Get OAuth 2.0 Protected Resource Metadata (RFC 9728)
|
||||
// @Success 200 {object} object.OauthProtectedResourceMetadata
|
||||
// @router /.well-known/oauth-protected-resource [get]
|
||||
func (c *RootController) GetOauthProtectedResourceMetadata() {
|
||||
host := c.Ctx.Request.Host
|
||||
c.Data["json"] = object.GetOauthProtectedResourceMetadata(host)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetOauthProtectedResourceMetadataByApplication
|
||||
// @Title GetOauthProtectedResourceMetadataByApplication
|
||||
// @Tag OAuth 2.0 API
|
||||
// @Description Get OAuth 2.0 Protected Resource Metadata for specific application (RFC 9728)
|
||||
// @Param application path string true "application name"
|
||||
// @Success 200 {object} object.OauthProtectedResourceMetadata
|
||||
// @router /.well-known/:application/oauth-protected-resource [get]
|
||||
func (c *RootController) GetOauthProtectedResourceMetadataByApplication() {
|
||||
application := c.Ctx.Input.Param(":application")
|
||||
host := c.Ctx.Request.Host
|
||||
c.Data["json"] = object.GetOauthProtectedResourceMetadataByApplication(host, application)
|
||||
c.ServeJSON()
|
||||
}
|
||||
@@ -137,3 +137,29 @@ func (c *RootController) GetWebFingerByApplication() {
|
||||
c.Ctx.Output.ContentType("application/jrd+json")
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetOAuthServerMetadata
|
||||
// @Title GetOAuthServerMetadata
|
||||
// @Tag OAuth API
|
||||
// @Description Get OAuth 2.0 Authorization Server Metadata (RFC 8414)
|
||||
// @Success 200 {object} object.OidcDiscovery
|
||||
// @router /.well-known/oauth-authorization-server [get]
|
||||
func (c *RootController) GetOAuthServerMetadata() {
|
||||
host := c.Ctx.Request.Host
|
||||
c.Data["json"] = object.GetOidcDiscovery(host, "")
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetOAuthServerMetadataByApplication
|
||||
// @Title GetOAuthServerMetadataByApplication
|
||||
// @Tag OAuth API
|
||||
// @Description Get OAuth 2.0 Authorization Server Metadata for specific application (RFC 8414)
|
||||
// @Param application path string true "application name"
|
||||
// @Success 200 {object} object.OidcDiscovery
|
||||
// @router /.well-known/:application/oauth-authorization-server [get]
|
||||
func (c *RootController) GetOAuthServerMetadataByApplication() {
|
||||
application := c.Ctx.Input.Param(":application")
|
||||
host := c.Ctx.Request.Host
|
||||
c.Data["json"] = object.GetOidcDiscovery(host, application)
|
||||
c.ServeJSON()
|
||||
}
|
||||
@@ -18,7 +18,7 @@ type EmailProvider interface {
|
||||
Send(fromAddress string, fromName string, toAddress []string, subject string, content string) error
|
||||
}
|
||||
|
||||
func GetEmailProvider(typ string, clientId string, clientSecret string, host string, port int, disableSsl bool, endpoint string, method string, httpHeaders map[string]string, bodyMapping map[string]string, contentType string, enableProxy bool) EmailProvider {
|
||||
func GetEmailProvider(typ string, clientId string, clientSecret string, host string, port int, sslMode string, endpoint string, method string, httpHeaders map[string]string, bodyMapping map[string]string, contentType string, enableProxy bool) EmailProvider {
|
||||
if typ == "Azure ACS" {
|
||||
return NewAzureACSEmailProvider(clientSecret, host)
|
||||
} else if typ == "Custom HTTP Email" {
|
||||
@@ -26,6 +26,6 @@ func GetEmailProvider(typ string, clientId string, clientSecret string, host str
|
||||
} else if typ == "SendGrid" {
|
||||
return NewSendgridEmailProvider(clientSecret, host, endpoint)
|
||||
} else {
|
||||
return NewSmtpEmailProvider(clientId, clientSecret, host, port, typ, disableSsl, enableProxy)
|
||||
return NewSmtpEmailProvider(clientId, clientSecret, host, port, typ, sslMode, enableProxy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,13 +25,20 @@ type SmtpEmailProvider struct {
|
||||
Dialer *gomail.Dialer
|
||||
}
|
||||
|
||||
func NewSmtpEmailProvider(userName string, password string, host string, port int, typ string, disableSsl bool, enableProxy bool) *SmtpEmailProvider {
|
||||
func NewSmtpEmailProvider(userName string, password string, host string, port int, typ string, sslMode string, enableProxy bool) *SmtpEmailProvider {
|
||||
dialer := gomail.NewDialer(host, port, userName, password)
|
||||
if typ == "SUBMAIL" {
|
||||
dialer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
}
|
||||
|
||||
dialer.SSL = !disableSsl
|
||||
// Handle SSL mode: "Auto" (or empty) means don't override gomail's default behavior
|
||||
// "Enable" means force SSL on, "Disable" means force SSL off
|
||||
if sslMode == "Enable" {
|
||||
dialer.SSL = true
|
||||
} else if sslMode == "Disable" {
|
||||
dialer.SSL = false
|
||||
}
|
||||
// If sslMode is "Auto" or empty, don't set dialer.SSL - let gomail decide based on port
|
||||
|
||||
if enableProxy {
|
||||
socks5Proxy := conf.GetConfigString("socks5Proxy")
|
||||
|
||||
7
go.mod
7
go.mod
@@ -17,6 +17,7 @@ require (
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.107
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
|
||||
github.com/aliyun/credentials-go v1.3.10
|
||||
github.com/aws/aws-sdk-go v1.45.5
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0
|
||||
github.com/beego/beego/v2 v2.3.8
|
||||
github.com/beevik/etree v1.1.0
|
||||
@@ -29,7 +30,6 @@ require (
|
||||
github.com/casdoor/xorm-adapter/v3 v3.1.0
|
||||
github.com/casvisor/casvisor-go-sdk v1.4.0
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
github.com/denisenkom/go-mssqldb v0.9.0
|
||||
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
|
||||
@@ -49,6 +49,7 @@ require (
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3
|
||||
github.com/markbates/goth v1.82.0
|
||||
github.com/microsoft/go-mssqldb v1.9.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/nyaruka/phonenumbers v1.2.2
|
||||
github.com/polarsource/polar-go v0.12.0
|
||||
@@ -114,7 +115,6 @@ require (
|
||||
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
|
||||
github.com/apistd/uni-go-sdk v0.0.2 // indirect
|
||||
github.com/atc0005/go-teams-notify/v2 v2.13.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.45.5 // indirect
|
||||
github.com/aws/smithy-go v1.24.0 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.156 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
@@ -161,7 +161,8 @@ require (
|
||||
github.com/go-webauthn/x v0.1.9 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
|
||||
24
go.sum
24
go.sum
@@ -627,6 +627,16 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGq
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U=
|
||||
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww=
|
||||
github.com/Azure/azure-storage-blob-go v0.15.0 h1:rXtgp8tN1p29GvpGgfJetavIG0V7OgcSXPpwp3tx6qk=
|
||||
github.com/Azure/azure-storage-blob-go v0.15.0/go.mod h1:vbjsVbX0dlxnRc4FFMPsS9BsJWPcne7GB7onqlPvz58=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
@@ -642,6 +652,8 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@@ -917,7 +929,6 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPc
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dghubble/oauth1 v0.7.3 h1:EkEM/zMDMp3zOsX2DC/ZQ2vnEX3ELK0/l9kb+vs4ptE=
|
||||
github.com/dghubble/oauth1 v0.7.3/go.mod h1:oxTe+az9NSMIucDPDCCtzJGsPhciJV33xocHfcR2sVY=
|
||||
@@ -1090,8 +1101,11 @@ github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -1350,6 +1364,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
||||
@@ -1414,6 +1430,8 @@ github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4
|
||||
github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU=
|
||||
github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microsoft/go-mssqldb v1.9.0 h1:5Vq+u2f4LDujJNeZn62Z4kBDEC9MjLv0ukRzOuEuvdA=
|
||||
github.com/microsoft/go-mssqldb v1.9.0/go.mod h1:GBbW9ASTiDC+mpgWDGKdm3FnFLTUsLYN3iFL90lQ+PA=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
@@ -1496,6 +1514,8 @@ github.com/pingcap/tidb/parser v0.0.0-20221126021158-6b02a5d8ba7d h1:1DyyRrgYeNj
|
||||
github.com/pingcap/tidb/parser v0.0.0-20221126021158-6b02a5d8ba7d/go.mod h1:ElJiub4lRy6UZDb+0JHDkGEdr6aOli+ykhyej7VCLoI=
|
||||
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1-0.20161029093637-248dadf4e906/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "Die Anmeldemethode: Anmeldung per E-Mail ist für die Anwendung nicht aktiviert",
|
||||
"The login method: login with face is not enabled for the application": "Die Anmeldemethode: Anmeldung per Gesicht ist für die Anwendung nicht aktiviert",
|
||||
"The login method: login with password is not enabled for the application": "Die Anmeldeart \"Anmeldung mit Passwort\" ist für die Anwendung nicht aktiviert",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "Die Bestellung: %s existiert nicht",
|
||||
"The organization: %s does not exist": "Die Organisation: %s existiert nicht",
|
||||
"The organization: %s has disabled users to signin": "Die Organisation: %s hat die Anmeldung von Benutzern deaktiviert",
|
||||
"The plan: %s does not exist": "Der Plan: %s existiert nicht",
|
||||
@@ -48,7 +48,7 @@
|
||||
"CIDR for IP: %s should not be empty": "CIDR für IP: %s darf nicht leer sein",
|
||||
"Default code does not match the code's matching rules": "Standardcode entspricht nicht den Übereinstimmungsregeln des Codes",
|
||||
"DisplayName cannot be blank": "Anzeigename kann nicht leer sein",
|
||||
"DisplayName is not valid real name": "DisplayName ist kein gültiger Vorname",
|
||||
"DisplayName is not valid real name": "Der Anzeigename ist kein gültiger echter Name",
|
||||
"Email already exists": "E-Mail existiert bereits",
|
||||
"Email cannot be empty": "E-Mail darf nicht leer sein",
|
||||
"Email is invalid": "E-Mail ist ungültig",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Gesichtsdaten stimmen nicht überein",
|
||||
"Failed to parse client IP: %s": "Fehler beim Parsen der Client-IP: %s",
|
||||
"FirstName cannot be blank": "Vorname darf nicht leer sein",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Gastbenutzer müssen ihr Konto aktualisieren, indem sie einen Benutzernamen und ein Passwort festlegen, bevor sie sich direkt anmelden können",
|
||||
"Invitation code cannot be blank": "Einladungscode darf nicht leer sein",
|
||||
"Invitation code exhausted": "Einladungscode aufgebraucht",
|
||||
"Invitation code is invalid": "Einladungscode ist ungültig",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Gruppen importieren fehlgeschlagen",
|
||||
"Failed to import users": "Fehler beim Importieren von Benutzern",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Unzureichendes Guthaben: neues Guthaben %v wäre unter dem Kreditlimit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Unzureichendes Guthaben: neues Organisationsguthaben %v wäre unter dem Kreditlimit %v",
|
||||
"Missing parameter": "Fehlender Parameter",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Nur Administrator kann Benutzer angeben",
|
||||
"Please login first": "Bitte zuerst einloggen",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "Das LDAP: %s existiert nicht",
|
||||
"The organization: %s should have one application at least": "Die Organisation: %s sollte mindestens eine Anwendung haben",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "Der Synchronizer: %s existiert nicht",
|
||||
"The user: %s doesn't exist": "Der Benutzer %s existiert nicht",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "Der Benutzer: %s wurde nicht gefunden",
|
||||
"User is required for User category transaction": "Benutzer ist für Benutzer-Kategorie-Transaktionen erforderlich",
|
||||
"Wrong userId": "Falsche Benutzer-ID",
|
||||
"don't support captchaProvider: ": "Unterstütze captchaProvider nicht:",
|
||||
"this operation is not allowed in demo mode": "Dieser Vorgang ist im Demo-Modus nicht erlaubt",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "Die Berechtigung: \"%s\" existiert nicht"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "Produktliste darf nicht leer sein"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "ID-Verifizierungsanbieter konnte nicht initialisiert werden",
|
||||
"Invalid application id": "Ungültige Anwendungs-ID",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "Kein ID-Verifizierungsanbieter konfiguriert",
|
||||
"Provider is not an ID Verification provider": "Anbieter ist kein ID-Verifizierungsanbieter",
|
||||
"the provider: %s does not exist": "Der Anbieter %s existiert nicht"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "Ungültige Telefonempfänger: %s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "Sitzungs-ID %s ist die aktuelle Sitzung und kann nicht gelöscht werden"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "Der Objektschlüssel %s ist nicht erlaubt",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Fehler"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Ticket nicht gefunden"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s wird von dieser Anwendung nicht unterstützt",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Anzeigename darf nicht leer sein",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Personalausweisinformationen und vollständiger Name sind erforderlich",
|
||||
"Identity verification failed": "Identitätsprüfung fehlgeschlagen",
|
||||
"MFA email is enabled but email is empty": "MFA-E-Mail ist aktiviert, aber E-Mail ist leer",
|
||||
"MFA phone is enabled but phone number is empty": "MFA-Telefon ist aktiviert, aber Telefonnummer ist leer",
|
||||
"New password cannot contain blank space.": "Das neue Passwort darf keine Leerzeichen enthalten.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "Keine Anwendung für Benutzer gefunden",
|
||||
"The new password must be different from your current password": "Das neue Passwort muss sich von Ihrem aktuellen Passwort unterscheiden",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "Benutzer ist bereits verifiziert",
|
||||
"the user's owner and name should not be empty": "Eigentümer und Name des Benutzers dürfen nicht leer sein"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Ungültiger Captcha-Anbieter.",
|
||||
"Phone number is invalid in your region %s": "Die Telefonnummer ist in Ihrer Region %s ungültig",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "Die Funktion \"Passwort vergessen\" ist deaktiviert",
|
||||
"The verification code has already been used!": "Der Verifizierungscode wurde bereits verwendet!",
|
||||
"The verification code has not been sent yet!": "Der Verifizierungscode wurde noch nicht gesendet!",
|
||||
"Turing test failed.": "Turing-Test fehlgeschlagen.",
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Missing parameter": "Missing parameter",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Only admin user can specify user",
|
||||
"Please login first": "Please login first",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "El método de inicio de sesión: inicio de sesión con correo electrónico no está habilitado para la aplicación",
|
||||
"The login method: login with face is not enabled for the application": "El método de inicio de sesión: inicio de sesión con reconocimiento facial no está habilitado para la aplicación",
|
||||
"The login method: login with password is not enabled for the application": "El método de inicio de sesión: inicio de sesión con contraseña no está habilitado para la aplicación",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "El pedido: %s no existe",
|
||||
"The organization: %s does not exist": "La organización: %s no existe",
|
||||
"The organization: %s has disabled users to signin": "La organización: %s ha desactivado el inicio de sesión de usuarios",
|
||||
"The plan: %s does not exist": "El plan: %s no existe",
|
||||
@@ -35,7 +35,7 @@
|
||||
"User's tag: %s is not listed in the application's tags": "La etiqueta del usuario: %s no está incluida en las etiquetas de la aplicación",
|
||||
"UserCode Expired": "Código de usuario expirado",
|
||||
"UserCode Invalid": "Código de usuario inválido",
|
||||
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "El usuario de pago %s no tiene una suscripción activa o pendiente y la aplicación: %s no tiene precio predeterminado",
|
||||
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "El usuario de pago %s no tiene una suscripción activa o pendiente y la aplicación %s no tiene precios predeterminados",
|
||||
"the application for user %s is not found": "no se encontró la aplicación para el usuario %s",
|
||||
"the organization: %s is not found": "no se encontró la organización: %s"
|
||||
},
|
||||
@@ -44,9 +44,9 @@
|
||||
},
|
||||
"check": {
|
||||
"%s does not meet the CIDR format requirements: %s": "%s no cumple con los requisitos del formato CIDR: %s",
|
||||
"Affiliation cannot be blank": "Afiliación no puede estar en blanco",
|
||||
"Affiliation cannot be blank": "La afiliación no puede estar vacía",
|
||||
"CIDR for IP: %s should not be empty": "El CIDR para la IP: %s no debe estar vacío",
|
||||
"Default code does not match the code's matching rules": "El código predeterminado no coincide con las reglas de coincidencia de códigos",
|
||||
"Default code does not match the code's matching rules": "El código predeterminado no cumple con las reglas de validación del código",
|
||||
"DisplayName cannot be blank": "El nombre de visualización no puede estar en blanco",
|
||||
"DisplayName is not valid real name": "El nombre de pantalla no es un nombre real válido",
|
||||
"Email already exists": "El correo electrónico ya existe",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Los datos faciales no coinciden",
|
||||
"Failed to parse client IP: %s": "Error al analizar la IP del cliente: %s",
|
||||
"FirstName cannot be blank": "El nombre no puede estar en blanco",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Los usuarios invitados deben actualizar su cuenta configurando un nombre de usuario y una contraseña antes de poder iniciar sesión directamente",
|
||||
"Invitation code cannot be blank": "El código de invitación no puede estar vacío",
|
||||
"Invitation code exhausted": "Código de invitación agotado",
|
||||
"Invitation code is invalid": "Código de invitación inválido",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Error al importar grupos",
|
||||
"Failed to import users": "Error al importar usuarios",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Saldo insuficiente: el nuevo saldo %v estaría por debajo del límite de crédito %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Saldo insuficiente: el nuevo saldo de la organización %v estaría por debajo del límite de crédito %v",
|
||||
"Missing parameter": "Parámetro faltante",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Solo el usuario administrador puede especificar usuario",
|
||||
"Please login first": "Por favor, inicia sesión primero",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "El LDAP: %s no existe",
|
||||
"The organization: %s should have one application at least": "La organización: %s debe tener al menos una aplicación",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "El sincronizador: %s no existe",
|
||||
"The user: %s doesn't exist": "El usuario: %s no existe",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "El usuario: %s no encontrado",
|
||||
"User is required for User category transaction": "El usuario es obligatorio para la transacción de la categoría Usuario",
|
||||
"Wrong userId": "ID de usuario incorrecto",
|
||||
"don't support captchaProvider: ": "No apoyo a captchaProvider",
|
||||
"this operation is not allowed in demo mode": "esta operación no está permitida en modo de demostración",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "El permiso: \"%s\" no existe"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "La lista de productos no puede estar vacía"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "Error al inicializar el proveedor de verificación de ID",
|
||||
"Invalid application id": "Identificación de aplicación no válida",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "No hay proveedor de verificación de ID configurado",
|
||||
"Provider is not an ID Verification provider": "El proveedor no es un proveedor de verificación de ID",
|
||||
"the provider: %s does not exist": "El proveedor: %s no existe"
|
||||
},
|
||||
"resource": {
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Error"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Ticket no encontrado"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "El tipo de subvención: %s no es compatible con esta aplicación",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "El nombre de pantalla no puede estar vacío",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Se requiere información de la tarjeta de identificación y el nombre real",
|
||||
"Identity verification failed": "Falló la verificación de identidad",
|
||||
"MFA email is enabled but email is empty": "El correo electrónico MFA está habilitado pero el correo está vacío",
|
||||
"MFA phone is enabled but phone number is empty": "El teléfono MFA está habilitado pero el número de teléfono está vacío",
|
||||
"New password cannot contain blank space.": "La nueva contraseña no puede contener espacios en blanco.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "No se encontró aplicación para el usuario",
|
||||
"The new password must be different from your current password": "La nueva contraseña debe ser diferente de su contraseña actual",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "El usuario ya está verificado",
|
||||
"the user's owner and name should not be empty": "el propietario y el nombre del usuario no deben estar vacíos"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Proveedor de captcha no válido.",
|
||||
"Phone number is invalid in your region %s": "El número de teléfono es inválido en tu región %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "La función de contraseña olvidada está deshabilitada",
|
||||
"The verification code has already been used!": "¡El código de verificación ya ha sido utilizado!",
|
||||
"The verification code has not been sent yet!": "¡El código de verificación aún no ha sido enviado!",
|
||||
"Turing test failed.": "El test de Turing falló.",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "La méthode de connexion : connexion par e-mail n'est pas activée pour l'application",
|
||||
"The login method: login with face is not enabled for the application": "La méthode de connexion : connexion par visage n'est pas activée pour l'application",
|
||||
"The login method: login with password is not enabled for the application": "La méthode de connexion : connexion avec mot de passe n'est pas activée pour l'application",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "La commande : %s n'existe pas",
|
||||
"The organization: %s does not exist": "L'organisation : %s n'existe pas",
|
||||
"The organization: %s has disabled users to signin": "L'organisation: %s a désactivé la connexion des utilisateurs",
|
||||
"The plan: %s does not exist": "Le plan : %s n'existe pas",
|
||||
@@ -35,7 +35,7 @@
|
||||
"User's tag: %s is not listed in the application's tags": "Le tag de l'utilisateur : %s n'est pas répertorié dans les tags de l'application",
|
||||
"UserCode Expired": "Code utilisateur expiré",
|
||||
"UserCode Invalid": "Code utilisateur invalide",
|
||||
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "L'utilisateur payant %s n'a pas d'abonnement actif ou en attente et l'application : %s n'a pas de tarification par défaut",
|
||||
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "L'utilisateur payant %s n'a pas d'abonnement actif ou en attente et l'application %s n'a pas de tarification par défaut",
|
||||
"the application for user %s is not found": "L'application pour l'utilisateur %s est introuvable",
|
||||
"the organization: %s is not found": "L'organisation : %s est introuvable"
|
||||
},
|
||||
@@ -44,9 +44,9 @@
|
||||
},
|
||||
"check": {
|
||||
"%s does not meet the CIDR format requirements: %s": "%s ne respecte pas les exigences du format CIDR : %s",
|
||||
"Affiliation cannot be blank": "Affiliation ne peut pas être vide",
|
||||
"Affiliation cannot be blank": "L'affiliation ne peut pas être vide",
|
||||
"CIDR for IP: %s should not be empty": "Le CIDR pour l'IP : %s ne doit pas être vide",
|
||||
"Default code does not match the code's matching rules": "Le code par défaut ne correspond pas aux règles de correspondance du code",
|
||||
"Default code does not match the code's matching rules": "Le code par défaut ne respecte pas les règles de validation du code",
|
||||
"DisplayName cannot be blank": "Le nom d'affichage ne peut pas être vide",
|
||||
"DisplayName is not valid real name": "DisplayName n'est pas un nom réel valide",
|
||||
"Email already exists": "E-mail déjà existant",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Données faciales incorrectes",
|
||||
"Failed to parse client IP: %s": "Échec de l'analyse de l'IP client : %s",
|
||||
"FirstName cannot be blank": "Le prénom ne peut pas être laissé vide",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Les utilisateurs invités doivent mettre à niveau leur compte en définissant un nom d'utilisateur et un mot de passe avant de pouvoir se connecter directement",
|
||||
"Invitation code cannot be blank": "Le code d'invitation ne peut pas être vide",
|
||||
"Invitation code exhausted": "Code d'invitation épuisé",
|
||||
"Invitation code is invalid": "Code d'invitation invalide",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Échec de l'importation des groupes",
|
||||
"Failed to import users": "Échec de l'importation des utilisateurs",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Solde insuffisant : le nouveau solde %v serait inférieur à la limite de crédit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Solde insuffisant : le nouveau solde de l'organisation %v serait inférieur à la limite de crédit %v",
|
||||
"Missing parameter": "Paramètre manquant",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Seul un administrateur peut désigner un utilisateur",
|
||||
"Please login first": "Veuillez d'abord vous connecter",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "Le LDAP : %s n'existe pas",
|
||||
"The organization: %s should have one application at least": "L'organisation : %s doit avoir au moins une application",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "Le synchroniseur : %s n'existe pas",
|
||||
"The user: %s doesn't exist": "L'utilisateur : %s n'existe pas",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "L'utilisateur : %s est introuvable",
|
||||
"User is required for User category transaction": "L'utilisateur est requis pour la transaction de catégorie Utilisateur",
|
||||
"Wrong userId": "ID utilisateur incorrect",
|
||||
"don't support captchaProvider: ": "ne prend pas en charge captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "cette opération n'est pas autorisée en mode démo",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "La permission : \"%s\" n'existe pas"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "La liste des produits ne peut pas être vide"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "Échec de l'initialisation du fournisseur de vérification d'identité",
|
||||
"Invalid application id": "Identifiant d'application invalide",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "Aucun fournisseur de vérification d'identité configuré",
|
||||
"Provider is not an ID Verification provider": "Le fournisseur n'est pas un fournisseur de vérification d'identité",
|
||||
"the provider: %s does not exist": "Le fournisseur : %s n'existe pas"
|
||||
},
|
||||
"resource": {
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Erreur"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Ticket introuvable"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Type_de_subvention : %s n'est pas pris en charge dans cette application",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Le nom d'affichage ne peut pas être vide",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Les informations de la carte d'identité et le nom réel sont requis",
|
||||
"Identity verification failed": "Échec de la vérification d'identité",
|
||||
"MFA email is enabled but email is empty": "L'authentification MFA par e-mail est activée mais l'e-mail est vide",
|
||||
"MFA phone is enabled but phone number is empty": "L'authentification MFA par téléphone est activée mais le numéro de téléphone est vide",
|
||||
"New password cannot contain blank space.": "Le nouveau mot de passe ne peut pas contenir d'espace.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "Aucune application trouvée pour l'utilisateur",
|
||||
"The new password must be different from your current password": "Le nouveau mot de passe doit être différent de votre mot de passe actuel",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "L'utilisateur est déjà vérifié",
|
||||
"the user's owner and name should not be empty": "le propriétaire et le nom de l'utilisateur ne doivent pas être vides"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Fournisseur de captcha invalide.",
|
||||
"Phone number is invalid in your region %s": "Le numéro de téléphone n'est pas valide dans votre région %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "La fonction de mot de passe oublié est désactivée",
|
||||
"The verification code has already been used!": "Le code de vérification a déjà été utilisé !",
|
||||
"The verification code has not been sent yet!": "Le code de vérification n'a pas encore été envoyé !",
|
||||
"Turing test failed.": "Le test de Turing a échoué.",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "このアプリケーションではメールログインは有効になっていません",
|
||||
"The login method: login with face is not enabled for the application": "このアプリケーションでは顔認証ログインは有効になっていません",
|
||||
"The login method: login with password is not enabled for the application": "ログイン方法:パスワードでのログインはアプリケーションで有効になっていません",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "注文:%s は存在しません",
|
||||
"The organization: %s does not exist": "組織「%s」は存在しません",
|
||||
"The organization: %s has disabled users to signin": "組織: %s はユーザーのサインインを無効にしました",
|
||||
"The plan: %s does not exist": "プラン: %sは存在しません",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "顔認証データが一致しません",
|
||||
"Failed to parse client IP: %s": "クライアント IP「%s」の解析に失敗しました",
|
||||
"FirstName cannot be blank": "ファーストネームは空白にできません",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "ゲストユーザーは直接サインインする前に、ユーザー名とパスワードを設定してアカウントをアップグレードする必要があります",
|
||||
"Invitation code cannot be blank": "招待コードは空にできません",
|
||||
"Invitation code exhausted": "招待コードの使用回数が上限に達しました",
|
||||
"Invitation code is invalid": "招待コードが無効です",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "グループのインポートに失敗しました",
|
||||
"Failed to import users": "ユーザーのインポートに失敗しました",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "残高不足:新しい残高 %v がクレジット制限 %v を下回ります",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "残高不足:新しい組織残高 %v がクレジット制限 %v を下回ります",
|
||||
"Missing parameter": "不足しているパラメーター",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "管理者ユーザーのみがユーザーを指定できます",
|
||||
"Please login first": "最初にログインしてください",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "LDAP:%s は存在しません",
|
||||
"The organization: %s should have one application at least": "組織「%s」は少なくとも1つのアプリケーションを持っている必要があります",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "同期装置:%s は存在しません",
|
||||
"The user: %s doesn't exist": "そのユーザー:%sは存在しません",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "ユーザー:%s が見つかりません",
|
||||
"User is required for User category transaction": "ユーザーカテゴリトランザクションにはユーザーが必要です",
|
||||
"Wrong userId": "無効なユーザーIDです",
|
||||
"don't support captchaProvider: ": "captchaProviderをサポートしないでください",
|
||||
"this operation is not allowed in demo mode": "この操作はデモモードでは許可されていません",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "権限「%s」は存在しません"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "商品リストは空にできません"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "ID認証プロバイダーの初期化に失敗しました",
|
||||
"Invalid application id": "アプリケーションIDが無効です",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "ID認証プロバイダーが設定されていません",
|
||||
"Provider is not an ID Verification provider": "プロバイダーはID認証プロバイダーではありません",
|
||||
"the provider: %s does not exist": "プロバイダー%sは存在しません"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "電話受信者が無効です:%s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "セッションID %s は現在のセッションであり、削除できません"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "オブジェクトキー %s は許可されていません",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "エラー"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "チケットが見つかりません"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "grant_type:%sはこのアプリケーションでサポートされていません",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "表示名は空にできません",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "身分証明書の情報と実名が必要です",
|
||||
"Identity verification failed": "身元確認に失敗しました",
|
||||
"MFA email is enabled but email is empty": "MFA メールが有効になっていますが、メールアドレスが空です",
|
||||
"MFA phone is enabled but phone number is empty": "MFA 電話番号が有効になっていますが、電話番号が空です",
|
||||
"New password cannot contain blank space.": "新しいパスワードにはスペースを含めることはできません。",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "ユーザーのアプリケーションが見つかりません",
|
||||
"The new password must be different from your current password": "新しいパスワードは現在のパスワードと異なる必要があります",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "ユーザーは既に認証済みです",
|
||||
"the user's owner and name should not be empty": "ユーザーのオーナーと名前は空にできません"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "無効なCAPTCHAプロバイダー。",
|
||||
"Phone number is invalid in your region %s": "電話番号はあなたの地域で無効です %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "パスワードを忘れた機能は無効になっています",
|
||||
"The verification code has already been used!": "この検証コードは既に使用されています!",
|
||||
"The verification code has not been sent yet!": "検証コードはまだ送信されていません!",
|
||||
"Turing test failed.": "チューリングテストは失敗しました。",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "Metoda logowania: logowanie przez email nie jest włączona dla aplikacji",
|
||||
"The login method: login with face is not enabled for the application": "Metoda logowania: logowanie przez twarz nie jest włączona dla aplikacji",
|
||||
"The login method: login with password is not enabled for the application": "Metoda logowania: logowanie przez hasło nie jest włączone dla aplikacji",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "Zamówienie: %s nie istnieje",
|
||||
"The organization: %s does not exist": "Organizacja: %s nie istnieje",
|
||||
"The organization: %s has disabled users to signin": "Organizacja: %s wyłączyła logowanie użytkowników",
|
||||
"The plan: %s does not exist": "Plan: %s nie istnieje",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Niezgodność danych twarzy",
|
||||
"Failed to parse client IP: %s": "Nie udało się przeanalizować IP klienta: %s",
|
||||
"FirstName cannot be blank": "Imię nie może być puste",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Użytkownicy-goście muszą uaktualnić swoje konto, ustawiając nazwę użytkownika i hasło, zanim będą mogli się zalogować bezpośrednio",
|
||||
"Invitation code cannot be blank": "Kod zaproszenia nie może być pusty",
|
||||
"Invitation code exhausted": "Kod zaproszenia został wykorzystany",
|
||||
"Invitation code is invalid": "Kod zaproszenia jest nieprawidłowy",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Nie udało się zaimportować grup",
|
||||
"Failed to import users": "Nie udało się zaimportować użytkowników",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Niewystarczające saldo: nowe saldo %v byłoby poniżej limitu kredytowego %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Niewystarczające saldo: nowe saldo organizacji %v byłoby poniżej limitu kredytowego %v",
|
||||
"Missing parameter": "Brakujący parametr",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Tylko administrator może wskazać użytkownika",
|
||||
"Please login first": "Najpierw się zaloguj",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "LDAP: %s nie istnieje",
|
||||
"The organization: %s should have one application at least": "Organizacja: %s powinna mieć co najmniej jedną aplikację",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "Synchronizer: %s nie istnieje",
|
||||
"The user: %s doesn't exist": "Użytkownik: %s nie istnieje",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "Użytkownik: %s nie został znaleziony",
|
||||
"User is required for User category transaction": "Użytkownik jest wymagany do transakcji kategorii użytkownika",
|
||||
"Wrong userId": "Nieprawidłowy userId",
|
||||
"don't support captchaProvider: ": "nie obsługuje captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "ta operacja nie jest dozwolona w trybie demo",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "Uprawnienie: \"%s\" nie istnieje"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "Lista produktów nie może być pusta"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "Nie udało się zainicjować dostawcy weryfikacji ID",
|
||||
"Invalid application id": "Nieprawidłowe id aplikacji",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "Brak skonfigurowanego dostawcy weryfikacji ID",
|
||||
"Provider is not an ID Verification provider": "Dostawca nie jest dostawcą weryfikacji ID",
|
||||
"the provider: %s does not exist": "dostawca: %s nie istnieje"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "Nieprawidłowi odbiorcy telefonu: %s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "identyfikator sesji %s jest bieżącą sesją i nie może być usunięty"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "Klucz obiektu: %s jest niedozwolony",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Błąd"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Nie znaleziono biletu"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s nie jest obsługiwany w tej aplikacji",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Nazwa wyświetlana nie może być pusta",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Wymagane są informacje z dowodu osobistego i prawdziwe nazwisko",
|
||||
"Identity verification failed": "Weryfikacja tożsamości nie powiodła się",
|
||||
"MFA email is enabled but email is empty": "MFA email jest włączone, ale email jest pusty",
|
||||
"MFA phone is enabled but phone number is empty": "MFA telefon jest włączony, ale numer telefonu jest pusty",
|
||||
"New password cannot contain blank space.": "Nowe hasło nie może zawierać spacji.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "Nie znaleziono aplikacji dla użytkownika",
|
||||
"The new password must be different from your current password": "Nowe hasło musi różnić się od obecnego hasła",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "Użytkownik jest już zweryfikowany",
|
||||
"the user's owner and name should not be empty": "właściciel i nazwa użytkownika nie powinny być puste"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Nieprawidłowy dostawca captcha.",
|
||||
"Phone number is invalid in your region %s": "Numer telefonu jest nieprawidłowy w twoim regionie %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "Funkcja \"Zapomniałem hasła\" jest wyłączona",
|
||||
"The verification code has already been used!": "Kod weryfikacyjny został już wykorzystany!",
|
||||
"The verification code has not been sent yet!": "Kod weryfikacyjny nie został jeszcze wysłany!",
|
||||
"Turing test failed.": "Test Turinga nie powiódł się.",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "O método de login com e-mail não está habilitado para o aplicativo",
|
||||
"The login method: login with face is not enabled for the application": "O método de login com reconhecimento facial não está habilitado para o aplicativo",
|
||||
"The login method: login with password is not enabled for the application": "O método de login com senha não está habilitado para o aplicativo",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "O pedido: %s não existe",
|
||||
"The organization: %s does not exist": "A organização: %s não existe",
|
||||
"The organization: %s has disabled users to signin": "A organização: %s desativou o login de usuários",
|
||||
"The plan: %s does not exist": "O plano: %s não existe",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Dados faciais não correspondem",
|
||||
"Failed to parse client IP: %s": "Falha ao analisar o IP do cliente: %s",
|
||||
"FirstName cannot be blank": "O primeiro nome não pode estar em branco",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Usuários convidados devem atualizar suas contas definindo um nome de usuário e senha antes de poderem entrar diretamente",
|
||||
"Invitation code cannot be blank": "O código de convite não pode estar em branco",
|
||||
"Invitation code exhausted": "O código de convite foi esgotado",
|
||||
"Invitation code is invalid": "Código de convite inválido",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Falha ao importar grupos",
|
||||
"Failed to import users": "Falha ao importar usuários",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Saldo insuficiente: o novo saldo %v estaria abaixo do limite de crédito %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Saldo insuficiente: o novo saldo da organização %v estaria abaixo do limite de crédito %v",
|
||||
"Missing parameter": "Parâmetro ausente",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Apenas um administrador pode especificar um usuário",
|
||||
"Please login first": "Por favor, faça login primeiro",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "O LDAP: %s não existe",
|
||||
"The organization: %s should have one application at least": "A organização: %s deve ter pelo menos um aplicativo",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "O sincronizador: %s não existe",
|
||||
"The user: %s doesn't exist": "O usuário: %s não existe",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "O usuário: %s não foi encontrado",
|
||||
"User is required for User category transaction": "Usuário é obrigatório para transação de categoria de usuário",
|
||||
"Wrong userId": "ID de usuário incorreto",
|
||||
"don't support captchaProvider: ": "captchaProvider não suportado: ",
|
||||
"this operation is not allowed in demo mode": "esta operação não é permitida no modo de demonstração",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "A permissão: \"%s\" não existe"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "A lista de produtos não pode estar vazia"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "Falha ao inicializar provedor de verificação de ID",
|
||||
"Invalid application id": "ID de aplicativo inválido",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "Nenhum provedor de verificação de ID configurado",
|
||||
"Provider is not an ID Verification provider": "Provedor não é um provedor de verificação de ID",
|
||||
"the provider: %s does not exist": "O provedor: %s não existe"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "Destinatários de telefone inválidos: %s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "ID da sessão %s é a sessão atual e não pode ser excluída"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "A chave de objeto: %s não é permitida",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Erro"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Ticket não encontrado"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s não é suportado neste aplicativo",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "O nome de exibição não pode estar vazio",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Informações do documento de identidade e nome verdadeiro são obrigatórios",
|
||||
"Identity verification failed": "Falha na verificação de identidade",
|
||||
"MFA email is enabled but email is empty": "MFA por e-mail está habilitado, mas o e-mail está vazio",
|
||||
"MFA phone is enabled but phone number is empty": "MFA por telefone está habilitado, mas o número de telefone está vazio",
|
||||
"New password cannot contain blank space.": "A nova senha não pode conter espaços em branco.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "Nenhum aplicativo encontrado para o usuário",
|
||||
"The new password must be different from your current password": "A nova senha deve ser diferente da senha atual",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "Usuário já está verificado",
|
||||
"the user's owner and name should not be empty": "O proprietário e o nome do usuário não devem estar vazios"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Provedor de captcha inválido.",
|
||||
"Phone number is invalid in your region %s": "Número de telefone inválido na sua região %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "A funcionalidade de esqueci a senha está desabilitada",
|
||||
"The verification code has already been used!": "O código de verificação já foi utilizado!",
|
||||
"The verification code has not been sent yet!": "O código de verificação ainda não foi enviado!",
|
||||
"Turing test failed.": "O teste de Turing falhou.",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "Uygulama için e-posta ile giriş yöntemi etkin değil",
|
||||
"The login method: login with face is not enabled for the application": "Uygulama için yüz ile giriş yöntemi etkin değil",
|
||||
"The login method: login with password is not enabled for the application": "Şifre ile giriş yöntemi bu uygulama için etkin değil",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "Sipariş: %s mevcut değil",
|
||||
"The organization: %s does not exist": "Organizasyon: %s mevcut değil",
|
||||
"The organization: %s has disabled users to signin": "Organizasyon: %s kullanıcıların oturum açmasını devre dışı bıraktı",
|
||||
"The plan: %s does not exist": "Plan: %s mevcut değil",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Yüz verisi uyuşmazlığı",
|
||||
"Failed to parse client IP: %s": "İstemci IP'si ayrıştırılamadı: %s",
|
||||
"FirstName cannot be blank": "Ad boş olamaz",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Misafir kullanıcılar doğrudan giriş yapabilmek için kullanıcı adı ve şifre belirleyerek hesaplarını yükseltmelidir",
|
||||
"Invitation code cannot be blank": "Davet kodu boş olamaz",
|
||||
"Invitation code exhausted": "Davet kodu kullanım dışı",
|
||||
"Invitation code is invalid": "Davet kodu geçersiz",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Gruplar içe aktarılamadı",
|
||||
"Failed to import users": "Kullanıcılar içe aktarılamadı",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Yetersiz bakiye: yeni bakiye %v kredi limitinin altında olacak %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Yetersiz bakiye: yeni organizasyon bakiyesi %v kredi limitinin altında olacak %v",
|
||||
"Missing parameter": "Eksik parametre",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Yalnızca yönetici kullanıcı kullanıcı belirleyebilir",
|
||||
"Please login first": "Lütfen önce giriş yapın",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "LDAP: %s mevcut değil",
|
||||
"The organization: %s should have one application at least": "Organizasyon: %s en az bir uygulamaya sahip olmalı",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "Senkronizasyon: %s mevcut değil",
|
||||
"The user: %s doesn't exist": "Kullanıcı: %s bulunamadı",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "Kullanıcı: %s bulunamadı",
|
||||
"User is required for User category transaction": "Kullanıcı kategorisi işlemi için kullanıcı gerekli",
|
||||
"Wrong userId": "Yanlış kullanıcı kimliği",
|
||||
"don't support captchaProvider: ": "captchaProvider desteklenmiyor: ",
|
||||
"this operation is not allowed in demo mode": "bu işlem demo modunda izin verilmiyor",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "İzin: \"%s\" mevcut değil"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "Ürün listesi boş olamaz"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "Kimlik Doğrulama sağlayıcısı başlatılamadı",
|
||||
"Invalid application id": "Geçersiz uygulama id",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "Kimlik Doğrulama sağlayıcısı yapılandırılmamış",
|
||||
"Provider is not an ID Verification provider": "Sağlayıcı bir Kimlik Doğrulama sağlayıcısı değil",
|
||||
"the provider: %s does not exist": "provider: %s bulunamadı"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "Geçersiz telefon alıcıları: %s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "oturum kimliği %s geçerli oturumdur ve silinemez"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "objectKey: %s izin verilmiyor",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Hata"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Bilet bulunamadı"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s bu uygulamada desteklenmiyor",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Görünen ad boş olamaz",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Kimlik kartı bilgileri ve gerçek adı gereklidir",
|
||||
"Identity verification failed": "Kimlik doğrulama başarısız",
|
||||
"MFA email is enabled but email is empty": "MFA e-postası etkin ancak e-posta boş",
|
||||
"MFA phone is enabled but phone number is empty": "MFA telefonu etkin ancak telefon numarası boş",
|
||||
"New password cannot contain blank space.": "Yeni şifre boşluk içeremez.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "Kullanıcı için uygulama bulunamadı",
|
||||
"The new password must be different from your current password": "Yeni şifre mevcut şifrenizden farklı olmalıdır",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "Kullanıcı zaten doğrulanmış",
|
||||
"the user's owner and name should not be empty": "kullanıcının sahibi ve adı boş olmamalıdır"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Geçersiz captcha sağlayıcı.",
|
||||
"Phone number is invalid in your region %s": "Telefon numaranız bölgenizde geçersiz %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "Şifremi unuttum özelliği devre dışı",
|
||||
"The verification code has already been used!": "Doğrulama kodu zaten kullanılmış!",
|
||||
"The verification code has not been sent yet!": "Doğrulama kodu henüz gönderilmedi!",
|
||||
"Turing test failed.": "Turing testi başarısız.",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "Метод входу через email не увімкнено для цього додатка",
|
||||
"The login method: login with face is not enabled for the application": "Метод входу через обличчя не увімкнено для цього додатка",
|
||||
"The login method: login with password is not enabled for the application": "Метод входу через пароль не увімкнено для цього додатка",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "Замовлення: %s не існує",
|
||||
"The organization: %s does not exist": "Організація: %s не існує",
|
||||
"The organization: %s has disabled users to signin": "Організація: %s вимкнула вхід користувачів",
|
||||
"The plan: %s does not exist": "План: %s не існує",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Невідповідність даних обличчя",
|
||||
"Failed to parse client IP: %s": "Не вдалося розібрати IP клієнта: %s",
|
||||
"FirstName cannot be blank": "Ім’я не може бути порожнім",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Гостьові користувачі повинні оновити свій обліковий запис, встановивши ім'я користувача та пароль, перш ніж вони зможуть увійти безпосередньо",
|
||||
"Invitation code cannot be blank": "Код запрошення не може бути порожнім",
|
||||
"Invitation code exhausted": "Код запрошення вичерпано",
|
||||
"Invitation code is invalid": "Код запрошення недійсний",
|
||||
@@ -83,8 +83,8 @@
|
||||
"The user is forbidden to sign in, please contact the administrator": "Користувачу заборонено вхід, зверніться до адміністратора",
|
||||
"The user: %s doesn't exist in LDAP server": "Користувач: %s не існує на сервері LDAP",
|
||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Ім’я користувача може містити лише буквено-цифрові символи, підкреслення або дефіси, не може мати послідовні дефіси або підкреслення та не може починатися або закінчуватися дефісом або підкресленням.",
|
||||
"The value \"%s\" for account field \"%s\" doesn't match the account item regex": "Värdet \"%s\" för kontofältet \"%s\" matchar inte kontots regex",
|
||||
"The value \"%s\" for signup field \"%s\" doesn't match the signup item regex of the application \"%s\"": "Värdet \"%s\" för registreringsfältet \"%s\" matchar inte registreringsfältets regex för applikationen \"%s\"",
|
||||
"The value \"%s\" for account field \"%s\" doesn't match the account item regex": "Значення \"%s\" для поля облікового запису \"%s\" не відповідає регулярному виразу облікового запису",
|
||||
"The value \"%s\" for signup field \"%s\" doesn't match the signup item regex of the application \"%s\"": "Значення \"%s\" для поля реєстрації \"%s\" не відповідає регулярному виразу поля реєстрації додатка \"%s\"",
|
||||
"Username already exists": "Ім’я користувача вже існує",
|
||||
"Username cannot be an email address": "Ім’я користувача не може бути email-адресою",
|
||||
"Username cannot contain white spaces": "Ім’я користувача не може містити пробіли",
|
||||
@@ -94,7 +94,7 @@
|
||||
"Username supports email format. Also The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline. Also pay attention to the email format.": "Ім’я користувача підтримує формат email. Також може містити лише буквено-цифрові символи, підкреслення або дефіси, не може мати послідовні дефіси або підкреслення та не може починатися або закінчуватися дефісом або підкресленням. Зверніть увагу на формат email.",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Ви ввели неправильний пароль або код забагато разів, зачекайте %d хвилин і спробуйте знову",
|
||||
"Your IP address: %s has been banned according to the configuration of: ": "Ваша IP-адреса: %s заблокована відповідно до конфігурації: ",
|
||||
"Your password has expired. Please reset your password by clicking \"Forgot password\"": "Ditt lösenord har gått ut. Återställ det genom att klicka på \"Glömt lösenord\"",
|
||||
"Your password has expired. Please reset your password by clicking \"Forgot password\"": "Ваш пароль застарів. Будь ласка, скиньте пароль, натиснувши \"Забув пароль\"",
|
||||
"Your region is not allow to signup by phone": "У вашому регіоні реєстрація за телефоном недоступна",
|
||||
"password or code is incorrect": "пароль або код неправильний",
|
||||
"password or code is incorrect, you have %s remaining chances": "пароль або код неправильний, у вас залишилось %s спроб",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Не вдалося імпортувати групи",
|
||||
"Failed to import users": "Не вдалося імпортувати користувачів",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Недостатній баланс: новий баланс %v буде нижче кредитного ліміту %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Недостатній баланс: новий баланс організації %v буде нижче кредитного ліміту %v",
|
||||
"Missing parameter": "Відсутній параметр",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Лише адміністратор може вказати користувача",
|
||||
"Please login first": "Спочатку увійдіть",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "LDAP: %s не існує",
|
||||
"The organization: %s should have one application at least": "Організація: %s має мати щонайменше один додаток",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "Синхронізатор: %s не існує",
|
||||
"The user: %s doesn't exist": "Користувач: %s не існує",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "Користувач: %s не знайдено",
|
||||
"User is required for User category transaction": "Користувач обов'язковий для транзакції категорії користувача",
|
||||
"Wrong userId": "Неправильний userId",
|
||||
"don't support captchaProvider: ": "не підтримується captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "ця операція недоступна в демо-режимі",
|
||||
@@ -143,16 +144,16 @@
|
||||
"adding a new user to the 'built-in' organization is currently disabled. Please note: all users in the 'built-in' organization are global administrators in Casdoor. Refer to the docs: https://casdoor.org/docs/basic/core-concepts#how-does-casdoor-manage-itself. If you still wish to create a user for the 'built-in' organization, go to the organization's settings page and enable the 'Has privilege consent' option.": "Додавання нового користувача до організації «built-in» (вбудованої) на даний момент вимкнено. Зауважте: усі користувачі в організації «built-in» є глобальними адміністраторами в Casdoor. Дивіться документацію: https://casdoor.org/docs/basic/core-concepts#how-does-casdoor-manage-itself. Якщо ви все ще хочете створити користувача для організації «built-in», перейдіть на сторінку налаштувань організації та увімкніть опцію «Має згоду на привілеї»."
|
||||
},
|
||||
"permission": {
|
||||
"The permission: \"%s\" doesn't exist": "Behörigheten: \"%s\" finns inte"
|
||||
"The permission: \"%s\" doesn't exist": "Дозвіл: \"%s\" не існує"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "Список товарів не може бути порожнім"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "Не вдалося ініціалізувати провайдера верифікації ID",
|
||||
"Invalid application id": "Недійсний id додатка",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "Провайдер верифікації ID не налаштований",
|
||||
"Provider is not an ID Verification provider": "Провайдер не є провайдером верифікації ID",
|
||||
"the provider: %s does not exist": "провайдер: %s не існує"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "Недійсні отримувачі телефону: %s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "ідентифікатор сесії %s є поточною сесією і не може бути видалений"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "objectKey: %s не дозволено",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Помилка"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Квиток не знайдено"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s не підтримується в цьому додатку",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Відображуване ім’я не може бути порожнім",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Інформація про посвідчення особи та справжнє ім'я обов'язкові",
|
||||
"Identity verification failed": "Верифікація особи не вдалася",
|
||||
"MFA email is enabled but email is empty": "MFA email увімкнено, але email порожній",
|
||||
"MFA phone is enabled but phone number is empty": "MFA телефон увімкнено, але номер телефону порожній",
|
||||
"New password cannot contain blank space.": "Новий пароль не може містити пробіли.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "Не знайдено додаток для користувача",
|
||||
"The new password must be different from your current password": "Новий пароль повинен відрізнятися від поточного пароля",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "Користувач уже верифікований",
|
||||
"the user's owner and name should not be empty": "власник ім’я користувача не повинні бути порожніми"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Недійсний провайдер captcha.",
|
||||
"Phone number is invalid in your region %s": "Номер телефону недійсний у вашому регіоні %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "Функція відновлення пароля вимкнена",
|
||||
"The verification code has already been used!": "Код підтвердження вже використано!",
|
||||
"The verification code has not been sent yet!": "Код підтвердження ще не надіслано!",
|
||||
"Turing test failed.": "Тест Тюрінга не пройдено.",
|
||||
@@ -219,8 +220,8 @@
|
||||
"Unknown type": "Невідомий тип",
|
||||
"Wrong verification code!": "Неправильний код підтвердження!",
|
||||
"You should verify your code in %d min!": "Ви маєте підтвердити код за %d хв!",
|
||||
"please add a SMS provider to the \"Providers\" list for the application: %s": "lägg till en SMS-leverantör i listan \"Leverantörer\" för applikationen: %s",
|
||||
"please add an Email provider to the \"Providers\" list for the application: %s": "lägg till en e-postleverantör i listan \"Leverantörer\" för applikationen: %s",
|
||||
"please add a SMS provider to the \"Providers\" list for the application: %s": "будь ласка, додайте SMS-провайдера до списку \"Провайдери\" для додатка: %s",
|
||||
"please add an Email provider to the \"Providers\" list for the application: %s": "будь ласка, додайте Email-провайдера до списку \"Провайдери\" для додатка: %s",
|
||||
"the user does not exist, please sign up first": "користувача не існує, спочатку зареєструйтесь"
|
||||
},
|
||||
"webauthn": {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "Phương thức đăng nhập bằng email chưa được bật cho ứng dụng",
|
||||
"The login method: login with face is not enabled for the application": "Phương thức đăng nhập bằng khuôn mặt chưa được bật cho ứng dụng",
|
||||
"The login method: login with password is not enabled for the application": "Phương thức đăng nhập: đăng nhập bằng mật khẩu không được kích hoạt cho ứng dụng",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "Đơn hàng: %s không tồn tại",
|
||||
"The organization: %s does not exist": "Tổ chức: %s không tồn tại",
|
||||
"The organization: %s has disabled users to signin": "Tổ chức: %s đã vô hiệu hóa đăng nhập của người dùng",
|
||||
"The plan: %s does not exist": "Kế hoạch: %s không tồn tại",
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "Dữ liệu khuôn mặt không khớp",
|
||||
"Failed to parse client IP: %s": "Không thể phân tích IP khách: %s",
|
||||
"FirstName cannot be blank": "Tên không được để trống",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Người dùng khách phải nâng cấp tài khoản bằng cách đặt tên người dùng và mật khẩu trước khi có thể đăng nhập trực tiếp",
|
||||
"Invitation code cannot be blank": "Mã mời không được để trống",
|
||||
"Invitation code exhausted": "Mã mời đã hết",
|
||||
"Invitation code is invalid": "Mã mời không hợp lệ",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "Không thể nhập nhóm",
|
||||
"Failed to import users": "Không thể nhập người dùng",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Số dư không đủ: số dư mới %v sẽ thấp hơn giới hạn tín dụng %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Số dư không đủ: số dư tổ chức mới %v sẽ thấp hơn giới hạn tín dụng %v",
|
||||
"Missing parameter": "Thiếu tham số",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "Chỉ người dùng quản trị mới có thể chỉ định người dùng",
|
||||
"Please login first": "Vui lòng đăng nhập trước",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "LDAP: %s không tồn tại",
|
||||
"The organization: %s should have one application at least": "Tổ chức: %s cần có ít nhất một ứng dụng",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "Bộ đồng bộ: %s không tồn tại",
|
||||
"The user: %s doesn't exist": "Người dùng: %s không tồn tại",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "Người dùng: %s không được tìm thấy",
|
||||
"User is required for User category transaction": "Người dùng được yêu cầu cho giao dịch danh mục Người dùng",
|
||||
"Wrong userId": "ID người dùng sai",
|
||||
"don't support captchaProvider: ": "không hỗ trợ captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "thao tác này không được phép trong chế độ demo",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "Quyền: \"%s\" không tồn tại"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "Danh sách sản phẩm không thể trống"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "Không thể khởi tạo nhà cung cấp Xác minh ID",
|
||||
"Invalid application id": "Sai ID ứng dụng",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "Không có nhà cung cấp Xác minh ID được cấu hình",
|
||||
"Provider is not an ID Verification provider": "Nhà cung cấp không phải là nhà cung cấp Xác minh ID",
|
||||
"the provider: %s does not exist": "Nhà cung cấp: %s không tồn tại"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "Người nhận điện thoại không hợp lệ: %s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "id phiên %s là phiên hiện tại và không thể bị xóa"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "Khóa đối tượng: %s không được phép",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "Lỗi"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "Không tìm thấy vé"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Loại cấp phép: %s không được hỗ trợ trong ứng dụng này",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Tên hiển thị không thể trống",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "Thông tin chứng minh nhân dân và tên thật là bắt buộc",
|
||||
"Identity verification failed": "Xác minh danh tính thất bại",
|
||||
"MFA email is enabled but email is empty": "MFA email đã bật nhưng email trống",
|
||||
"MFA phone is enabled but phone number is empty": "MFA điện thoại đã bật nhưng số điện thoại trống",
|
||||
"New password cannot contain blank space.": "Mật khẩu mới không thể chứa dấu trắng.",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "Không tìm thấy ứng dụng cho người dùng",
|
||||
"The new password must be different from your current password": "Mật khẩu mới phải khác với mật khẩu hiện tại của bạn",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "Người dùng đã được xác minh",
|
||||
"the user's owner and name should not be empty": "chủ sở hữu và tên người dùng không được để trống"
|
||||
},
|
||||
"util": {
|
||||
@@ -210,7 +211,7 @@
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Nhà cung cấp captcha không hợp lệ.",
|
||||
"Phone number is invalid in your region %s": "Số điện thoại không hợp lệ trong vùng của bạn %s",
|
||||
"The forgot password feature is disabled": "The forgot password feature is disabled",
|
||||
"The forgot password feature is disabled": "Tính năng quên mật khẩu đã bị tắt",
|
||||
"The verification code has already been used!": "Mã xác thực đã được sử dụng!",
|
||||
"The verification code has not been sent yet!": "Mã xác thực chưa được gửi!",
|
||||
"Turing test failed.": "Kiểm định Turing thất bại.",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"The login method: login with email is not enabled for the application": "该应用禁止采用邮箱登录方式",
|
||||
"The login method: login with face is not enabled for the application": "该应用禁止采用人脸登录",
|
||||
"The login method: login with password is not enabled for the application": "该应用禁止采用密码登录方式",
|
||||
"The order: %s does not exist": "The order: %s does not exist",
|
||||
"The order: %s does not exist": "订单: %s 不存在",
|
||||
"The organization: %s does not exist": "组织: %s 不存在",
|
||||
"The organization: %s has disabled users to signin": "组织: %s 禁止用户登录",
|
||||
"The plan: %s does not exist": "计划: %s不存在",
|
||||
@@ -35,7 +35,7 @@
|
||||
"User's tag: %s is not listed in the application's tags": "用户的标签: %s不在该应用的标签列表中",
|
||||
"UserCode Expired": "用户代码已过期",
|
||||
"UserCode Invalid": "用户代码无效",
|
||||
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "paid-user %s 没有激活或正在等待订阅并且应用: %s 没有默认值",
|
||||
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "付费用户 %s 没有激活或待处理的订阅,且应用 %s 没有默认定价",
|
||||
"the application for user %s is not found": "未找到用户 %s 的应用程序",
|
||||
"the organization: %s is not found": "组织: %s 不存在"
|
||||
},
|
||||
@@ -57,7 +57,7 @@
|
||||
"Face data mismatch": "人脸不匹配",
|
||||
"Failed to parse client IP: %s": "无法解析客户端 IP 地址: %s",
|
||||
"FirstName cannot be blank": "名不可以为空",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "Guest users must upgrade their account by setting a username and password before they can sign in directly",
|
||||
"Guest users must upgrade their account by setting a username and password before they can sign in directly": "访客用户必须通过设置用户名和密码来升级账户,然后才能直接登录",
|
||||
"Invitation code cannot be blank": "邀请码不能为空",
|
||||
"Invitation code exhausted": "邀请码使用次数已耗尽",
|
||||
"Invitation code is invalid": "邀请码无效",
|
||||
@@ -106,17 +106,18 @@
|
||||
"general": {
|
||||
"Failed to import groups": "导入群组失败",
|
||||
"Failed to import users": "导入用户失败",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "Insufficient balance: new balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "Insufficient balance: new organization balance %v would be below credit limit %v",
|
||||
"Insufficient balance: new balance %v would be below credit limit %v": "余额不足:新余额 %v 将低于信用限额 %v",
|
||||
"Insufficient balance: new organization balance %v would be below credit limit %v": "余额不足:新组织余额 %v 将低于信用限额 %v",
|
||||
"Missing parameter": "缺少参数",
|
||||
"Multiple captcha providers are not allowed in the same application: %s": "Multiple captcha providers are not allowed in the same application: %s",
|
||||
"Only admin user can specify user": "仅管理员用户可以指定用户",
|
||||
"Please login first": "请先登录",
|
||||
"The LDAP: %s does not exist": "The LDAP: %s does not exist",
|
||||
"The LDAP: %s does not exist": "LDAP: %s 不存在",
|
||||
"The organization: %s should have one application at least": "组织: %s 应该拥有至少一个应用",
|
||||
"The syncer: %s does not exist": "The syncer: %s does not exist",
|
||||
"The syncer: %s does not exist": "同步器: %s 不存在",
|
||||
"The user: %s doesn't exist": "用户: %s不存在",
|
||||
"The user: %s is not found": "The user: %s is not found",
|
||||
"User is required for User category transaction": "User is required for User category transaction",
|
||||
"The user: %s is not found": "用户: %s 未找到",
|
||||
"User is required for User category transaction": "用户类别交易需要用户",
|
||||
"Wrong userId": "错误的 userId",
|
||||
"don't support captchaProvider: ": "不支持验证码提供商: ",
|
||||
"this operation is not allowed in demo mode": "demo模式下不允许该操作",
|
||||
@@ -146,13 +147,13 @@
|
||||
"The permission: \"%s\" doesn't exist": "权限: \"%s\" 不存在"
|
||||
},
|
||||
"product": {
|
||||
"Product list cannot be empty": "Product list cannot be empty"
|
||||
"Product list cannot be empty": "产品列表不能为空"
|
||||
},
|
||||
"provider": {
|
||||
"Failed to initialize ID Verification provider": "Failed to initialize ID Verification provider",
|
||||
"Failed to initialize ID Verification provider": "初始化身份验证提供商失败",
|
||||
"Invalid application id": "无效的应用ID",
|
||||
"No ID Verification provider configured": "No ID Verification provider configured",
|
||||
"Provider is not an ID Verification provider": "Provider is not an ID Verification provider",
|
||||
"No ID Verification provider configured": "未配置身份验证提供商",
|
||||
"Provider is not an ID Verification provider": "提供商不是身份验证提供商",
|
||||
"the provider: %s does not exist": "提供商: %s不存在"
|
||||
},
|
||||
"resource": {
|
||||
@@ -171,7 +172,7 @@
|
||||
"Invalid phone receivers: %s": "无效的手机短信收信人: %s"
|
||||
},
|
||||
"session": {
|
||||
"session id %s is the current session and cannot be deleted": "session id %s is the current session and cannot be deleted"
|
||||
"session id %s is the current session and cannot be deleted": "会话ID %s 是当前会话,无法删除"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "objectKey: %s被禁止",
|
||||
@@ -181,7 +182,7 @@
|
||||
"Error": "错误"
|
||||
},
|
||||
"ticket": {
|
||||
"Ticket not found": "Ticket not found"
|
||||
"Ticket not found": "工单未找到"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "该应用不支持Grant_type: %s",
|
||||
@@ -192,14 +193,14 @@
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "显示名称不可为空",
|
||||
"ID card information and real name are required": "ID card information and real name are required",
|
||||
"Identity verification failed": "Identity verification failed",
|
||||
"ID card information and real name are required": "需要身份证信息和真实姓名",
|
||||
"Identity verification failed": "身份验证失败",
|
||||
"MFA email is enabled but email is empty": "MFA 电子邮件已启用,但电子邮件为空",
|
||||
"MFA phone is enabled but phone number is empty": "MFA 电话已启用,但电话号码为空",
|
||||
"New password cannot contain blank space.": "新密码不可以包含空格",
|
||||
"No application found for user": "No application found for user",
|
||||
"No application found for user": "未找到用户的应用程序",
|
||||
"The new password must be different from your current password": "新密码必须与您当前的密码不同",
|
||||
"User is already verified": "User is already verified",
|
||||
"User is already verified": "用户已验证",
|
||||
"the user's owner and name should not be empty": "用户的组织和名称不能为空"
|
||||
},
|
||||
"util": {
|
||||
|
||||
@@ -86,6 +86,18 @@
|
||||
{"name": "Homepage", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Bio", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Tag", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
|
||||
{"name": "Language", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Gender", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Birthday", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Education", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Balance", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
|
||||
{"name": "Balance credit", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
|
||||
{"name": "Balance currency", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
|
||||
{"name": "Cart", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
|
||||
{"name": "Transactions", "visible": true, "viewRule": "Self", "modifyRule": "Self"},
|
||||
{"name": "Score", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Karma", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Ranking", "visible": true, "viewRule": "Public", "modifyRule": "Self"},
|
||||
{"name": "Signup application", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
|
||||
{"name": "Register type", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
|
||||
{"name": "Register source", "visible": true, "viewRule": "Public", "modifyRule": "Admin"},
|
||||
|
||||
56
mcp/auth.go
56
mcp/auth.go
@@ -15,6 +15,7 @@
|
||||
package mcp
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@@ -120,3 +121,58 @@ func (c *McpController) GetAcceptLanguage() string {
|
||||
}
|
||||
return language
|
||||
}
|
||||
|
||||
// GetTokenFromRequest extracts the Bearer token from the Authorization header
|
||||
func (c *McpController) GetTokenFromRequest() string {
|
||||
authHeader := c.Ctx.Request.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Extract Bearer token
|
||||
parts := strings.SplitN(authHeader, " ", 2)
|
||||
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") {
|
||||
return ""
|
||||
}
|
||||
|
||||
return parts[1]
|
||||
}
|
||||
|
||||
// GetClaimsFromToken parses and validates the JWT token and returns the claims
|
||||
// Returns nil if no token is present or if token is invalid
|
||||
func (c *McpController) GetClaimsFromToken() *object.Claims {
|
||||
tokenString := c.GetTokenFromRequest()
|
||||
if tokenString == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Try to find the application for this token
|
||||
// For MCP, we'll try to parse using the first available application's certificate
|
||||
// In a production scenario, you might want to use a specific MCP application
|
||||
token, err := object.GetTokenByAccessToken(tokenString)
|
||||
if err != nil || token == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
application, err := object.GetApplication(token.Application)
|
||||
if err != nil || application == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
claims, err := object.ParseJwtTokenByApplication(tokenString, application)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return claims
|
||||
}
|
||||
|
||||
// GetScopesFromClaims extracts the scopes from JWT claims and returns them as a slice
|
||||
func GetScopesFromClaims(claims *object.Claims) []string {
|
||||
if claims == nil || claims.Scope == "" {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// Scopes are space-separated in OAuth 2.0
|
||||
return strings.Split(claims.Scope, " ")
|
||||
}
|
||||
|
||||
211
mcp/base.go
211
mcp/base.go
@@ -268,7 +268,160 @@ func (c *McpController) handlePing(req McpRequest) {
|
||||
}
|
||||
|
||||
func (c *McpController) handleToolsList(req McpRequest) {
|
||||
tools := []McpTool{
|
||||
allTools := c.getAllTools()
|
||||
|
||||
// Get JWT claims from the request
|
||||
claims := c.GetClaimsFromToken()
|
||||
|
||||
// If no token is present, check session authentication
|
||||
if claims == nil {
|
||||
username := c.GetSessionUsername()
|
||||
// If user is authenticated via session, return all tools (backward compatibility)
|
||||
if username != "" {
|
||||
result := McpListToolsResult{
|
||||
Tools: allTools,
|
||||
}
|
||||
c.McpResponseOk(req.ID, result)
|
||||
return
|
||||
}
|
||||
|
||||
// Unauthenticated request - return all tools for discovery
|
||||
// This allows clients to see what tools are available before authenticating
|
||||
result := McpListToolsResult{
|
||||
Tools: allTools,
|
||||
}
|
||||
c.McpResponseOk(req.ID, result)
|
||||
return
|
||||
}
|
||||
|
||||
// Token-based authentication - filter tools by scopes
|
||||
grantedScopes := GetScopesFromClaims(claims)
|
||||
allowedTools := GetToolsForScopes(grantedScopes, BuiltinScopes)
|
||||
|
||||
// Filter tools based on allowed scopes
|
||||
var filteredTools []McpTool
|
||||
for _, tool := range allTools {
|
||||
if allowedTools[tool.Name] {
|
||||
filteredTools = append(filteredTools, tool)
|
||||
}
|
||||
}
|
||||
|
||||
result := McpListToolsResult{
|
||||
Tools: filteredTools,
|
||||
}
|
||||
|
||||
c.McpResponseOk(req.ID, result)
|
||||
}
|
||||
|
||||
func (c *McpController) handleToolsCall(req McpRequest) {
|
||||
var params McpCallToolParams
|
||||
err := json.Unmarshal(req.Params, ¶ms)
|
||||
if err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Check scope-tool permission
|
||||
if !c.checkToolPermission(req.ID, params.Name) {
|
||||
return // Error already sent by checkToolPermission
|
||||
}
|
||||
|
||||
// Route to the appropriate tool handler
|
||||
switch params.Name {
|
||||
case "get_applications":
|
||||
var args GetApplicationsArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleGetApplicationsTool(req.ID, args)
|
||||
case "get_application":
|
||||
var args GetApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleGetApplicationTool(req.ID, args)
|
||||
case "add_application":
|
||||
var args AddApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleAddApplicationTool(req.ID, args)
|
||||
case "update_application":
|
||||
var args UpdateApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleUpdateApplicationTool(req.ID, args)
|
||||
case "delete_application":
|
||||
var args DeleteApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleDeleteApplicationTool(req.ID, args)
|
||||
default:
|
||||
c.McpResponseError(req.ID, -32602, "Invalid tool name", fmt.Sprintf("Tool '%s' not found", params.Name))
|
||||
}
|
||||
}
|
||||
|
||||
// checkToolPermission validates that the current token has the required scope for the tool
|
||||
// Returns false and sends an error response if permission is denied
|
||||
func (c *McpController) checkToolPermission(id interface{}, toolName string) bool {
|
||||
// Get JWT claims from the request
|
||||
claims := c.GetClaimsFromToken()
|
||||
|
||||
// If no token is present, check if the user is authenticated via session
|
||||
if claims == nil {
|
||||
username := c.GetSessionUsername()
|
||||
// If user is authenticated via session (e.g., session cookie), allow access
|
||||
// This maintains backward compatibility with existing session-based auth
|
||||
if username != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// No authentication present - deny access
|
||||
c.sendInsufficientScopeError(id, toolName, []string{})
|
||||
return false
|
||||
}
|
||||
|
||||
// Extract scopes from claims
|
||||
grantedScopes := GetScopesFromClaims(claims)
|
||||
|
||||
// Get allowed tools for the granted scopes
|
||||
allowedTools := GetToolsForScopes(grantedScopes, BuiltinScopes)
|
||||
|
||||
// Check if the requested tool is allowed
|
||||
if !allowedTools[toolName] {
|
||||
c.sendInsufficientScopeError(id, toolName, grantedScopes)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// sendInsufficientScopeError sends an error response for insufficient scope
|
||||
func (c *McpController) sendInsufficientScopeError(id interface{}, toolName string, grantedScopes []string) {
|
||||
// Find required scope for this tool
|
||||
requiredScope := GetRequiredScopeForTool(toolName, BuiltinScopes)
|
||||
|
||||
errorData := map[string]interface{}{
|
||||
"tool": toolName,
|
||||
"granted_scopes": grantedScopes,
|
||||
}
|
||||
if requiredScope != "" {
|
||||
errorData["required_scope"] = requiredScope
|
||||
}
|
||||
|
||||
c.McpResponseError(id, -32001, "insufficient_scope", errorData)
|
||||
}
|
||||
|
||||
// getAllTools returns all available MCP tools
|
||||
func (c *McpController) getAllTools() []McpTool {
|
||||
return []McpTool{
|
||||
{
|
||||
Name: "get_applications",
|
||||
Description: "Get all applications for a specific owner",
|
||||
@@ -344,60 +497,4 @@ func (c *McpController) handleToolsList(req McpRequest) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
result := McpListToolsResult{
|
||||
Tools: tools,
|
||||
}
|
||||
|
||||
c.McpResponseOk(req.ID, result)
|
||||
}
|
||||
|
||||
func (c *McpController) handleToolsCall(req McpRequest) {
|
||||
var params McpCallToolParams
|
||||
err := json.Unmarshal(req.Params, ¶ms)
|
||||
if err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Route to the appropriate tool handler
|
||||
switch params.Name {
|
||||
case "get_applications":
|
||||
var args GetApplicationsArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleGetApplicationsTool(req.ID, args)
|
||||
case "get_application":
|
||||
var args GetApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleGetApplicationTool(req.ID, args)
|
||||
case "add_application":
|
||||
var args AddApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleAddApplicationTool(req.ID, args)
|
||||
case "update_application":
|
||||
var args UpdateApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleUpdateApplicationTool(req.ID, args)
|
||||
case "delete_application":
|
||||
var args DeleteApplicationArgs
|
||||
if err := json.Unmarshal(params.Arguments, &args); err != nil {
|
||||
c.sendInvalidParamsError(req.ID, err.Error())
|
||||
return
|
||||
}
|
||||
c.handleDeleteApplicationTool(req.ID, args)
|
||||
default:
|
||||
c.McpResponseError(req.ID, -32602, "Invalid tool name", fmt.Sprintf("Tool '%s' not found", params.Name))
|
||||
}
|
||||
}
|
||||
|
||||
158
mcp/permission.go
Normal file
158
mcp/permission.go
Normal file
@@ -0,0 +1,158 @@
|
||||
// Copyright 2026 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 mcp
|
||||
|
||||
import (
|
||||
"github.com/casdoor/casdoor/object"
|
||||
)
|
||||
|
||||
// BuiltinScopes defines the default scope-to-tool mappings for Casdoor's MCP server
|
||||
var BuiltinScopes = []*object.ScopeItem{
|
||||
{
|
||||
Name: "application:read",
|
||||
DisplayName: "Read Applications",
|
||||
Description: "View application list and details",
|
||||
Tools: []string{"get_applications", "get_application"},
|
||||
},
|
||||
{
|
||||
Name: "application:write",
|
||||
DisplayName: "Manage Applications",
|
||||
Description: "Create, update, and delete applications",
|
||||
Tools: []string{"add_application", "update_application", "delete_application"},
|
||||
},
|
||||
{
|
||||
Name: "user:read",
|
||||
DisplayName: "Read Users",
|
||||
Description: "View user list and details",
|
||||
Tools: []string{"get_users", "get_user"},
|
||||
},
|
||||
{
|
||||
Name: "user:write",
|
||||
DisplayName: "Manage Users",
|
||||
Description: "Create, update, and delete users",
|
||||
Tools: []string{"add_user", "update_user", "delete_user"},
|
||||
},
|
||||
{
|
||||
Name: "organization:read",
|
||||
DisplayName: "Read Organizations",
|
||||
Description: "View organization list and details",
|
||||
Tools: []string{"get_organizations", "get_organization"},
|
||||
},
|
||||
{
|
||||
Name: "organization:write",
|
||||
DisplayName: "Manage Organizations",
|
||||
Description: "Create, update, and delete organizations",
|
||||
Tools: []string{"add_organization", "update_organization", "delete_organization"},
|
||||
},
|
||||
{
|
||||
Name: "permission:read",
|
||||
DisplayName: "Read Permissions",
|
||||
Description: "View permission list and details",
|
||||
Tools: []string{"get_permissions", "get_permission"},
|
||||
},
|
||||
{
|
||||
Name: "permission:write",
|
||||
DisplayName: "Manage Permissions",
|
||||
Description: "Create, update, and delete permissions",
|
||||
Tools: []string{"add_permission", "update_permission", "delete_permission"},
|
||||
},
|
||||
{
|
||||
Name: "role:read",
|
||||
DisplayName: "Read Roles",
|
||||
Description: "View role list and details",
|
||||
Tools: []string{"get_roles", "get_role"},
|
||||
},
|
||||
{
|
||||
Name: "role:write",
|
||||
DisplayName: "Manage Roles",
|
||||
Description: "Create, update, and delete roles",
|
||||
Tools: []string{"add_role", "update_role", "delete_role"},
|
||||
},
|
||||
{
|
||||
Name: "provider:read",
|
||||
DisplayName: "Read Providers",
|
||||
Description: "View provider list and details",
|
||||
Tools: []string{"get_providers", "get_provider"},
|
||||
},
|
||||
{
|
||||
Name: "provider:write",
|
||||
DisplayName: "Manage Providers",
|
||||
Description: "Create, update, and delete providers",
|
||||
Tools: []string{"add_provider", "update_provider", "delete_provider"},
|
||||
},
|
||||
{
|
||||
Name: "token:read",
|
||||
DisplayName: "Read Tokens",
|
||||
Description: "View token list and details",
|
||||
Tools: []string{"get_tokens", "get_token"},
|
||||
},
|
||||
{
|
||||
Name: "token:write",
|
||||
DisplayName: "Manage Tokens",
|
||||
Description: "Delete tokens",
|
||||
Tools: []string{"delete_token"},
|
||||
},
|
||||
}
|
||||
|
||||
// ConvenienceScopes defines alias scopes that expand to multiple resource scopes
|
||||
var ConvenienceScopes = map[string][]string{
|
||||
"read": {"application:read", "user:read", "organization:read", "permission:read", "role:read", "provider:read", "token:read"},
|
||||
"write": {"application:write", "user:write", "organization:write", "permission:write", "role:write", "provider:write", "token:write"},
|
||||
"admin": {"application:read", "application:write", "user:read", "user:write", "organization:read", "organization:write", "permission:read", "permission:write", "role:read", "role:write", "provider:read", "provider:write", "token:read", "token:write"},
|
||||
}
|
||||
|
||||
// GetToolsForScopes returns a map of tools allowed by the given scopes
|
||||
// The grantedScopes are the scopes present in the token
|
||||
// The registry contains the scope-to-tool mappings (either BuiltinScopes or Application.Scopes)
|
||||
func GetToolsForScopes(grantedScopes []string, registry []*object.ScopeItem) map[string]bool {
|
||||
allowed := make(map[string]bool)
|
||||
|
||||
// Expand convenience scopes first
|
||||
expandedScopes := make([]string, 0)
|
||||
for _, scopeName := range grantedScopes {
|
||||
if expansion, isConvenience := ConvenienceScopes[scopeName]; isConvenience {
|
||||
expandedScopes = append(expandedScopes, expansion...)
|
||||
} else {
|
||||
expandedScopes = append(expandedScopes, scopeName)
|
||||
}
|
||||
}
|
||||
|
||||
// Map scopes to tools
|
||||
for _, scopeName := range expandedScopes {
|
||||
for _, item := range registry {
|
||||
if item.Name == scopeName {
|
||||
for _, tool := range item.Tools {
|
||||
allowed[tool] = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allowed
|
||||
}
|
||||
|
||||
// GetRequiredScopeForTool returns the first scope that provides access to the given tool
|
||||
// Returns an empty string if no scope is found for the tool
|
||||
func GetRequiredScopeForTool(toolName string, registry []*object.ScopeItem) string {
|
||||
for _, scopeItem := range registry {
|
||||
for _, tool := range scopeItem.Tools {
|
||||
if tool == toolName {
|
||||
return scopeItem.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -61,9 +61,17 @@ type SamlItem struct {
|
||||
}
|
||||
|
||||
type JwtItem struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Category string `json:"category"`
|
||||
Value string `json:"value"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type ScopeItem struct {
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Description string `json:"description"`
|
||||
Tools []string `json:"tools"` // MCP tools allowed by this scope
|
||||
}
|
||||
|
||||
type Application struct {
|
||||
@@ -72,6 +80,9 @@ type Application struct {
|
||||
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
Category string `xorm:"varchar(20)" json:"category"`
|
||||
Type string `xorm:"varchar(20)" json:"type"`
|
||||
Scopes []*ScopeItem `xorm:"mediumtext" json:"scopes"`
|
||||
Logo string `xorm:"varchar(200)" json:"logo"`
|
||||
Title string `xorm:"varchar(100)" json:"title"`
|
||||
Favicon string `xorm:"varchar(200)" json:"favicon"`
|
||||
@@ -143,6 +154,13 @@ type Application struct {
|
||||
FailedSigninLimit int `json:"failedSigninLimit"`
|
||||
FailedSigninFrozenTime int `json:"failedSigninFrozenTime"`
|
||||
CodeResendTimeout int `json:"codeResendTimeout"`
|
||||
|
||||
// Reverse Proxy fields
|
||||
Domain string `xorm:"varchar(100)" json:"domain"`
|
||||
OtherDomains []string `xorm:"mediumtext" json:"otherDomains"`
|
||||
UpstreamHost string `xorm:"varchar(100)" json:"upstreamHost"`
|
||||
SslMode string `xorm:"varchar(100)" json:"sslMode"`
|
||||
SslCert string `xorm:"varchar(100)" json:"sslCert"`
|
||||
}
|
||||
|
||||
func GetApplicationCount(owner, field, value string) (int64, error) {
|
||||
|
||||
@@ -20,7 +20,8 @@ import "github.com/casdoor/casdoor/email"
|
||||
|
||||
// TestSmtpServer Test the SMTP server
|
||||
func TestSmtpServer(provider *Provider) error {
|
||||
smtpEmailProvider := email.NewSmtpEmailProvider(provider.ClientId, provider.ClientSecret, provider.Host, provider.Port, provider.Type, provider.DisableSsl, provider.EnableProxy)
|
||||
sslMode := getSslMode(provider)
|
||||
smtpEmailProvider := email.NewSmtpEmailProvider(provider.ClientId, provider.ClientSecret, provider.Host, provider.Port, provider.Type, sslMode, provider.EnableProxy)
|
||||
sender, err := smtpEmailProvider.Dialer.Dial()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -31,7 +32,8 @@ func TestSmtpServer(provider *Provider) error {
|
||||
}
|
||||
|
||||
func SendEmail(provider *Provider, title string, content string, dest []string, sender string) error {
|
||||
emailProvider := email.GetEmailProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.Host, provider.Port, provider.DisableSsl, provider.Endpoint, provider.Method, provider.HttpHeaders, provider.UserMapping, provider.IssuerUrl, provider.EnableProxy)
|
||||
sslMode := getSslMode(provider)
|
||||
emailProvider := email.GetEmailProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.Host, provider.Port, sslMode, provider.Endpoint, provider.Method, provider.HttpHeaders, provider.UserMapping, provider.IssuerUrl, provider.EnableProxy)
|
||||
|
||||
fromAddress := provider.ClientId2
|
||||
if fromAddress == "" {
|
||||
@@ -45,3 +47,19 @@ func SendEmail(provider *Provider, title string, content string, dest []string,
|
||||
|
||||
return emailProvider.Send(fromAddress, fromName, dest, title, content)
|
||||
}
|
||||
|
||||
// getSslMode returns the SSL mode for the provider, with backward compatibility for DisableSsl
|
||||
func getSslMode(provider *Provider) string {
|
||||
// If SslMode is set, use it
|
||||
if provider.SslMode != "" {
|
||||
return provider.SslMode
|
||||
}
|
||||
|
||||
// Backward compatibility: convert DisableSsl to SslMode
|
||||
if provider.DisableSsl {
|
||||
return "Disable"
|
||||
}
|
||||
|
||||
// Default to "Auto" for new configurations or when DisableSsl is false
|
||||
return "Auto"
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -49,7 +50,12 @@ func GetDashboard(owner string) (*map[string][]int64, error) {
|
||||
dashboard[tableName+"Counts"] = make([]int64, 31)
|
||||
tableFullName := tableNamePrefix + tableName
|
||||
go func(ch chan error) {
|
||||
defer wg.Done()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ch <- fmt.Errorf("panic in dashboard goroutine: %v", r)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
dashboardDateItems := []DashboardDateItem{}
|
||||
var countResult int64
|
||||
|
||||
|
||||
@@ -72,6 +72,18 @@ func getBuiltInAccountItems() []*AccountItem {
|
||||
{Name: "Homepage", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Bio", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Tag", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
{Name: "Language", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Gender", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Birthday", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Education", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Balance", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Balance credit", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Balance currency", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Cart", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Transactions", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Score", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Karma", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Ranking", Visible: true, ViewRule: "Public", ModifyRule: "Self"},
|
||||
{Name: "Signup application", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
{Name: "Register type", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
{Name: "Register source", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
@@ -120,6 +132,7 @@ func initBuiltInOrganization() bool {
|
||||
IsProfilePublic: false,
|
||||
UseEmailAsUsername: false,
|
||||
EnableTour: true,
|
||||
DcrPolicy: "open",
|
||||
}
|
||||
_, err = AddOrganization(organization)
|
||||
if err != nil {
|
||||
@@ -185,6 +198,9 @@ func initBuiltInApplication() {
|
||||
Name: "app-built-in",
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: "Casdoor",
|
||||
Category: "Default",
|
||||
Type: "All",
|
||||
Scopes: []*ScopeItem{},
|
||||
Logo: fmt.Sprintf("%s/img/casdoor-logo_1185x256.png", conf.GetConfigString("staticBaseUrl")),
|
||||
HomepageUrl: "https://casdoor.org",
|
||||
Organization: "built-in",
|
||||
|
||||
@@ -37,8 +37,9 @@ type Ldap struct {
|
||||
PasswordType string `xorm:"varchar(100)" json:"passwordType"`
|
||||
CustomAttributes map[string]string `json:"customAttributes"`
|
||||
|
||||
AutoSync int `json:"autoSync"`
|
||||
LastSync string `xorm:"varchar(100)" json:"lastSync"`
|
||||
AutoSync int `json:"autoSync"`
|
||||
LastSync string `xorm:"varchar(100)" json:"lastSync"`
|
||||
EnableGroups bool `xorm:"bool" json:"enableGroups"`
|
||||
}
|
||||
|
||||
func AddLdap(ldap *Ldap) (bool, error) {
|
||||
@@ -152,7 +153,7 @@ func UpdateLdap(ldap *Ldap) (bool, error) {
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.ID(ldap.Id).Cols("owner", "server_name", "host",
|
||||
"port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync", "default_group", "password_type", "allow_self_signed_cert", "custom_attributes").Update(ldap)
|
||||
"port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync", "default_group", "password_type", "allow_self_signed_cert", "custom_attributes", "enable_groups").Update(ldap)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -91,13 +91,28 @@ func (l *LdapAutoSynchronizer) syncRoutine(ldap *Ldap, stopChan chan struct{}) e
|
||||
return err
|
||||
}
|
||||
|
||||
// fetch all users
|
||||
// fetch all users and groups
|
||||
conn, err := ldap.GetLdapConn()
|
||||
if err != nil {
|
||||
logs.Warning(fmt.Sprintf("autoSync failed for %s, error %s", ldap.Id, err))
|
||||
continue
|
||||
}
|
||||
|
||||
// Sync groups first if enabled (so they exist before assigning users)
|
||||
if ldap.EnableGroups {
|
||||
groups, err := conn.GetLdapGroups(ldap)
|
||||
if err != nil {
|
||||
logs.Warning(fmt.Sprintf("autoSync failed to fetch groups for %s, error %s", ldap.Id, err))
|
||||
} else {
|
||||
newGroups, updatedGroups, err := SyncLdapGroups(ldap.Owner, groups, ldap.Id)
|
||||
if err != nil {
|
||||
logs.Warning(fmt.Sprintf("autoSync failed to sync groups for %s, error %s", ldap.Id, err))
|
||||
} else {
|
||||
logs.Info(fmt.Sprintf("ldap group sync success for %s, %d new groups, %d updated groups", ldap.Id, newGroups, updatedGroups))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
users, err := conn.GetLdapUsers(ldap)
|
||||
if err != nil {
|
||||
conn.Close()
|
||||
|
||||
@@ -87,10 +87,19 @@ type LdapUser struct {
|
||||
|
||||
GroupId string `json:"groupId"`
|
||||
Address string `json:"address"`
|
||||
MemberOf string `json:"memberOf"`
|
||||
MemberOf []string `json:"memberOf"`
|
||||
Attributes map[string]string `json:"attributes"`
|
||||
}
|
||||
|
||||
type LdapGroup struct {
|
||||
Dn string `json:"dn"`
|
||||
Cn string `json:"cn"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Member []string `json:"member"`
|
||||
ParentDn string `json:"parentDn"`
|
||||
}
|
||||
|
||||
func (ldap *Ldap) GetLdapConn() (c *LdapConn, err error) {
|
||||
var conn *goldap.Conn
|
||||
tlsConfig := tls.Config{
|
||||
@@ -179,7 +188,7 @@ func (l *LdapConn) GetLdapUsers(ldapServer *Ldap) ([]LdapUser, error) {
|
||||
SearchAttributes := []string{
|
||||
"uidNumber", "cn", "sn", "gidNumber", "entryUUID", "displayName", "mail", "email",
|
||||
"emailAddress", "telephoneNumber", "mobile", "mobileTelephoneNumber", "registeredAddress", "postalAddress",
|
||||
"c", "co",
|
||||
"c", "co", "memberOf",
|
||||
}
|
||||
if l.IsAD {
|
||||
SearchAttributes = append(SearchAttributes, "sAMAccountName")
|
||||
@@ -247,7 +256,7 @@ func (l *LdapConn) GetLdapUsers(ldapServer *Ldap) ([]LdapUser, error) {
|
||||
case "co":
|
||||
user.CountryName = attribute.Values[0]
|
||||
case "memberOf":
|
||||
user.MemberOf = attribute.Values[0]
|
||||
user.MemberOf = attribute.Values
|
||||
default:
|
||||
if propName, ok := ldapServer.CustomAttributes[attribute.Name]; ok {
|
||||
if user.Attributes == nil {
|
||||
@@ -263,42 +272,135 @@ func (l *LdapConn) GetLdapUsers(ldapServer *Ldap) ([]LdapUser, error) {
|
||||
return ldapUsers, nil
|
||||
}
|
||||
|
||||
// FIXME: The Base DN does not necessarily contain the Group
|
||||
//
|
||||
// func (l *ldapConn) GetLdapGroups(baseDn string) (map[string]ldapGroup, error) {
|
||||
// SearchFilter := "(objectClass=posixGroup)"
|
||||
// SearchAttributes := []string{"cn", "gidNumber"}
|
||||
// groupMap := make(map[string]ldapGroup)
|
||||
//
|
||||
// searchReq := goldap.NewSearchRequest(baseDn,
|
||||
// goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
|
||||
// SearchFilter, SearchAttributes, nil)
|
||||
// searchResult, err := l.Conn.Search(searchReq)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// if len(searchResult.Entries) == 0 {
|
||||
// return nil, errors.New("no result")
|
||||
// }
|
||||
//
|
||||
// for _, entry := range searchResult.Entries {
|
||||
// var ldapGroupItem ldapGroup
|
||||
// for _, attribute := range entry.Attributes {
|
||||
// switch attribute.Name {
|
||||
// case "gidNumber":
|
||||
// ldapGroupItem.GidNumber = attribute.Values[0]
|
||||
// break
|
||||
// case "cn":
|
||||
// ldapGroupItem.Cn = attribute.Values[0]
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// groupMap[ldapGroupItem.GidNumber] = ldapGroupItem
|
||||
// }
|
||||
//
|
||||
// return groupMap, nil
|
||||
// }
|
||||
// GetLdapGroups fetches LDAP groups and organizational units
|
||||
func (l *LdapConn) GetLdapGroups(ldapServer *Ldap) ([]LdapGroup, error) {
|
||||
var allGroups []LdapGroup
|
||||
|
||||
// Search for LDAP groups (groupOfNames, groupOfUniqueNames, posixGroup)
|
||||
groupFilters := []string{
|
||||
"(objectClass=groupOfNames)",
|
||||
"(objectClass=groupOfUniqueNames)",
|
||||
"(objectClass=posixGroup)",
|
||||
}
|
||||
|
||||
// Add Active Directory group filter
|
||||
if l.IsAD {
|
||||
groupFilters = append(groupFilters, "(objectClass=group)")
|
||||
}
|
||||
|
||||
// Build combined filter
|
||||
var filterBuilder strings.Builder
|
||||
filterBuilder.WriteString("(|")
|
||||
for _, filter := range groupFilters {
|
||||
filterBuilder.WriteString(filter)
|
||||
}
|
||||
filterBuilder.WriteString(")")
|
||||
|
||||
SearchAttributes := []string{"cn", "name", "description", "member", "uniqueMember", "memberUid"}
|
||||
searchReq := goldap.NewSearchRequest(ldapServer.BaseDn,
|
||||
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
|
||||
filterBuilder.String(), SearchAttributes, nil)
|
||||
|
||||
searchResult, err := l.Conn.SearchWithPaging(searchReq, 100)
|
||||
if err != nil {
|
||||
// Groups might not exist, which is okay
|
||||
return allGroups, nil
|
||||
}
|
||||
|
||||
for _, entry := range searchResult.Entries {
|
||||
group := LdapGroup{
|
||||
Dn: entry.DN,
|
||||
}
|
||||
|
||||
for _, attribute := range entry.Attributes {
|
||||
switch attribute.Name {
|
||||
case "cn":
|
||||
group.Cn = attribute.Values[0]
|
||||
case "name":
|
||||
group.Name = attribute.Values[0]
|
||||
case "description":
|
||||
if len(attribute.Values) > 0 {
|
||||
group.Description = attribute.Values[0]
|
||||
}
|
||||
case "member", "uniqueMember", "memberUid":
|
||||
group.Member = append(group.Member, attribute.Values...)
|
||||
}
|
||||
}
|
||||
|
||||
// Use cn as name if name is not set
|
||||
if group.Name == "" {
|
||||
group.Name = group.Cn
|
||||
}
|
||||
|
||||
// Parse parent DN from the entry DN
|
||||
group.ParentDn = getParentDn(entry.DN)
|
||||
|
||||
allGroups = append(allGroups, group)
|
||||
}
|
||||
|
||||
// Also fetch organizational units as groups
|
||||
ouFilter := "(objectClass=organizationalUnit)"
|
||||
ouSearchReq := goldap.NewSearchRequest(ldapServer.BaseDn,
|
||||
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
|
||||
ouFilter, []string{"ou", "description"}, nil)
|
||||
|
||||
ouSearchResult, err := l.Conn.SearchWithPaging(ouSearchReq, 100)
|
||||
if err == nil {
|
||||
for _, entry := range ouSearchResult.Entries {
|
||||
ou := LdapGroup{
|
||||
Dn: entry.DN,
|
||||
}
|
||||
|
||||
for _, attribute := range entry.Attributes {
|
||||
switch attribute.Name {
|
||||
case "ou":
|
||||
ou.Name = attribute.Values[0]
|
||||
ou.Cn = attribute.Values[0]
|
||||
case "description":
|
||||
if len(attribute.Values) > 0 {
|
||||
ou.Description = attribute.Values[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse parent DN from the entry DN
|
||||
ou.ParentDn = getParentDn(entry.DN)
|
||||
|
||||
allGroups = append(allGroups, ou)
|
||||
}
|
||||
}
|
||||
|
||||
return allGroups, nil
|
||||
}
|
||||
|
||||
// getParentDn extracts the parent DN from a full DN
|
||||
func getParentDn(dn string) string {
|
||||
// Split DN by comma
|
||||
parts := strings.Split(dn, ",")
|
||||
if len(parts) <= 1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Remove the first component (the current node) and rejoin
|
||||
return strings.Join(parts[1:], ",")
|
||||
}
|
||||
|
||||
// parseDnToGroupName converts a DN to a group name
|
||||
func parseDnToGroupName(dn string) string {
|
||||
// Extract the CN or OU from the DN
|
||||
parts := strings.Split(dn, ",")
|
||||
if len(parts) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
firstPart := parts[0]
|
||||
// Extract value after = sign
|
||||
if idx := strings.Index(firstPart, "="); idx != -1 {
|
||||
return firstPart[idx+1:]
|
||||
}
|
||||
|
||||
return firstPart
|
||||
}
|
||||
|
||||
func AutoAdjustLdapUser(users []LdapUser) []LdapUser {
|
||||
res := make([]LdapUser, len(users))
|
||||
@@ -315,6 +417,7 @@ func AutoAdjustLdapUser(users []LdapUser) []LdapUser {
|
||||
Address: util.ReturnAnyNotEmpty(user.Address, user.PostalAddress, user.RegisteredAddress),
|
||||
Country: util.ReturnAnyNotEmpty(user.Country, user.CountryName),
|
||||
CountryName: user.CountryName,
|
||||
MemberOf: user.MemberOf,
|
||||
Attributes: user.Attributes,
|
||||
}
|
||||
}
|
||||
@@ -398,8 +501,22 @@ func SyncLdapUsers(owner string, syncUsers []LdapUser, ldapId string) (existUser
|
||||
}
|
||||
formatUserPhone(newUser)
|
||||
|
||||
// Assign user to groups based on memberOf attribute
|
||||
userGroups := []string{}
|
||||
if ldap.DefaultGroup != "" {
|
||||
newUser.Groups = []string{ldap.DefaultGroup}
|
||||
userGroups = append(userGroups, ldap.DefaultGroup)
|
||||
}
|
||||
|
||||
// Extract group names from memberOf DNs
|
||||
for _, memberDn := range syncUser.MemberOf {
|
||||
groupName := dnToGroupName(owner, memberDn)
|
||||
if groupName != "" {
|
||||
userGroups = append(userGroups, groupName)
|
||||
}
|
||||
}
|
||||
|
||||
if len(userGroups) > 0 {
|
||||
newUser.Groups = userGroups
|
||||
}
|
||||
|
||||
affected, err := AddUser(newUser, "en")
|
||||
@@ -420,6 +537,179 @@ func SyncLdapUsers(owner string, syncUsers []LdapUser, ldapId string) (existUser
|
||||
return existUsers, failedUsers, err
|
||||
}
|
||||
|
||||
// SyncLdapGroups syncs LDAP groups/OUs to Casdoor groups with hierarchy
|
||||
func SyncLdapGroups(owner string, ldapGroups []LdapGroup, ldapId string) (newGroups int, updatedGroups int, err error) {
|
||||
if len(ldapGroups) == 0 {
|
||||
return 0, 0, nil
|
||||
}
|
||||
|
||||
// Create a map of DN to group for quick lookup
|
||||
dnToGroup := make(map[string]*LdapGroup)
|
||||
for i := range ldapGroups {
|
||||
dnToGroup[ldapGroups[i].Dn] = &ldapGroups[i]
|
||||
}
|
||||
|
||||
// Get existing groups for this organization
|
||||
existingGroups, err := GetGroups(owner)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
existingGroupMap := make(map[string]*Group)
|
||||
for _, group := range existingGroups {
|
||||
existingGroupMap[group.Name] = group
|
||||
}
|
||||
|
||||
ldap, err := GetLdap(ldapId)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
// Process groups in hierarchical order (parents before children)
|
||||
processedGroups := make(map[string]bool)
|
||||
var processGroup func(ldapGroup *LdapGroup) error
|
||||
|
||||
processGroup = func(ldapGroup *LdapGroup) error {
|
||||
if processedGroups[ldapGroup.Dn] {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate group name from DN
|
||||
groupName := dnToGroupName(owner, ldapGroup.Dn)
|
||||
if groupName == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Determine parent
|
||||
var parentId string
|
||||
var isTopGroup bool
|
||||
|
||||
if ldapGroup.ParentDn == "" || ldapGroup.ParentDn == ldap.BaseDn {
|
||||
isTopGroup = true
|
||||
parentId = ""
|
||||
} else {
|
||||
// Process parent first
|
||||
if parentGroup, exists := dnToGroup[ldapGroup.ParentDn]; exists {
|
||||
err := processGroup(parentGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parentId = dnToGroupName(owner, ldapGroup.ParentDn)
|
||||
} else {
|
||||
isTopGroup = true
|
||||
}
|
||||
}
|
||||
|
||||
// Check if group already exists
|
||||
if existingGroup, exists := existingGroupMap[groupName]; exists {
|
||||
// Update existing group
|
||||
existingGroup.DisplayName = ldapGroup.Name
|
||||
existingGroup.ParentId = parentId
|
||||
existingGroup.IsTopGroup = isTopGroup
|
||||
existingGroup.Type = "ldap-synced"
|
||||
existingGroup.UpdatedTime = util.GetCurrentTime()
|
||||
|
||||
_, err := UpdateGroup(existingGroup.GetId(), existingGroup)
|
||||
if err == nil {
|
||||
updatedGroups++
|
||||
}
|
||||
} else {
|
||||
// Create new group
|
||||
newGroup := &Group{
|
||||
Owner: owner,
|
||||
Name: groupName,
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
UpdatedTime: util.GetCurrentTime(),
|
||||
DisplayName: ldapGroup.Name,
|
||||
ParentId: parentId,
|
||||
IsTopGroup: isTopGroup,
|
||||
Type: "ldap-synced",
|
||||
IsEnabled: true,
|
||||
}
|
||||
|
||||
_, err := AddGroup(newGroup)
|
||||
if err == nil {
|
||||
newGroups++
|
||||
existingGroupMap[groupName] = newGroup
|
||||
}
|
||||
}
|
||||
|
||||
processedGroups[ldapGroup.Dn] = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Process all groups
|
||||
for i := range ldapGroups {
|
||||
err := processGroup(&ldapGroups[i])
|
||||
if err != nil {
|
||||
// Log error but continue processing other groups
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return newGroups, updatedGroups, nil
|
||||
}
|
||||
|
||||
// dnToGroupName converts an LDAP DN to a Casdoor group name
|
||||
func dnToGroupName(owner, dn string) string {
|
||||
if dn == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Parse DN to extract meaningful components
|
||||
parts := strings.Split(dn, ",")
|
||||
|
||||
// Build a hierarchical name from DN components (excluding DC parts)
|
||||
var nameComponents []string
|
||||
for _, part := range parts {
|
||||
part = strings.TrimSpace(part)
|
||||
lowerPart := strings.ToLower(part)
|
||||
|
||||
// Skip DC (domain component) parts
|
||||
if strings.HasPrefix(lowerPart, "dc=") {
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract value after = sign
|
||||
if idx := strings.Index(part, "="); idx != -1 {
|
||||
value := part[idx+1:]
|
||||
nameComponents = append(nameComponents, value)
|
||||
}
|
||||
}
|
||||
|
||||
if len(nameComponents) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Reverse to get top-down hierarchy
|
||||
for i, j := 0, len(nameComponents)-1; i < j; i, j = i+1, j-1 {
|
||||
nameComponents[i], nameComponents[j] = nameComponents[j], nameComponents[i]
|
||||
}
|
||||
|
||||
// Join with underscore to create a unique group name
|
||||
groupName := strings.Join(nameComponents, "_")
|
||||
|
||||
// Sanitize group name - replace invalid characters with underscores
|
||||
// Keep only alphanumeric characters, underscores, and hyphens
|
||||
var sanitized strings.Builder
|
||||
for _, r := range groupName {
|
||||
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_' || r == '-' {
|
||||
sanitized.WriteRune(r)
|
||||
} else {
|
||||
sanitized.WriteRune('_')
|
||||
}
|
||||
}
|
||||
groupName = sanitized.String()
|
||||
|
||||
// Remove consecutive underscores and trim
|
||||
for strings.Contains(groupName, "__") {
|
||||
groupName = strings.ReplaceAll(groupName, "__", "_")
|
||||
}
|
||||
groupName = strings.Trim(groupName, "_")
|
||||
|
||||
return groupName
|
||||
}
|
||||
|
||||
func GetExistUuids(owner string, uuids []string) ([]string, error) {
|
||||
var existUuids []string
|
||||
|
||||
|
||||
193
object/oauth_dcr.go
Normal file
193
object/oauth_dcr.go
Normal file
@@ -0,0 +1,193 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// DynamicClientRegistrationRequest represents an RFC 7591 client registration request
|
||||
type DynamicClientRegistrationRequest struct {
|
||||
ClientName string `json:"client_name,omitempty"`
|
||||
RedirectUris []string `json:"redirect_uris,omitempty"`
|
||||
GrantTypes []string `json:"grant_types,omitempty"`
|
||||
ResponseTypes []string `json:"response_types,omitempty"`
|
||||
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
|
||||
ApplicationType string `json:"application_type,omitempty"`
|
||||
Contacts []string `json:"contacts,omitempty"`
|
||||
LogoUri string `json:"logo_uri,omitempty"`
|
||||
ClientUri string `json:"client_uri,omitempty"`
|
||||
PolicyUri string `json:"policy_uri,omitempty"`
|
||||
TosUri string `json:"tos_uri,omitempty"`
|
||||
Scope string `json:"scope,omitempty"`
|
||||
}
|
||||
|
||||
// DynamicClientRegistrationResponse represents an RFC 7591 client registration response
|
||||
type DynamicClientRegistrationResponse struct {
|
||||
ClientId string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret,omitempty"`
|
||||
ClientIdIssuedAt int64 `json:"client_id_issued_at,omitempty"`
|
||||
ClientSecretExpiresAt int64 `json:"client_secret_expires_at,omitempty"`
|
||||
ClientName string `json:"client_name,omitempty"`
|
||||
RedirectUris []string `json:"redirect_uris,omitempty"`
|
||||
GrantTypes []string `json:"grant_types,omitempty"`
|
||||
ResponseTypes []string `json:"response_types,omitempty"`
|
||||
TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"`
|
||||
ApplicationType string `json:"application_type,omitempty"`
|
||||
Contacts []string `json:"contacts,omitempty"`
|
||||
LogoUri string `json:"logo_uri,omitempty"`
|
||||
ClientUri string `json:"client_uri,omitempty"`
|
||||
PolicyUri string `json:"policy_uri,omitempty"`
|
||||
TosUri string `json:"tos_uri,omitempty"`
|
||||
Scope string `json:"scope,omitempty"`
|
||||
RegistrationClientUri string `json:"registration_client_uri,omitempty"`
|
||||
RegistrationAccessToken string `json:"registration_access_token,omitempty"`
|
||||
}
|
||||
|
||||
// DcrError represents an RFC 7591 error response
|
||||
type DcrError struct {
|
||||
Error string `json:"error"`
|
||||
ErrorDescription string `json:"error_description,omitempty"`
|
||||
}
|
||||
|
||||
// RegisterDynamicClient creates a new application based on DCR request
|
||||
func RegisterDynamicClient(req *DynamicClientRegistrationRequest, organization string) (*DynamicClientRegistrationResponse, *DcrError, error) {
|
||||
// Validate organization exists and has DCR enabled
|
||||
org, err := GetOrganization(util.GetId("admin", organization))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if org == nil {
|
||||
return nil, &DcrError{
|
||||
Error: "invalid_client_metadata",
|
||||
ErrorDescription: "organization not found",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Check if DCR is enabled for this organization
|
||||
if org.DcrPolicy == "" || org.DcrPolicy == "disabled" {
|
||||
return nil, &DcrError{
|
||||
Error: "invalid_client_metadata",
|
||||
ErrorDescription: "dynamic client registration is disabled for this organization",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if len(req.RedirectUris) == 0 {
|
||||
return nil, &DcrError{
|
||||
Error: "invalid_redirect_uri",
|
||||
ErrorDescription: "redirect_uris is required and must contain at least one URI",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Set defaults
|
||||
if req.ClientName == "" {
|
||||
clientIdPrefix := util.GenerateClientId()
|
||||
if len(clientIdPrefix) > 8 {
|
||||
clientIdPrefix = clientIdPrefix[:8]
|
||||
}
|
||||
req.ClientName = fmt.Sprintf("DCR Client %s", clientIdPrefix)
|
||||
}
|
||||
if len(req.GrantTypes) == 0 {
|
||||
req.GrantTypes = []string{"authorization_code"}
|
||||
}
|
||||
if len(req.ResponseTypes) == 0 {
|
||||
req.ResponseTypes = []string{"code"}
|
||||
}
|
||||
if req.TokenEndpointAuthMethod == "" {
|
||||
req.TokenEndpointAuthMethod = "client_secret_basic"
|
||||
}
|
||||
if req.ApplicationType == "" {
|
||||
req.ApplicationType = "web"
|
||||
}
|
||||
|
||||
// Generate unique application name
|
||||
randomName := util.GetRandomName()
|
||||
appName := fmt.Sprintf("dcr_%s", randomName)
|
||||
|
||||
// Create Application object
|
||||
// Note: DCR applications are created under "admin" owner by default
|
||||
// This can be made configurable in future versions
|
||||
clientId := util.GenerateClientId()
|
||||
clientSecret := util.GenerateClientSecret()
|
||||
createdTime := util.GetCurrentTime()
|
||||
|
||||
application := &Application{
|
||||
Owner: "admin",
|
||||
Name: appName,
|
||||
Organization: organization,
|
||||
CreatedTime: createdTime,
|
||||
DisplayName: req.ClientName,
|
||||
Category: "Agent",
|
||||
Type: "MCP",
|
||||
Scopes: []*ScopeItem{},
|
||||
Logo: req.LogoUri,
|
||||
HomepageUrl: req.ClientUri,
|
||||
ClientId: clientId,
|
||||
ClientSecret: clientSecret,
|
||||
RedirectUris: req.RedirectUris,
|
||||
GrantTypes: req.GrantTypes,
|
||||
EnablePassword: false,
|
||||
EnableSignUp: false,
|
||||
DisableSignin: false,
|
||||
EnableSigninSession: false,
|
||||
EnableCodeSignin: true,
|
||||
EnableAutoSignin: false,
|
||||
TokenFormat: "JWT",
|
||||
ExpireInHours: 168,
|
||||
RefreshExpireInHours: 168,
|
||||
CookieExpireInHours: 720,
|
||||
FormOffset: 2,
|
||||
Tags: []string{"dcr"},
|
||||
TermsOfUse: req.TosUri,
|
||||
}
|
||||
|
||||
// Add the application
|
||||
affected, err := AddApplication(application)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if !affected {
|
||||
return nil, &DcrError{
|
||||
Error: "invalid_client_metadata",
|
||||
ErrorDescription: "failed to create client application",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Build response
|
||||
response := &DynamicClientRegistrationResponse{
|
||||
ClientId: clientId,
|
||||
ClientSecret: clientSecret,
|
||||
ClientIdIssuedAt: time.Now().Unix(),
|
||||
ClientSecretExpiresAt: 0, // Never expires
|
||||
ClientName: req.ClientName,
|
||||
RedirectUris: req.RedirectUris,
|
||||
GrantTypes: req.GrantTypes,
|
||||
ResponseTypes: req.ResponseTypes,
|
||||
TokenEndpointAuthMethod: req.TokenEndpointAuthMethod,
|
||||
ApplicationType: req.ApplicationType,
|
||||
Contacts: req.Contacts,
|
||||
LogoUri: req.LogoUri,
|
||||
ClientUri: req.ClientUri,
|
||||
PolicyUri: req.PolicyUri,
|
||||
TosUri: req.TosUri,
|
||||
Scope: req.Scope,
|
||||
}
|
||||
|
||||
return response, nil, nil
|
||||
}
|
||||
@@ -49,6 +49,7 @@ type Order struct {
|
||||
type ProductInfo struct {
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
CreatedTime string `json:"createdTime,omitempty"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Image string `json:"image,omitempty"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
|
||||
@@ -276,7 +276,7 @@ func PayOrder(providerName, host, paymentEnv string, order *Order, lang string)
|
||||
OutOrderId: payResp.OrderId,
|
||||
}
|
||||
|
||||
if provider.Type == "Dummy" || provider.Type == "Balance" {
|
||||
if provider.Type == "Balance" {
|
||||
payment.State = pp.PaymentStatePaid
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ func PayOrder(providerName, host, paymentEnv string, order *Order, lang string)
|
||||
}
|
||||
|
||||
order.Payment = payment.Name
|
||||
if provider.Type == "Dummy" || provider.Type == "Balance" {
|
||||
if provider.Type == "Balance" {
|
||||
order.State = "Paid"
|
||||
order.Message = "Payment successful"
|
||||
order.UpdateTime = util.GetCurrentTime()
|
||||
@@ -364,7 +364,7 @@ func PayOrder(providerName, host, paymentEnv string, order *Order, lang string)
|
||||
}
|
||||
|
||||
// Update product stock after order state is persisted (for instant payment methods)
|
||||
if provider.Type == "Dummy" || provider.Type == "Balance" {
|
||||
if provider.Type == "Balance" {
|
||||
err = UpdateProductStock(orderProductInfos)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
||||
@@ -92,6 +92,8 @@ type Organization struct {
|
||||
AccountMenu string `xorm:"varchar(20)" json:"accountMenu"`
|
||||
AccountItems []*AccountItem `xorm:"mediumtext" json:"accountItems"`
|
||||
|
||||
DcrPolicy string `xorm:"varchar(100)" json:"dcrPolicy"`
|
||||
|
||||
OrgBalance float64 `json:"orgBalance"`
|
||||
UserBalance float64 `json:"userBalance"`
|
||||
BalanceCredit float64 `json:"balanceCredit"`
|
||||
|
||||
@@ -29,9 +29,9 @@ import (
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
||||
_ "github.com/go-sql-driver/mysql" // db = mysql
|
||||
_ "github.com/lib/pq" // db = postgres
|
||||
_ "github.com/go-sql-driver/mysql" // db = mysql
|
||||
_ "github.com/lib/pq" // db = postgres
|
||||
_ "github.com/microsoft/go-mssqldb" // db = mssql
|
||||
"github.com/xorm-io/xorm"
|
||||
"github.com/xorm-io/xorm/core"
|
||||
"github.com/xorm-io/xorm/names"
|
||||
|
||||
@@ -303,7 +303,7 @@ func NotifyPayment(body []byte, owner string, paymentName string, lang string) (
|
||||
order.Message = "Payment successful"
|
||||
order.UpdateTime = util.GetCurrentTime()
|
||||
} else if payment.State == pp.PaymentStateError {
|
||||
order.State = "PaymentFailed"
|
||||
order.State = "Failed"
|
||||
order.Message = payment.Message
|
||||
order.UpdateTime = util.GetCurrentTime()
|
||||
} else if payment.State == pp.PaymentStateCanceled {
|
||||
|
||||
@@ -53,7 +53,8 @@ type Provider struct {
|
||||
|
||||
Host string `xorm:"varchar(100)" json:"host"`
|
||||
Port int `json:"port"`
|
||||
DisableSsl bool `json:"disableSsl"` // If the provider type is WeChat, DisableSsl means EnableQRCode, if type is Google, it means sync phone number
|
||||
DisableSsl bool `json:"disableSsl"` // Deprecated: Use SslMode instead. If the provider type is WeChat, DisableSsl means EnableQRCode, if type is Google, it means sync phone number
|
||||
SslMode string `xorm:"varchar(100)" json:"sslMode"` // "Auto" (empty means Auto), "Enable", "Disable"
|
||||
Title string `xorm:"varchar(100)" json:"title"`
|
||||
Content string `xorm:"varchar(2000)" json:"content"` // If provider type is WeChat, Content means QRCode string by Base64 encoding
|
||||
Receiver string `xorm:"varchar(100)" json:"receiver"`
|
||||
|
||||
327
object/syncer_awsiam.go
Normal file
327
object/syncer_awsiam.go
Normal file
@@ -0,0 +1,327 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// AwsIamSyncerProvider implements SyncerProvider for AWS IAM API-based syncers
|
||||
type AwsIamSyncerProvider struct {
|
||||
Syncer *Syncer
|
||||
iamClient *iam.IAM
|
||||
}
|
||||
|
||||
// InitAdapter initializes the AWS IAM syncer
|
||||
func (p *AwsIamSyncerProvider) InitAdapter() error {
|
||||
// syncer.Host should be the AWS region (e.g., "us-east-1")
|
||||
// syncer.User should be the AWS Access Key ID
|
||||
// syncer.Password should be the AWS Secret Access Key
|
||||
|
||||
region := p.Syncer.Host
|
||||
if region == "" {
|
||||
return fmt.Errorf("AWS region (host field) is required for AWS IAM syncer")
|
||||
}
|
||||
|
||||
accessKeyId := p.Syncer.User
|
||||
if accessKeyId == "" {
|
||||
return fmt.Errorf("AWS Access Key ID (user field) is required for AWS IAM syncer")
|
||||
}
|
||||
|
||||
secretAccessKey := p.Syncer.Password
|
||||
if secretAccessKey == "" {
|
||||
return fmt.Errorf("AWS Secret Access Key (password field) is required for AWS IAM syncer")
|
||||
}
|
||||
|
||||
// Create AWS session
|
||||
sess, err := session.NewSession(&aws.Config{
|
||||
Region: aws.String(region),
|
||||
Credentials: credentials.NewStaticCredentials(accessKeyId, secretAccessKey, ""),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create AWS session: %w", err)
|
||||
}
|
||||
|
||||
// Create IAM client
|
||||
p.iamClient = iam.New(sess)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetOriginalUsers retrieves all users from AWS IAM API
|
||||
func (p *AwsIamSyncerProvider) GetOriginalUsers() ([]*OriginalUser, error) {
|
||||
if p.iamClient == nil {
|
||||
if err := p.InitAdapter(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return p.getAwsIamUsers()
|
||||
}
|
||||
|
||||
// AddUser adds a new user to AWS IAM (not supported for read-only API)
|
||||
func (p *AwsIamSyncerProvider) AddUser(user *OriginalUser) (bool, error) {
|
||||
// AWS IAM syncer is typically read-only
|
||||
return false, fmt.Errorf("adding users to AWS IAM is not supported")
|
||||
}
|
||||
|
||||
// UpdateUser updates an existing user in AWS IAM (not supported for read-only API)
|
||||
func (p *AwsIamSyncerProvider) UpdateUser(user *OriginalUser) (bool, error) {
|
||||
// AWS IAM syncer is typically read-only
|
||||
return false, fmt.Errorf("updating users in AWS IAM is not supported")
|
||||
}
|
||||
|
||||
// TestConnection tests the AWS IAM API connection
|
||||
func (p *AwsIamSyncerProvider) TestConnection() error {
|
||||
if p.iamClient == nil {
|
||||
if err := p.InitAdapter(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Try to list users with a limit of 1 to test the connection
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
input := &iam.ListUsersInput{
|
||||
MaxItems: aws.Int64(1),
|
||||
}
|
||||
|
||||
_, err := p.iamClient.ListUsersWithContext(ctx, input)
|
||||
return err
|
||||
}
|
||||
|
||||
// Close closes any open connections
|
||||
func (p *AwsIamSyncerProvider) Close() error {
|
||||
// AWS IAM client doesn't require explicit cleanup
|
||||
p.iamClient = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAwsIamUsers gets all users from AWS IAM API
|
||||
func (p *AwsIamSyncerProvider) getAwsIamUsers() ([]*OriginalUser, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
allUsers := []*iam.User{}
|
||||
var marker *string
|
||||
|
||||
// Paginate through all users
|
||||
for {
|
||||
input := &iam.ListUsersInput{
|
||||
Marker: marker,
|
||||
}
|
||||
|
||||
result, err := p.iamClient.ListUsersWithContext(ctx, input)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list IAM users: %w", err)
|
||||
}
|
||||
|
||||
allUsers = append(allUsers, result.Users...)
|
||||
|
||||
if result.IsTruncated == nil || !*result.IsTruncated {
|
||||
break
|
||||
}
|
||||
|
||||
marker = result.Marker
|
||||
}
|
||||
|
||||
// Convert AWS IAM users to Casdoor OriginalUser
|
||||
originalUsers := []*OriginalUser{}
|
||||
for _, iamUser := range allUsers {
|
||||
originalUser, err := p.awsIamUserToOriginalUser(iamUser)
|
||||
if err != nil {
|
||||
// Log error but continue processing other users
|
||||
userName := "unknown"
|
||||
if iamUser.UserName != nil {
|
||||
userName = *iamUser.UserName
|
||||
}
|
||||
fmt.Printf("Warning: Failed to convert IAM user %s: %v\n", userName, err)
|
||||
continue
|
||||
}
|
||||
originalUsers = append(originalUsers, originalUser)
|
||||
}
|
||||
|
||||
return originalUsers, nil
|
||||
}
|
||||
|
||||
// awsIamUserToOriginalUser converts AWS IAM user to Casdoor OriginalUser
|
||||
func (p *AwsIamSyncerProvider) awsIamUserToOriginalUser(iamUser *iam.User) (*OriginalUser, error) {
|
||||
if iamUser == nil {
|
||||
return nil, fmt.Errorf("IAM user is nil")
|
||||
}
|
||||
|
||||
user := &OriginalUser{
|
||||
Address: []string{},
|
||||
Properties: map[string]string{},
|
||||
Groups: []string{},
|
||||
}
|
||||
|
||||
// Set ID from UserId (unique identifier)
|
||||
if iamUser.UserId != nil {
|
||||
user.Id = *iamUser.UserId
|
||||
}
|
||||
|
||||
// Set Name from UserName
|
||||
if iamUser.UserName != nil {
|
||||
user.Name = *iamUser.UserName
|
||||
}
|
||||
|
||||
// Set DisplayName (use UserName if not available separately)
|
||||
if iamUser.UserName != nil {
|
||||
user.DisplayName = *iamUser.UserName
|
||||
}
|
||||
|
||||
// Set CreatedTime from CreateDate
|
||||
if iamUser.CreateDate != nil {
|
||||
user.CreatedTime = iamUser.CreateDate.Format(time.RFC3339)
|
||||
} else {
|
||||
user.CreatedTime = util.GetCurrentTime()
|
||||
}
|
||||
|
||||
// Get user tags which might contain additional information
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
tagsInput := &iam.ListUserTagsInput{
|
||||
UserName: iamUser.UserName,
|
||||
}
|
||||
|
||||
tagsResult, err := p.iamClient.ListUserTagsWithContext(ctx, tagsInput)
|
||||
if err == nil && tagsResult != nil {
|
||||
// Process tags to extract additional user information
|
||||
for _, tag := range tagsResult.Tags {
|
||||
if tag.Key != nil && tag.Value != nil {
|
||||
key := *tag.Key
|
||||
value := *tag.Value
|
||||
|
||||
switch key {
|
||||
case "Email", "email":
|
||||
user.Email = value
|
||||
case "Phone", "phone":
|
||||
user.Phone = value
|
||||
case "DisplayName", "displayName":
|
||||
user.DisplayName = value
|
||||
case "FirstName", "firstName":
|
||||
user.FirstName = value
|
||||
case "LastName", "lastName":
|
||||
user.LastName = value
|
||||
case "Title", "title":
|
||||
user.Title = value
|
||||
case "Department", "department":
|
||||
user.Affiliation = value
|
||||
default:
|
||||
// Store other tags in Properties
|
||||
user.Properties[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AWS IAM users are active by default unless specified in tags
|
||||
// Check if there's a "Status" or "Active" tag
|
||||
if status, ok := user.Properties["Status"]; ok {
|
||||
if status == "Inactive" || status == "Disabled" {
|
||||
user.IsForbidden = true
|
||||
}
|
||||
}
|
||||
if active, ok := user.Properties["Active"]; ok {
|
||||
if active == "false" || active == "False" || active == "0" {
|
||||
user.IsForbidden = true
|
||||
}
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// GetOriginalGroups retrieves all groups from AWS IAM
|
||||
func (p *AwsIamSyncerProvider) GetOriginalGroups() ([]*OriginalGroup, error) {
|
||||
if p.iamClient == nil {
|
||||
if err := p.InitAdapter(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
allGroups := []*iam.Group{}
|
||||
var marker *string
|
||||
|
||||
// Paginate through all groups
|
||||
for {
|
||||
input := &iam.ListGroupsInput{
|
||||
Marker: marker,
|
||||
}
|
||||
|
||||
result, err := p.iamClient.ListGroupsWithContext(ctx, input)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list IAM groups: %w", err)
|
||||
}
|
||||
|
||||
allGroups = append(allGroups, result.Groups...)
|
||||
|
||||
if result.IsTruncated == nil || !*result.IsTruncated {
|
||||
break
|
||||
}
|
||||
|
||||
marker = result.Marker
|
||||
}
|
||||
|
||||
// Convert AWS IAM groups to Casdoor OriginalGroup
|
||||
originalGroups := []*OriginalGroup{}
|
||||
for _, iamGroup := range allGroups {
|
||||
if iamGroup.GroupId != nil && iamGroup.GroupName != nil {
|
||||
group := &OriginalGroup{
|
||||
Id: *iamGroup.GroupId,
|
||||
Name: *iamGroup.GroupName,
|
||||
}
|
||||
|
||||
if iamGroup.GroupName != nil {
|
||||
group.DisplayName = *iamGroup.GroupName
|
||||
}
|
||||
|
||||
originalGroups = append(originalGroups, group)
|
||||
}
|
||||
}
|
||||
|
||||
return originalGroups, nil
|
||||
}
|
||||
|
||||
// GetOriginalUserGroups retrieves the group IDs that a user belongs to
|
||||
func (p *AwsIamSyncerProvider) GetOriginalUserGroups(userId string) ([]string, error) {
|
||||
if p.iamClient == nil {
|
||||
if err := p.InitAdapter(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Note: AWS IAM API requires UserName to query groups, but this interface provides UserId.
|
||||
// This is a known limitation. To properly implement this, we would need to:
|
||||
// 1. Maintain a mapping cache from UserId to UserName, or
|
||||
// 2. Modify the interface to accept both UserId and UserName
|
||||
// For now, returning empty groups to maintain interface compatibility.
|
||||
// TODO: Implement user group synchronization by maintaining a UserId->UserName mapping
|
||||
|
||||
return []string{}, nil
|
||||
}
|
||||
@@ -175,14 +175,18 @@ func (p *DingtalkSyncerProvider) getDingtalkAccessToken() (string, error) {
|
||||
return tokenResp.AccessToken, nil
|
||||
}
|
||||
|
||||
// getDingtalkDepartments gets all department IDs from DingTalk API
|
||||
// getDingtalkDepartments gets all department IDs from DingTalk API recursively
|
||||
func (p *DingtalkSyncerProvider) getDingtalkDepartments(accessToken string) ([]int64, error) {
|
||||
return p.getDingtalkDepartmentsRecursive(accessToken, 1)
|
||||
}
|
||||
|
||||
// getDingtalkDepartmentsRecursive recursively fetches all departments starting from parentDeptId
|
||||
func (p *DingtalkSyncerProvider) getDingtalkDepartmentsRecursive(accessToken string, parentDeptId int64) ([]int64, error) {
|
||||
apiUrl := fmt.Sprintf("https://oapi.dingtalk.com/topapi/v2/department/listsub?access_token=%s",
|
||||
url.QueryEscape(accessToken))
|
||||
|
||||
// Get root department (dept_id=1)
|
||||
postData := map[string]interface{}{
|
||||
"dept_id": 1,
|
||||
"dept_id": parentDeptId,
|
||||
}
|
||||
|
||||
data, err := p.postJSON(apiUrl, postData)
|
||||
@@ -201,9 +205,16 @@ func (p *DingtalkSyncerProvider) getDingtalkDepartments(accessToken string) ([]i
|
||||
deptResp.Errcode, deptResp.Errmsg)
|
||||
}
|
||||
|
||||
deptIds := []int64{1} // Include root department
|
||||
// Start with the parent department itself
|
||||
deptIds := []int64{parentDeptId}
|
||||
|
||||
// Recursively fetch all child departments
|
||||
for _, dept := range deptResp.Result {
|
||||
deptIds = append(deptIds, dept.DeptId)
|
||||
childDeptIds, err := p.getDingtalkDepartmentsRecursive(accessToken, dept.DeptId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deptIds = append(deptIds, childDeptIds...)
|
||||
}
|
||||
|
||||
return deptIds, nil
|
||||
@@ -415,6 +426,7 @@ func (p *DingtalkSyncerProvider) dingtalkUserToOriginalUser(dingtalkUser *Dingta
|
||||
Address: []string{},
|
||||
Properties: map[string]string{},
|
||||
Groups: []string{},
|
||||
DingTalk: dingtalkUser.UserId, // Link DingTalk provider account
|
||||
}
|
||||
|
||||
// Add department IDs to Groups field
|
||||
|
||||
@@ -72,6 +72,8 @@ func GetSyncerProvider(syncer *Syncer) SyncerProvider {
|
||||
return &OktaSyncerProvider{Syncer: syncer}
|
||||
case "SCIM":
|
||||
return &SCIMSyncerProvider{Syncer: syncer}
|
||||
case "AWS IAM":
|
||||
return &AwsIamSyncerProvider{Syncer: syncer}
|
||||
case "Keycloak":
|
||||
return &KeycloakSyncerProvider{
|
||||
DatabaseSyncerProvider: DatabaseSyncerProvider{Syncer: syncer},
|
||||
|
||||
@@ -376,6 +376,7 @@ func (p *LarkSyncerProvider) larkUserToOriginalUser(larkUser *LarkUser) *Origina
|
||||
Address: []string{},
|
||||
Properties: map[string]string{},
|
||||
Groups: []string{},
|
||||
Lark: larkUser.UserId, // Link Lark provider account
|
||||
}
|
||||
|
||||
// Set avatar if available
|
||||
|
||||
@@ -70,6 +70,18 @@ func (syncer *Syncer) updateUserForOriginalFields(user *User, key string) (bool,
|
||||
|
||||
columns := syncer.getCasdoorColumns()
|
||||
columns = append(columns, "affiliation", "hash", "pre_hash")
|
||||
|
||||
// Add provider-specific field for API-based syncers to enable login binding
|
||||
// This allows synced users to login via their provider accounts
|
||||
switch syncer.Type {
|
||||
case "WeCom":
|
||||
columns = append(columns, "wecom")
|
||||
case "DingTalk":
|
||||
columns = append(columns, "dingtalk")
|
||||
case "Lark":
|
||||
columns = append(columns, "lark")
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.Where(key+" = ? and owner = ?", syncer.getUserValue(&oldUser, key), oldUser.Owner).Cols(columns...).Update(user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
@@ -275,6 +275,7 @@ func (p *WecomSyncerProvider) wecomUserToOriginalUser(wecomUser *WecomUser) *Ori
|
||||
Address: []string{},
|
||||
Properties: map[string]string{},
|
||||
Groups: []string{},
|
||||
Wecom: wecomUser.UserId, // Link WeCom provider account
|
||||
}
|
||||
|
||||
// Set gender
|
||||
|
||||
@@ -43,6 +43,7 @@ type Token struct {
|
||||
CodeChallenge string `xorm:"varchar(100)" json:"codeChallenge"`
|
||||
CodeIsUsed bool `json:"codeIsUsed"`
|
||||
CodeExpireIn int64 `json:"codeExpireIn"`
|
||||
Resource string `xorm:"varchar(255)" json:"resource"` // RFC 8707 Resource Indicator
|
||||
}
|
||||
|
||||
func GetTokenCount(owner, organization, field, value string) (int64, error) {
|
||||
|
||||
@@ -338,6 +338,50 @@ func getClaimsWithoutThirdIdp(claims Claims) ClaimsWithoutThirdIdp {
|
||||
return res
|
||||
}
|
||||
|
||||
// getUserFieldValue gets the value of a user field by name, handling special cases like Roles and Permissions
|
||||
func getUserFieldValue(user *User, fieldName string) (interface{}, bool) {
|
||||
if user == nil {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Handle special fields that need conversion
|
||||
switch fieldName {
|
||||
case "Roles":
|
||||
return getUserRoleNames(user), true
|
||||
case "Permissions":
|
||||
return getUserPermissionNames(user), true
|
||||
case "permissionNames":
|
||||
permissionNames := []string{}
|
||||
for _, val := range user.Permissions {
|
||||
permissionNames = append(permissionNames, val.Name)
|
||||
}
|
||||
return permissionNames, true
|
||||
}
|
||||
|
||||
// Handle Properties fields (e.g., Properties.my_field)
|
||||
if strings.HasPrefix(fieldName, "Properties.") {
|
||||
parts := strings.Split(fieldName, ".")
|
||||
if len(parts) == 2 {
|
||||
propName := parts[1]
|
||||
if user.Properties != nil {
|
||||
if value, exists := user.Properties[propName]; exists {
|
||||
return value, true
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Use reflection to get the field value
|
||||
userValue := reflect.ValueOf(user).Elem()
|
||||
userField := userValue.FieldByName(fieldName)
|
||||
if userField.IsValid() {
|
||||
return userField.Interface(), true
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func getClaimsCustom(claims Claims, tokenField []string, tokenAttributes []*JwtItem) jwt.MapClaims {
|
||||
res := make(jwt.MapClaims)
|
||||
|
||||
@@ -414,16 +458,30 @@ func getClaimsCustom(claims Claims, tokenField []string, tokenAttributes []*JwtI
|
||||
}
|
||||
|
||||
for _, item := range tokenAttributes {
|
||||
valueList := replaceAttributeValue(claims.User, item.Value)
|
||||
if len(valueList) == 0 {
|
||||
continue
|
||||
var value interface{}
|
||||
|
||||
// If Category is "Existing Field", get the actual field value from the user
|
||||
if item.Category == "Existing Field" {
|
||||
fieldValue, found := getUserFieldValue(claims.User, item.Value)
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
value = fieldValue
|
||||
} else {
|
||||
// Default behavior: use replaceAttributeValue for "Static Value" or empty category
|
||||
valueList := replaceAttributeValue(claims.User, item.Value)
|
||||
if len(valueList) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if item.Type == "String" {
|
||||
value = valueList[0]
|
||||
} else {
|
||||
value = valueList
|
||||
}
|
||||
}
|
||||
|
||||
if item.Type == "String" {
|
||||
res[item.Name] = valueList[0]
|
||||
} else {
|
||||
res[item.Name] = valueList
|
||||
}
|
||||
res[item.Name] = value
|
||||
}
|
||||
|
||||
return res
|
||||
@@ -451,7 +509,7 @@ func refineUser(user *User) *User {
|
||||
return user
|
||||
}
|
||||
|
||||
func generateJwtToken(application *Application, user *User, provider string, signinMethod string, nonce string, scope string, host string) (string, string, string, error) {
|
||||
func generateJwtToken(application *Application, user *User, provider string, signinMethod string, nonce string, scope string, resource string, host string) (string, string, string, error) {
|
||||
nowTime := time.Now()
|
||||
expireTime := nowTime.Add(time.Duration(application.ExpireInHours * float64(time.Hour)))
|
||||
refreshExpireTime := nowTime.Add(time.Duration(application.RefreshExpireInHours * float64(time.Hour)))
|
||||
@@ -495,7 +553,10 @@ func generateJwtToken(application *Application, user *User, provider string, sig
|
||||
},
|
||||
}
|
||||
|
||||
if application.IsShared {
|
||||
// RFC 8707: Use resource as audience when provided
|
||||
if resource != "" {
|
||||
claims.Audience = []string{resource}
|
||||
} else if application.IsShared {
|
||||
claims.Audience = []string{application.ClientId + "-org-" + user.Owner}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -92,6 +93,26 @@ type DeviceAuthResponse struct {
|
||||
Interval int `json:"interval"`
|
||||
}
|
||||
|
||||
// validateResourceURI validates that the resource parameter is a valid absolute URI
|
||||
// according to RFC 8707 Section 2
|
||||
func validateResourceURI(resource string) error {
|
||||
if resource == "" {
|
||||
return nil // empty resource is allowed (backward compatibility)
|
||||
}
|
||||
|
||||
parsedURL, err := url.Parse(resource)
|
||||
if err != nil {
|
||||
return fmt.Errorf("resource must be a valid URI")
|
||||
}
|
||||
|
||||
// RFC 8707: The resource parameter must be an absolute URI
|
||||
if !parsedURL.IsAbs() {
|
||||
return fmt.Errorf("resource must be an absolute URI")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExpireTokenByAccessToken(accessToken string) (bool, *Application, *Token, error) {
|
||||
token, err := GetTokenByAccessToken(accessToken)
|
||||
if err != nil {
|
||||
@@ -138,7 +159,7 @@ func CheckOAuthLogin(clientId string, responseType string, redirectUri string, s
|
||||
return "", application, nil
|
||||
}
|
||||
|
||||
func GetOAuthCode(userId string, clientId string, provider string, signinMethod string, responseType string, redirectUri string, scope string, state string, nonce string, challenge string, host string, lang string) (*Code, error) {
|
||||
func GetOAuthCode(userId string, clientId string, provider string, signinMethod string, responseType string, redirectUri string, scope string, state string, nonce string, challenge string, resource string, host string, lang string) (*Code, error) {
|
||||
user, err := GetUser(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -169,11 +190,19 @@ func GetOAuthCode(userId string, clientId string, provider string, signinMethod
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Validate resource parameter (RFC 8707)
|
||||
if err := validateResourceURI(resource); err != nil {
|
||||
return &Code{
|
||||
Message: err.Error(),
|
||||
Code: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
err = ExtendUserWithRolesAndPermissions(user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, provider, signinMethod, nonce, scope, host)
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, provider, signinMethod, nonce, scope, resource, host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -198,6 +227,7 @@ func GetOAuthCode(userId string, clientId string, provider string, signinMethod
|
||||
CodeChallenge: challenge,
|
||||
CodeIsUsed: false,
|
||||
CodeExpireIn: time.Now().Add(time.Minute * 5).Unix(),
|
||||
Resource: resource,
|
||||
}
|
||||
_, err = AddToken(token)
|
||||
if err != nil {
|
||||
@@ -210,7 +240,7 @@ func GetOAuthCode(userId string, clientId string, provider string, signinMethod
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetOAuthToken(grantType string, clientId string, clientSecret string, code string, verifier string, scope string, nonce string, username string, password string, host string, refreshToken string, tag string, avatar string, lang string, subjectToken string, subjectTokenType string, audience string) (interface{}, error) {
|
||||
func GetOAuthToken(grantType string, clientId string, clientSecret string, code string, verifier string, scope string, nonce string, username string, password string, host string, refreshToken string, tag string, avatar string, lang string, subjectToken string, subjectTokenType string, audience string, resource string) (interface{}, error) {
|
||||
application, err := GetApplicationByClientId(clientId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -236,7 +266,7 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
||||
var tokenError *TokenError
|
||||
switch grantType {
|
||||
case "authorization_code": // Authorization Code Grant
|
||||
token, tokenError, err = GetAuthorizationCodeToken(application, clientSecret, code, verifier)
|
||||
token, tokenError, err = GetAuthorizationCodeToken(application, clientSecret, code, verifier, resource)
|
||||
case "password": // Resource Owner Password Credentials Grant
|
||||
token, tokenError, err = GetPasswordToken(application, username, password, scope, host)
|
||||
case "client_credentials": // Client Credentials Grant
|
||||
@@ -391,7 +421,7 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newAccessToken, newRefreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", scope, host)
|
||||
newAccessToken, newRefreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", scope, "", host)
|
||||
if err != nil {
|
||||
return &TokenError{
|
||||
Error: EndpointError,
|
||||
@@ -545,7 +575,7 @@ func createGuestUserToken(application *Application, clientSecret string, verifie
|
||||
}
|
||||
|
||||
// Generate JWT token
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, guestUser, "", "", "", "", "")
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, guestUser, "", "", "", "", "", "")
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: EndpointError,
|
||||
@@ -595,7 +625,7 @@ func generateGuestUsername() string {
|
||||
|
||||
// GetAuthorizationCodeToken
|
||||
// Authorization code flow
|
||||
func GetAuthorizationCodeToken(application *Application, clientSecret string, code string, verifier string) (*Token, *TokenError, error) {
|
||||
func GetAuthorizationCodeToken(application *Application, clientSecret string, code string, verifier string, resource string) (*Token, *TokenError, error) {
|
||||
if code == "" {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidRequest,
|
||||
@@ -663,6 +693,14 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RFC 8707: Validate resource parameter matches the one in the authorization request
|
||||
if resource != token.Resource {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: fmt.Sprintf("resource parameter does not match authorization request, expected: [%s], got: [%s]", token.Resource, resource),
|
||||
}, nil
|
||||
}
|
||||
|
||||
nowUnix := time.Now().Unix()
|
||||
if nowUnix > token.CodeExpireIn {
|
||||
// code must be used within 5 minutes
|
||||
@@ -719,7 +757,7 @@ func GetPasswordToken(application *Application, username string, password string
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", scope, host)
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", scope, "", host)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: EndpointError,
|
||||
@@ -765,7 +803,7 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
|
||||
Type: "application",
|
||||
}
|
||||
|
||||
accessToken, _, tokenName, err := generateJwtToken(application, nullUser, "", "", "", scope, host)
|
||||
accessToken, _, tokenName, err := generateJwtToken(application, nullUser, "", "", "", scope, "", host)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: EndpointError,
|
||||
@@ -829,7 +867,7 @@ func GetTokenByUser(application *Application, user *User, scope string, nonce st
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", nonce, scope, host)
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", nonce, scope, "", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -936,7 +974,7 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", "", host)
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", "", "", host)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: EndpointError,
|
||||
@@ -1110,7 +1148,7 @@ func GetTokenExchangeToken(application *Application, clientSecret string, subjec
|
||||
}
|
||||
|
||||
// Generate new JWT token
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", scope, host)
|
||||
accessToken, refreshToken, tokenName, err := generateJwtToken(application, user, "", "", "", scope, "", host)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: EndpointError,
|
||||
|
||||
@@ -405,7 +405,7 @@ func ClearUserOAuthProperties(user *User, providerType string) (bool, error) {
|
||||
|
||||
func userVisible(isAdmin bool, item *AccountItem) bool {
|
||||
if item == nil {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
if item.ViewRule == "Admin" && !isAdmin {
|
||||
@@ -564,10 +564,11 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, allowDis
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
if oldUser.SignupApplication != newUser.SignupApplication {
|
||||
item := GetAccountItemByName("Signup application", organization)
|
||||
|
||||
if oldUser.Language != newUser.Language {
|
||||
item := GetAccountItemByName("Language", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.SignupApplication = oldUser.SignupApplication
|
||||
newUser.Language = oldUser.Language
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
@@ -600,6 +601,83 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, allowDis
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Balance != newUser.Balance {
|
||||
item := GetAccountItemByName("Balance", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Balance = oldUser.Balance
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.BalanceCredit != newUser.BalanceCredit {
|
||||
item := GetAccountItemByName("Balance credit", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.BalanceCredit = oldUser.BalanceCredit
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.BalanceCurrency != newUser.BalanceCurrency {
|
||||
item := GetAccountItemByName("Balance currency", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.BalanceCurrency = oldUser.BalanceCurrency
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
oldUserCartJson, _ := json.Marshal(oldUser.Cart)
|
||||
if newUser.Cart == nil {
|
||||
newUser.Cart = []ProductInfo{}
|
||||
}
|
||||
newUserCartJson, _ := json.Marshal(newUser.Cart)
|
||||
if string(oldUserCartJson) != string(newUserCartJson) {
|
||||
item := GetAccountItemByName("Cart", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Cart = oldUser.Cart
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Score != newUser.Score {
|
||||
item := GetAccountItemByName("Score", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Score = oldUser.Score
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Karma != newUser.Karma {
|
||||
item := GetAccountItemByName("Karma", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Karma = oldUser.Karma
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Ranking != newUser.Ranking {
|
||||
item := GetAccountItemByName("Ranking", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Ranking = oldUser.Ranking
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.SignupApplication != newUser.SignupApplication {
|
||||
item := GetAccountItemByName("Signup application", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.SignupApplication = oldUser.SignupApplication
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.IdCard != newUser.IdCard {
|
||||
item := GetAccountItemByName("ID card", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
@@ -728,51 +806,6 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, allowDis
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Balance != newUser.Balance {
|
||||
item := GetAccountItemByName("Balance", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Balance = oldUser.Balance
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Score != newUser.Score {
|
||||
item := GetAccountItemByName("Score", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Score = oldUser.Score
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Karma != newUser.Karma {
|
||||
item := GetAccountItemByName("Karma", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Karma = oldUser.Karma
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Language != newUser.Language {
|
||||
item := GetAccountItemByName("Language", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Language = oldUser.Language
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Ranking != newUser.Ranking {
|
||||
item := GetAccountItemByName("Ranking", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
newUser.Ranking = oldUser.Ranking
|
||||
} else {
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
}
|
||||
|
||||
if oldUser.Currency != newUser.Currency {
|
||||
item := GetAccountItemByName("Currency", organization)
|
||||
if !userVisible(isAdmin, item) {
|
||||
@@ -792,6 +825,11 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, allowDis
|
||||
}
|
||||
|
||||
for _, accountItem := range itemsChanged {
|
||||
// Skip nil items - these occur when a field doesn't have a corresponding
|
||||
// account item configuration, meaning no validation rules apply
|
||||
if accountItem == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if pass, err := CheckAccountItemModifyRule(accountItem, isAdmin, lang); !pass {
|
||||
return pass, err
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
mssql "github.com/denisenkom/go-mssqldb"
|
||||
mssql "github.com/microsoft/go-mssqldb"
|
||||
|
||||
"github.com/lib/pq"
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
59
object/wellknown_oauth_prm.go
Normal file
59
object/wellknown_oauth_prm.go
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// OauthProtectedResourceMetadata represents RFC 9728 OAuth 2.0 Protected Resource Metadata
|
||||
type OauthProtectedResourceMetadata struct {
|
||||
Resource string `json:"resource"`
|
||||
AuthorizationServers []string `json:"authorization_servers"`
|
||||
BearerMethodsSupported []string `json:"bearer_methods_supported,omitempty"`
|
||||
ScopesSupported []string `json:"scopes_supported,omitempty"`
|
||||
ResourceSigningAlg []string `json:"resource_signing_alg_values_supported,omitempty"`
|
||||
ResourceDocumentation string `json:"resource_documentation,omitempty"`
|
||||
}
|
||||
|
||||
// GetOauthProtectedResourceMetadata returns RFC 9728 Protected Resource Metadata for global discovery
|
||||
func GetOauthProtectedResourceMetadata(host string) OauthProtectedResourceMetadata {
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
|
||||
return OauthProtectedResourceMetadata{
|
||||
Resource: originBackend,
|
||||
AuthorizationServers: []string{originBackend},
|
||||
BearerMethodsSupported: []string{"header"},
|
||||
ScopesSupported: []string{"openid", "profile", "email", "read", "write"},
|
||||
ResourceSigningAlg: []string{"RS256"},
|
||||
}
|
||||
}
|
||||
|
||||
// GetOauthProtectedResourceMetadataByApplication returns RFC 9728 Protected Resource Metadata for application-specific discovery
|
||||
func GetOauthProtectedResourceMetadataByApplication(host string, applicationName string) OauthProtectedResourceMetadata {
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
|
||||
// For application-specific discovery, the resource identifier includes the application name
|
||||
resourceIdentifier := fmt.Sprintf("%s/.well-known/%s", originBackend, applicationName)
|
||||
authServer := fmt.Sprintf("%s/.well-known/%s", originBackend, applicationName)
|
||||
|
||||
return OauthProtectedResourceMetadata{
|
||||
Resource: resourceIdentifier,
|
||||
AuthorizationServers: []string{authServer},
|
||||
BearerMethodsSupported: []string{"header"},
|
||||
ScopesSupported: []string{"openid", "profile", "email", "read", "write"},
|
||||
ResourceSigningAlg: []string{"RS256"},
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ type OidcDiscovery struct {
|
||||
TokenEndpoint string `json:"token_endpoint"`
|
||||
UserinfoEndpoint string `json:"userinfo_endpoint"`
|
||||
DeviceAuthorizationEndpoint string `json:"device_authorization_endpoint"`
|
||||
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
|
||||
JwksUri string `json:"jwks_uri"`
|
||||
IntrospectionEndpoint string `json:"introspection_endpoint"`
|
||||
ResponseTypesSupported []string `json:"response_types_supported"`
|
||||
@@ -40,6 +41,7 @@ type OidcDiscovery struct {
|
||||
SubjectTypesSupported []string `json:"subject_types_supported"`
|
||||
IdTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported"`
|
||||
ScopesSupported []string `json:"scopes_supported"`
|
||||
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
|
||||
ClaimsSupported []string `json:"claims_supported"`
|
||||
RequestParameterSupported bool `json:"request_parameter_supported"`
|
||||
RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported"`
|
||||
@@ -123,6 +125,23 @@ func GetOidcDiscovery(host string, applicationName string) OidcDiscovery {
|
||||
jwksUri = fmt.Sprintf("%s/.well-known/jwks", originBackend)
|
||||
}
|
||||
|
||||
// Default OIDC scopes
|
||||
scopes := []string{"openid", "email", "profile", "address", "phone", "offline_access"}
|
||||
|
||||
// Merge application-specific custom scopes if application is provided
|
||||
if applicationName != "" {
|
||||
applicationId := util.GetId("admin", applicationName)
|
||||
application, err := GetApplication(applicationId)
|
||||
if err == nil && application != nil && len(application.Scopes) > 0 {
|
||||
for _, scope := range application.Scopes {
|
||||
// Add custom scope names to the scopes list
|
||||
if scope.Name != "" {
|
||||
scopes = append(scopes, scope.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Examples:
|
||||
// https://login.okta.com/.well-known/openid-configuration
|
||||
// https://auth0.auth0.com/.well-known/openid-configuration
|
||||
@@ -134,6 +153,7 @@ func GetOidcDiscovery(host string, applicationName string) OidcDiscovery {
|
||||
TokenEndpoint: fmt.Sprintf("%s/api/login/oauth/access_token", originBackend),
|
||||
UserinfoEndpoint: fmt.Sprintf("%s/api/userinfo", originBackend),
|
||||
DeviceAuthorizationEndpoint: fmt.Sprintf("%s/api/device-auth", originBackend),
|
||||
RegistrationEndpoint: fmt.Sprintf("%s/api/oauth/register", originBackend),
|
||||
JwksUri: jwksUri,
|
||||
IntrospectionEndpoint: fmt.Sprintf("%s/api/login/oauth/introspect", originBackend),
|
||||
ResponseTypesSupported: []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none"},
|
||||
@@ -141,7 +161,8 @@ func GetOidcDiscovery(host string, applicationName string) OidcDiscovery {
|
||||
GrantTypesSupported: []string{"authorization_code", "implicit", "password", "client_credentials", "refresh_token", "urn:ietf:params:oauth:grant-type:device_code", "urn:ietf:params:oauth:grant-type:token-exchange"},
|
||||
SubjectTypesSupported: []string{"public"},
|
||||
IdTokenSigningAlgValuesSupported: []string{"RS256", "RS512", "ES256", "ES384", "ES512"},
|
||||
ScopesSupported: []string{"openid", "email", "profile", "address", "phone", "offline_access"},
|
||||
ScopesSupported: scopes,
|
||||
CodeChallengeMethodsSupported: []string{"S256"},
|
||||
ClaimsSupported: []string{"iss", "ver", "sub", "aud", "iat", "exp", "id", "type", "displayName", "avatar", "permanentAvatar", "email", "phone", "location", "affiliation", "title", "homepage", "bio", "tag", "region", "language", "score", "ranking", "isOnline", "isAdmin", "isForbidden", "signupApplication", "ldap"},
|
||||
RequestParameterSupported: true,
|
||||
RequestObjectSigningAlgValuesSupported: []string{"HS256", "HS384", "HS512"},
|
||||
41
pp/dummy.go
41
pp/dummy.go
@@ -14,22 +14,59 @@
|
||||
|
||||
package pp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type DummyPaymentProvider struct{}
|
||||
|
||||
type DummyOrderInfo struct {
|
||||
Price float64 `json:"price"`
|
||||
Currency string `json:"currency"`
|
||||
ProductDisplayName string `json:"productDisplayName"`
|
||||
}
|
||||
|
||||
func NewDummyPaymentProvider() (*DummyPaymentProvider, error) {
|
||||
pp := &DummyPaymentProvider{}
|
||||
return pp, nil
|
||||
}
|
||||
|
||||
func (pp *DummyPaymentProvider) Pay(r *PayReq) (*PayResp, error) {
|
||||
// Encode payment information in OrderId for later retrieval in Notify.
|
||||
// Note: This is a test/mock provider and the OrderId is only used internally for testing.
|
||||
// Real payment providers would receive this information from their external payment gateway.
|
||||
orderInfo := DummyOrderInfo{
|
||||
Price: r.Price,
|
||||
Currency: r.Currency,
|
||||
ProductDisplayName: "",
|
||||
}
|
||||
orderInfoBytes, err := json.Marshal(orderInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encode order info: %w", err)
|
||||
}
|
||||
|
||||
return &PayResp{
|
||||
PayUrl: r.ReturnUrl,
|
||||
PayUrl: r.ReturnUrl,
|
||||
OrderId: string(orderInfoBytes),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (pp *DummyPaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||
// Decode payment information from OrderId
|
||||
var orderInfo DummyOrderInfo
|
||||
if orderId != "" {
|
||||
err := json.Unmarshal([]byte(orderId), &orderInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode order info: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return &NotifyResult{
|
||||
PaymentStatus: PaymentStatePaid,
|
||||
PaymentStatus: PaymentStatePaid,
|
||||
Price: orderInfo.Price,
|
||||
Currency: orderInfo.Currency,
|
||||
ProductDisplayName: orderInfo.ProductDisplayName,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,17 @@ func denyMcpRequest(ctx *context.Context) {
|
||||
Data: T(ctx, "auth:Unauthorized operation"),
|
||||
})
|
||||
|
||||
// Add WWW-Authenticate header per MCP Authorization spec (RFC 9728)
|
||||
// Use the same logic as getOriginFromHost to determine the scheme
|
||||
host := ctx.Request.Host
|
||||
scheme := "https"
|
||||
if !strings.Contains(host, ".") {
|
||||
// localhost:8000 or computer-name:80
|
||||
scheme = "http"
|
||||
}
|
||||
resourceMetadataUrl := fmt.Sprintf("%s://%s/.well-known/oauth-protected-resource", scheme, host)
|
||||
ctx.Output.Header("WWW-Authenticate", fmt.Sprintf("Bearer realm=\"casdoor\", resource_metadata=\"%s\"", resourceMetadataUrl))
|
||||
|
||||
ctx.Output.SetStatus(http.StatusUnauthorized)
|
||||
_ = ctx.Output.JSON(resp, true, false)
|
||||
}
|
||||
|
||||
@@ -65,6 +65,22 @@ func RecordMessage(ctx *context.Context) {
|
||||
|
||||
userId := getUser(ctx)
|
||||
|
||||
// Special handling for set-password endpoint to capture target user
|
||||
if ctx.Request.URL.Path == "/api/set-password" {
|
||||
// Parse form if not already parsed
|
||||
if err := ctx.Request.ParseForm(); err != nil {
|
||||
fmt.Printf("RecordMessage() error parsing form: %s\n", err.Error())
|
||||
} else {
|
||||
userOwner := ctx.Request.Form.Get("userOwner")
|
||||
userName := ctx.Request.Form.Get("userName")
|
||||
|
||||
if userOwner != "" && userName != "" {
|
||||
targetUserId := util.GetId(userOwner, userName)
|
||||
ctx.Input.SetParam("recordTargetUserId", targetUserId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Input.SetParam("recordUserId", userId)
|
||||
}
|
||||
|
||||
@@ -76,7 +92,20 @@ func AfterRecordMessage(ctx *context.Context) {
|
||||
}
|
||||
|
||||
userId := ctx.Input.Params()["recordUserId"]
|
||||
if userId != "" {
|
||||
targetUserId := ctx.Input.Params()["recordTargetUserId"]
|
||||
|
||||
// For set-password endpoint, use target user if available
|
||||
// We use defensive error handling here (log instead of panic) because target user
|
||||
// parsing is a new feature. If it fails, we gracefully fall back to the regular
|
||||
// userId flow or empty user/org fields, maintaining backward compatibility.
|
||||
if record.Action == "set-password" && targetUserId != "" {
|
||||
owner, user, err := util.GetOwnerAndNameFromIdWithError(targetUserId)
|
||||
if err != nil {
|
||||
fmt.Printf("AfterRecordMessage() error parsing target user %s: %s\n", targetUserId, err.Error())
|
||||
} else {
|
||||
record.Organization, record.User = owner, user
|
||||
}
|
||||
} else if userId != "" {
|
||||
owner, user, err := util.GetOwnerAndNameFromIdWithError(userId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -298,6 +298,7 @@ func InitAPI() {
|
||||
web.Router("/api/login/oauth/access_token", &controllers.ApiController{}, "POST:GetOAuthToken")
|
||||
web.Router("/api/login/oauth/refresh_token", &controllers.ApiController{}, "POST:RefreshToken")
|
||||
web.Router("/api/login/oauth/introspect", &controllers.ApiController{}, "POST:IntrospectToken")
|
||||
web.Router("/api/oauth/register", &controllers.ApiController{}, "POST:DynamicClientRegister")
|
||||
|
||||
web.Router("/api/get-records", &controllers.ApiController{}, "GET:GetRecords")
|
||||
web.Router("/api/get-records-filter", &controllers.ApiController{}, "POST:GetRecordsByFilter")
|
||||
@@ -320,10 +321,14 @@ func InitAPI() {
|
||||
|
||||
web.Router("/.well-known/openid-configuration", &controllers.RootController{}, "GET:GetOidcDiscovery")
|
||||
web.Router("/.well-known/:application/openid-configuration", &controllers.RootController{}, "GET:GetOidcDiscoveryByApplication")
|
||||
web.Router("/.well-known/oauth-authorization-server", &controllers.RootController{}, "GET:GetOAuthServerMetadata")
|
||||
web.Router("/.well-known/:application/oauth-authorization-server", &controllers.RootController{}, "GET:GetOAuthServerMetadataByApplication")
|
||||
web.Router("/.well-known/jwks", &controllers.RootController{}, "*:GetJwks")
|
||||
web.Router("/.well-known/:application/jwks", &controllers.RootController{}, "*:GetJwksByApplication")
|
||||
web.Router("/.well-known/webfinger", &controllers.RootController{}, "GET:GetWebFinger")
|
||||
web.Router("/.well-known/:application/webfinger", &controllers.RootController{}, "GET:GetWebFingerByApplication")
|
||||
web.Router("/.well-known/oauth-protected-resource", &controllers.RootController{}, "GET:GetOauthProtectedResourceMetadata")
|
||||
web.Router("/.well-known/:application/oauth-protected-resource", &controllers.RootController{}, "GET:GetOauthProtectedResourceMetadataByApplication")
|
||||
|
||||
web.Router("/cas/:organization/:application/serviceValidate", &controllers.RootController{}, "GET:CasServiceValidate")
|
||||
web.Router("/cas/:organization/:application/proxyValidate", &controllers.RootController{}, "GET:CasProxyValidate")
|
||||
|
||||
@@ -89,7 +89,7 @@ func fastAutoSignin(ctx *context.Context) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
code, err := object.GetOAuthCode(userId, clientId, "", "autoSignin", responseType, redirectUri, scope, state, nonce, codeChallenge, ctx.Request.Host, getAcceptLanguage(ctx))
|
||||
code, err := object.GetOAuthCode(userId, clientId, "", "autoSignin", responseType, redirectUri, scope, state, nonce, codeChallenge, "", ctx.Request.Host, getAcceptLanguage(ctx))
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if code.Message != "" {
|
||||
|
||||
@@ -48,6 +48,7 @@ import ProviderTable from "./table/ProviderTable";
|
||||
import SigninMethodTable from "./table/SigninMethodTable";
|
||||
import SignupTable from "./table/SignupTable";
|
||||
import SamlAttributeTable from "./table/SamlAttributeTable";
|
||||
import ScopeTable from "./table/ScopeTable";
|
||||
import PromptPage from "./auth/PromptPage";
|
||||
import copy from "copy-to-clipboard";
|
||||
import ThemeEditor from "./common/theme/ThemeEditor";
|
||||
@@ -58,6 +59,7 @@ import * as GroupBackend from "./backend/GroupBackend";
|
||||
import TokenAttributeTable from "./table/TokenAttributeTable";
|
||||
import {Content, Header} from "antd/es/layout/layout";
|
||||
import Sider from "antd/es/layout/Sider";
|
||||
import PaginateSelect from "./common/PaginateSelect";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
@@ -149,7 +151,6 @@ class ApplicationEditPage extends React.Component {
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getApplication();
|
||||
this.getOrganizations();
|
||||
this.getGroups();
|
||||
}
|
||||
|
||||
getApplication() {
|
||||
@@ -174,6 +175,10 @@ class ApplicationEditPage extends React.Component {
|
||||
application.tags = [];
|
||||
}
|
||||
|
||||
if (application.otherDomains === null || application.otherDomains === undefined) {
|
||||
application.otherDomains = [];
|
||||
}
|
||||
|
||||
this.setState({
|
||||
application: application,
|
||||
});
|
||||
@@ -201,17 +206,6 @@ class ApplicationEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getGroups() {
|
||||
GroupBackend.getGroups(this.state.owner)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
groups: res.data,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getCerts(application) {
|
||||
let owner = application.organization;
|
||||
if (application.isShared) {
|
||||
@@ -318,6 +312,61 @@ class ApplicationEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel(i18next.t("general:Category"), i18next.t("general:Category - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<Select
|
||||
virtual={false}
|
||||
style={{width: "100%"}}
|
||||
value={this.state.application.category}
|
||||
onChange={(value) => {
|
||||
this.updateApplicationField("category", value);
|
||||
if (value === "Agent") {
|
||||
this.updateApplicationField("type", "MCP");
|
||||
} else {
|
||||
this.updateApplicationField("type", "All");
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Option value="Default">Default</Option>
|
||||
<Option value="Agent">Agent</Option>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel(i18next.t("general:Type"), i18next.t("general:Type - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<Select
|
||||
virtual={false}
|
||||
style={{width: "100%"}}
|
||||
value={this.state.application.type}
|
||||
onChange={(value) => {
|
||||
this.updateApplicationField("type", value);
|
||||
}}
|
||||
>
|
||||
{
|
||||
(this.state.application.category === "Agent") ? (
|
||||
<>
|
||||
<Option value="MCP">MCP</Option>
|
||||
<Option value="A2A">A2A</Option>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Option value="All">All</Option>
|
||||
<Option value="OIDC">OIDC</Option>
|
||||
<Option value="OAuth">OAuth</Option>
|
||||
<Option value="SAML">SAML</Option>
|
||||
<Option value="CAS">CAS</Option>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel(i18next.t("general:Is shared"), i18next.t("general:Is shared - Tooltip"))} :
|
||||
@@ -527,6 +576,22 @@ class ApplicationEditPage extends React.Component {
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
(this.state.application.category === "Agent") ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel(i18next.t("general:Scopes"), i18next.t("general:Scopes - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<ScopeTable
|
||||
title={i18next.t("general:Scopes")}
|
||||
table={this.state.application.scopes}
|
||||
onUpdateTable={(value) => {this.updateApplicationField("scopes", value);}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
) : null
|
||||
}
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel(i18next.t("application:Token format"), i18next.t("application:Token format - Tooltip"))} :
|
||||
@@ -611,24 +676,30 @@ class ApplicationEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("ldap:Default group"), i18next.t("ldap:Default group - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={21}>
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.application.defaultGroup ?? []} onChange={(value => {
|
||||
this.updateApplicationField("defaultGroup", value);
|
||||
})}
|
||||
>
|
||||
<Option key={""} value={""}>
|
||||
<PaginateSelect
|
||||
virtual
|
||||
style={{width: "100%"}}
|
||||
allowClear
|
||||
placeholder={i18next.t("general:Default")}
|
||||
value={this.state.application.defaultGroup || undefined}
|
||||
fetchPage={GroupBackend.getGroups}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.owner, false, page, pageSize, field, searchText, "", ""];
|
||||
}}
|
||||
reloadKey={this.state.owner}
|
||||
optionMapper={(group) => Setting.getOption(
|
||||
<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>
|
||||
{group.type === "Physical" ? <UsergroupAddOutlined /> : <HolderOutlined />}
|
||||
{group.displayName}
|
||||
</Space>,
|
||||
`${group.owner}/${group.name}`
|
||||
)}
|
||||
filterOption={false}
|
||||
onChange={(value) => {
|
||||
this.updateApplicationField("defaultGroup", value || "");
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
@@ -1306,6 +1377,71 @@ class ApplicationEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{this.state.activeMenuKey === "reverse-proxy" && (
|
||||
<React.Fragment>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel("Domain", "The public-facing domain for this application (e.g., blog.example.com)")} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<Input value={this.state.application.domain} placeholder="blog.example.com" onChange={e => {
|
||||
this.updateApplicationField("domain", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel("Other domains", "Additional domains that should also route to this application")} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<Select
|
||||
mode="tags"
|
||||
style={{width: "100%"}}
|
||||
value={this.state.application.otherDomains}
|
||||
onChange={(value) => {
|
||||
this.updateApplicationField("otherDomains", value);
|
||||
}}
|
||||
placeholder="Please input additional domains"
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel("Upstream host", "The upstream backend address to forward requests to (e.g., localhost:8080 or 192.168.1.100)")} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<Input value={this.state.application.upstreamHost} placeholder="localhost:8080" onChange={e => {
|
||||
this.updateApplicationField("upstreamHost", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel("SSL mode", "SSL/TLS mode for the reverse proxy")} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.application.sslMode} onChange={(value => {this.updateApplicationField("sslMode", value);})}>
|
||||
<Option value="">{i18next.t("general:None")}</Option>
|
||||
<Option value="HTTPS and HTTP">HTTPS and HTTP</Option>
|
||||
<Option value="HTTPS Only">HTTPS Only</Option>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||
{Setting.getLabel("SSL cert", "Certificate to use for TLS termination")} :
|
||||
</Col>
|
||||
<Col span={21} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.application.sslCert} onChange={(value => {this.updateApplicationField("sslCert", value);})}>
|
||||
<Option value="">{i18next.t("general:None")}</Option>
|
||||
{
|
||||
this.state.certs.map((cert, index) => <Option key={index} value={cert.name}>{cert.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
)}</>;
|
||||
}
|
||||
|
||||
@@ -1318,11 +1454,12 @@ class ApplicationEditPage extends React.Component {
|
||||
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitApplicationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteApplication()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||
</div>
|
||||
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
|
||||
<Layout style={{background: "inherit"}}>
|
||||
} style={{margin: (Setting.isMobile()) ? "5px" : {}, height: "calc(100vh - 145px - 48px)", overflow: "hidden"}}
|
||||
styles={{body: {height: "100%"}}} type="inner">
|
||||
<Layout style={{background: "inherit", height: "100%", overflow: "auto"}}>
|
||||
{
|
||||
this.state.menuMode === "horizontal" || !this.state.menuMode ? (
|
||||
<Header style={{background: "inherit", padding: "0px"}}>
|
||||
<Header style={{background: "inherit", padding: "0px", position: "sticky", top: 0}}>
|
||||
<div className="demo-logo" />
|
||||
<Tabs
|
||||
onChange={(key) => {
|
||||
@@ -1337,12 +1474,13 @@ class ApplicationEditPage extends React.Component {
|
||||
{label: i18next.t("application:Providers"), key: "providers"},
|
||||
{label: i18next.t("application:UI Customization"), key: "ui-customization"},
|
||||
{label: i18next.t("application:Security"), key: "security"},
|
||||
{label: "Reverse Proxy", key: "reverse-proxy"},
|
||||
]}
|
||||
/>
|
||||
</Header>
|
||||
) : null
|
||||
}
|
||||
<Layout style={{background: "inherit", maxHeight: "calc(70vh - 70px)", overflow: "auto"}}>
|
||||
<Layout style={{background: "inherit", overflow: "auto"}}>
|
||||
{
|
||||
this.state.menuMode === "vertical" ? (
|
||||
<Sider width={200} style={{background: "inherit", position: "sticky", top: 0}}>
|
||||
@@ -1360,6 +1498,7 @@ class ApplicationEditPage extends React.Component {
|
||||
<Menu.Item key="providers">{i18next.t("application:Providers")}</Menu.Item>
|
||||
<Menu.Item key="ui-customization">{i18next.t("application:UI Customization")}</Menu.Item>
|
||||
<Menu.Item key="security">{i18next.t("application:Security")}</Menu.Item>
|
||||
<Menu.Item key="reverse-proxy">Reverse Proxy</Menu.Item>
|
||||
</Menu>
|
||||
</Sider>) : null
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ class ApplicationListPage extends BaseListPage {
|
||||
organization: organizationName,
|
||||
createdTime: moment().format(),
|
||||
displayName: `New Application - ${randomName}`,
|
||||
category: "Default",
|
||||
type: "All",
|
||||
scopes: [],
|
||||
logo: `${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`,
|
||||
enablePassword: true,
|
||||
enableSignUp: true,
|
||||
@@ -179,6 +182,40 @@ class ApplicationListPage extends BaseListPage {
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("displayName"),
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Category"),
|
||||
dataIndex: "category",
|
||||
key: "category",
|
||||
width: "120px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("category"),
|
||||
render: (text, record, index) => {
|
||||
const category = text;
|
||||
const tagColor = category === "Agent" ? "green" : "blue";
|
||||
return (
|
||||
<span style={{
|
||||
padding: "4px 8px",
|
||||
borderRadius: "4px",
|
||||
backgroundColor: tagColor,
|
||||
color: "white",
|
||||
fontWeight: "500",
|
||||
}}>
|
||||
{category}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Type"),
|
||||
dataIndex: "type",
|
||||
key: "type",
|
||||
width: "100px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("type"),
|
||||
render: (text, record, index) => {
|
||||
return text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Logo",
|
||||
dataIndex: "logo",
|
||||
|
||||
@@ -75,6 +75,11 @@ class CartListPage extends BaseListPage {
|
||||
|
||||
const owner = this.state.user?.owner || this.props.account.owner;
|
||||
const carts = this.state.data || [];
|
||||
const invalidCarts = carts.filter(item => item.isInvalid);
|
||||
if (invalidCarts.length > 0) {
|
||||
Setting.showMessage("error", i18next.t("product:Cart contains invalid products, please delete them before placing an order"));
|
||||
return;
|
||||
}
|
||||
if (carts.length === 0) {
|
||||
Setting.showMessage("error", i18next.t("product:Product list cannot be empty"));
|
||||
return;
|
||||
@@ -117,7 +122,11 @@ class CartListPage extends BaseListPage {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = user.cart.findIndex(item => item.name === record.name && item.price === record.price && (item.pricingName || "") === (record.pricingName || "") && (item.planName || "") === (record.planName || ""));
|
||||
const index = user.cart.findIndex(item =>
|
||||
item.name === record.name &&
|
||||
(record.isRecharge ? item.price === record.price : true) &&
|
||||
(item.pricingName || "") === (record.pricingName || "") &&
|
||||
(item.planName || "") === (record.planName || ""));
|
||||
if (index === -1) {
|
||||
Setting.showMessage("error", i18next.t("general:Failed to delete"));
|
||||
return;
|
||||
@@ -144,7 +153,7 @@ class CartListPage extends BaseListPage {
|
||||
return;
|
||||
}
|
||||
|
||||
const itemKey = `${record.name}-${record.price}-${record.pricingName || ""}-${record.planName || ""}`;
|
||||
const itemKey = `${record.name}-${record.price !== null ? record.price : "null"}-${record.pricingName || ""}-${record.planName || ""}`;
|
||||
if (this.updatingCartItemsRef?.[itemKey]) {
|
||||
return;
|
||||
}
|
||||
@@ -152,64 +161,71 @@ class CartListPage extends BaseListPage {
|
||||
this.updatingCartItemsRef[itemKey] = true;
|
||||
|
||||
const user = Setting.deepCopy(this.state.user);
|
||||
const index = user.cart.findIndex(item => item.name === record.name && item.price === record.price && (item.pricingName || "") === (record.pricingName || "") && (item.planName || "") === (record.planName || ""));
|
||||
const index = user.cart.findIndex(item =>
|
||||
item.name === record.name &&
|
||||
(record.isRecharge ? item.price === record.price : true) &&
|
||||
(item.pricingName || "") === (record.pricingName || "") &&
|
||||
(item.planName || "") === (record.planName || ""));
|
||||
if (index === -1) {
|
||||
delete this.updatingCartItemsRef[itemKey];
|
||||
return;
|
||||
}
|
||||
|
||||
if (index !== -1) {
|
||||
user.cart[index].quantity = newQuantity;
|
||||
|
||||
const newData = [...this.state.data];
|
||||
const dataIndex = newData.findIndex(item => item.name === record.name && item.price === record.price && (item.pricingName || "") === (record.pricingName || "") && (item.planName || "") === (record.planName || ""));
|
||||
if (dataIndex !== -1) {
|
||||
newData[dataIndex].quantity = newQuantity;
|
||||
this.setState({data: newData});
|
||||
}
|
||||
|
||||
this.setState(prevState => ({
|
||||
updatingCartItems: {
|
||||
...(prevState.updatingCartItems || {}),
|
||||
[itemKey]: true,
|
||||
},
|
||||
}));
|
||||
|
||||
UserBackend.updateUser(user.owner, user.name, user)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({user: user});
|
||||
} else {
|
||||
Setting.showMessage("error", res.msg);
|
||||
this.fetch();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
this.fetch();
|
||||
})
|
||||
.finally(() => {
|
||||
delete this.updatingCartItemsRef[itemKey];
|
||||
this.setState(prevState => {
|
||||
const updatingCartItems = {...(prevState.updatingCartItems || {})};
|
||||
delete updatingCartItems[itemKey];
|
||||
return {updatingCartItems};
|
||||
});
|
||||
});
|
||||
user.cart[index].quantity = newQuantity;
|
||||
const newData = [...this.state.data];
|
||||
const dataIndex = newData.findIndex(item =>
|
||||
item.name === record.name &&
|
||||
(record.price !== null ? item.price === record.price : true) &&
|
||||
(item.pricingName || "") === (record.pricingName || "") &&
|
||||
(item.planName || "") === (record.planName || ""));
|
||||
if (dataIndex !== -1) {
|
||||
newData[dataIndex].quantity = newQuantity;
|
||||
this.setState({data: newData});
|
||||
}
|
||||
|
||||
this.setState(prevState => ({
|
||||
updatingCartItems: {
|
||||
...(prevState.updatingCartItems || {}),
|
||||
[itemKey]: true,
|
||||
},
|
||||
}));
|
||||
|
||||
UserBackend.updateUser(user.owner, user.name, user)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({user: user});
|
||||
} else {
|
||||
Setting.showMessage("error", res.msg);
|
||||
this.fetch();
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
this.fetch();
|
||||
})
|
||||
.finally(() => {
|
||||
delete this.updatingCartItemsRef[itemKey];
|
||||
this.setState(prevState => {
|
||||
const updatingCartItems = {...(prevState.updatingCartItems || {})};
|
||||
delete updatingCartItems[itemKey];
|
||||
return {updatingCartItems};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
renderTable(carts) {
|
||||
const isEmpty = carts === undefined || carts === null || carts.length === 0;
|
||||
const hasInvalidItems = carts && carts.some(item => item.isInvalid);
|
||||
const owner = this.state.user?.owner || this.props.account.owner;
|
||||
|
||||
let total = 0;
|
||||
let currency = "";
|
||||
if (carts && carts.length > 0) {
|
||||
carts.forEach(item => {
|
||||
const validCarts = carts.filter(item => !item.isInvalid);
|
||||
validCarts.forEach(item => {
|
||||
total += item.price * item.quantity;
|
||||
});
|
||||
currency = carts[0].currency;
|
||||
currency = validCarts.length > 0 ? validCarts[0].currency : (carts[0].currency || "USD");
|
||||
}
|
||||
|
||||
const columns = [
|
||||
@@ -222,6 +238,9 @@ class CartListPage extends BaseListPage {
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
render: (text, record, index) => {
|
||||
if (record.isInvalid) {
|
||||
return <span style={{color: "red"}}>{text}</span>;
|
||||
}
|
||||
return (
|
||||
<Link to={`/products/${owner}/${text}`}>
|
||||
{text}
|
||||
@@ -235,6 +254,12 @@ class CartListPage extends BaseListPage {
|
||||
key: "displayName",
|
||||
width: "170px",
|
||||
sorter: true,
|
||||
render: (text, record) => {
|
||||
if (record.isInvalid) {
|
||||
return <span style={{color: "red"}}>{i18next.t("product:Invalid product")}</span>;
|
||||
}
|
||||
return text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("product:Image"),
|
||||
@@ -268,6 +293,9 @@ class CartListPage extends BaseListPage {
|
||||
sorter: true,
|
||||
render: (text, record) => {
|
||||
if (!text) {return null;}
|
||||
if (record.isInvalid) {
|
||||
return <span style={{color: "red"}}>{text}</span>;
|
||||
}
|
||||
return (
|
||||
<Link to={`/pricings/${owner}/${text}`}>
|
||||
{text}
|
||||
@@ -283,6 +311,9 @@ class CartListPage extends BaseListPage {
|
||||
sorter: true,
|
||||
render: (text, record) => {
|
||||
if (!text) {return null;}
|
||||
if (record.isInvalid) {
|
||||
return <span style={{color: "red"}}>{text}</span>;
|
||||
}
|
||||
return (
|
||||
<Link to={`/plans/${owner}/${text}`}>
|
||||
{text}
|
||||
@@ -297,7 +328,7 @@ class CartListPage extends BaseListPage {
|
||||
width: "100px",
|
||||
sorter: true,
|
||||
render: (text, record) => {
|
||||
const itemKey = `${record.name}-${record.price}-${record.pricingName || ""}-${record.planName || ""}`;
|
||||
const itemKey = `${record.name}-${record.price !== null ? record.price : "null"}-${record.pricingName || ""}-${record.planName || ""}`;
|
||||
const isUpdating = this.state.updatingCartItems?.[itemKey] === true;
|
||||
return (
|
||||
<QuantityStepper
|
||||
@@ -306,7 +337,7 @@ class CartListPage extends BaseListPage {
|
||||
onIncrease={() => this.updateCartItemQuantity(record, text + 1)}
|
||||
onDecrease={() => this.updateCartItemQuantity(record, text - 1)}
|
||||
onChange={null}
|
||||
disabled={isUpdating}
|
||||
disabled={isUpdating || record.isInvalid}
|
||||
/>
|
||||
);
|
||||
},
|
||||
@@ -320,7 +351,11 @@ class CartListPage extends BaseListPage {
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<div style={{display: "flex", flexWrap: "wrap", gap: "8px"}}>
|
||||
<Button type="primary" onClick={() => this.props.history.push(`/products/${owner}/${record.name}/buy`)}>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => this.props.history.push(`/products/${owner}/${record.name}/buy`)}
|
||||
disabled={record.isInvalid}
|
||||
>
|
||||
{i18next.t("general:Detail")}
|
||||
</Button>
|
||||
<PopconfirmModal
|
||||
@@ -358,7 +393,7 @@ class CartListPage extends BaseListPage {
|
||||
onConfirm={() => this.clearCart()}
|
||||
disabled={isEmpty}
|
||||
/>
|
||||
<Button type="primary" size="small" onClick={() => this.placeOrder()} disabled={isEmpty || this.state.isPlacingOrder} loading={this.state.isPlacingOrder}>{i18next.t("general:Place Order")}</Button>
|
||||
<Button type="primary" size="small" onClick={() => this.placeOrder()} disabled={isEmpty || hasInvalidItems || this.state.isPlacingOrder} loading={this.state.isPlacingOrder}>{i18next.t("general:Place Order")}</Button>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
@@ -379,7 +414,7 @@ class CartListPage extends BaseListPage {
|
||||
size="large"
|
||||
style={{height: "50px", fontSize: "20px", padding: "0 40px", borderRadius: "5px"}}
|
||||
onClick={() => this.placeOrder()}
|
||||
disabled={this.state.isPlacingOrder}
|
||||
disabled={hasInvalidItems || this.state.isPlacingOrder}
|
||||
loading={this.state.isPlacingOrder}
|
||||
>
|
||||
{i18next.t("general:Place Order")}
|
||||
@@ -404,17 +439,33 @@ class CartListPage extends BaseListPage {
|
||||
ProductBackend.getProduct(organizationName, item.name)
|
||||
.then(pRes => {
|
||||
if (pRes.status === "ok" && pRes.data) {
|
||||
const isCurrencyChanged = item.currency && pRes.data.currency && item.currency !== pRes.data.currency;
|
||||
if (isCurrencyChanged) {
|
||||
Setting.showMessage("warning", i18next.t("product:Product not found or invalid") + `: ${item.name}`);
|
||||
}
|
||||
return {
|
||||
...pRes.data,
|
||||
createdTime: item.createdTime,
|
||||
pricingName: item.pricingName,
|
||||
planName: item.planName,
|
||||
quantity: item.quantity,
|
||||
price: pRes.data.isRecharge ? item.price : pRes.data.price,
|
||||
isInvalid: isCurrencyChanged,
|
||||
};
|
||||
}
|
||||
return item;
|
||||
Setting.showMessage("warning", i18next.t("product:Product not found or invalid") + `: ${item.name}`);
|
||||
return {
|
||||
...item,
|
||||
isInvalid: true,
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
Setting.showMessage("warning", i18next.t("product:Product not found or invalid") + `: ${item.name}`);
|
||||
return {
|
||||
...item,
|
||||
isInvalid: true,
|
||||
};
|
||||
})
|
||||
.catch(() => item)
|
||||
);
|
||||
|
||||
const fullCartData = await Promise.all(productPromises);
|
||||
@@ -432,6 +483,10 @@ class CartListPage extends BaseListPage {
|
||||
const comparison = aValue > bValue ? 1 : -1;
|
||||
return params.sortOrder === "ascend" ? comparison : -comparison;
|
||||
});
|
||||
} else {
|
||||
sortedData.sort((a, b) => {
|
||||
return b.createdTime - a.createdTime;
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
@@ -445,6 +500,11 @@ class CartListPage extends BaseListPage {
|
||||
searchText: params.searchText,
|
||||
searchedColumn: params.searchedColumn,
|
||||
});
|
||||
|
||||
const invalidProducts = sortedData.filter(item => item.isInvalid);
|
||||
invalidProducts.forEach(item => {
|
||||
Setting.showMessage("error", i18next.t("product:Product not found or invalid") + `: ${item.name}`);
|
||||
});
|
||||
} else {
|
||||
this.setState({loading: false});
|
||||
Setting.showMessage("error", res.msg);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, Row, Select} from "antd";
|
||||
import PaginateSelect from "./common/PaginateSelect";
|
||||
import * as OrderBackend from "./backend/OrderBackend";
|
||||
import * as ProductBackend from "./backend/ProductBackend";
|
||||
import * as UserBackend from "./backend/UserBackend";
|
||||
@@ -41,7 +42,6 @@ class OrderEditPage extends React.Component {
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getOrder();
|
||||
this.getProducts();
|
||||
this.getUsers();
|
||||
this.getPayments();
|
||||
}
|
||||
|
||||
@@ -72,19 +72,6 @@ class OrderEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getUsers() {
|
||||
UserBackend.getUsers(this.state.organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
users: res.data,
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `Failed to get users: ${res.msg}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getPayments() {
|
||||
PaymentBackend.getPayments(this.state.organizationName)
|
||||
.then((res) => {
|
||||
@@ -184,13 +171,24 @@ class OrderEditPage extends React.Component {
|
||||
{i18next.t("general:User")}:
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.order.user} disabled={isViewMode} onChange={(value) => {
|
||||
this.updateOrderField("user", value);
|
||||
}}>
|
||||
{
|
||||
this.state.users?.map((user, index) => <Option key={index} value={user.name}>{user.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
<PaginateSelect
|
||||
virtual
|
||||
style={{width: "100%"}}
|
||||
value={this.state.order.user}
|
||||
disabled={isViewMode}
|
||||
allowClear
|
||||
fetchPage={UserBackend.getUsers}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.organizationName, page, pageSize, field, searchText];
|
||||
}}
|
||||
reloadKey={this.state.organizationName}
|
||||
optionMapper={(user) => Setting.getOption(user.name, user.name)}
|
||||
filterOption={false}
|
||||
onChange={(value) => {
|
||||
this.updateOrderField("user", value || "");
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
|
||||
@@ -236,6 +236,13 @@ class OrderListPage extends BaseListPage {
|
||||
width: "120px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("state"),
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Tooltip title={record.message || ""}>
|
||||
<span>{text}</span>
|
||||
</Tooltip>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Action"),
|
||||
@@ -248,7 +255,7 @@ class OrderListPage extends BaseListPage {
|
||||
return (
|
||||
<div style={{display: "flex", flexWrap: "wrap", gap: "8px"}}>
|
||||
<Button onClick={() => this.props.history.push(`/orders/${record.owner}/${record.name}/pay`)}>
|
||||
{record.state === "Created" ? i18next.t("order:Pay") : i18next.t("general:Detail")}
|
||||
{(record.state === "Created" || record.state === "Failed") ? i18next.t("order:Pay") : i18next.t("general:Detail")}
|
||||
</Button>
|
||||
<Button danger onClick={() => this.cancelOrder(record)} disabled={record.state !== "Created" || !isAdmin}>
|
||||
{i18next.t("general:Cancel")}
|
||||
|
||||
@@ -272,7 +272,7 @@ class OrderPayPage extends React.Component {
|
||||
const updateTimeMap = {
|
||||
Paid: i18next.t("order:Payment time"),
|
||||
Canceled: i18next.t("order:Cancel time"),
|
||||
PaymentFailed: i18next.t("order:Payment failed time"),
|
||||
Failed: i18next.t("order:Payment failed time"),
|
||||
Timeout: i18next.t("order:Timeout time"),
|
||||
};
|
||||
const updateTimeLabel = updateTimeMap[state] || i18next.t("general:Updated time");
|
||||
|
||||
@@ -122,7 +122,7 @@ class PaymentResultPage extends React.Component {
|
||||
payment: payment,
|
||||
});
|
||||
if (payment.state === "Created") {
|
||||
if (["PayPal", "Stripe", "AirWallex", "Alipay", "WeChat Pay", "Balance"].includes(payment.type)) {
|
||||
if (["PayPal", "Stripe", "AirWallex", "Alipay", "WeChat Pay", "Balance", "Dummy"].includes(payment.type)) {
|
||||
this.setState({
|
||||
timeout: setTimeout(async() => {
|
||||
await PaymentBackend.notifyPayment(this.state.owner, this.state.paymentName);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, Row, Select, Switch} from "antd";
|
||||
import PaginateSelect from "./common/PaginateSelect";
|
||||
import * as PermissionBackend from "./backend/PermissionBackend";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import * as UserBackend from "./backend/UserBackend";
|
||||
@@ -68,9 +69,6 @@ class PermissionEditPage extends React.Component {
|
||||
permission: permission,
|
||||
});
|
||||
|
||||
this.getUsers(permission.owner);
|
||||
this.getGroups(permission.owner);
|
||||
this.getRoles(permission.owner);
|
||||
this.getModels(permission.owner);
|
||||
this.getResources(permission.owner);
|
||||
this.getModel(permission.model);
|
||||
@@ -86,48 +84,6 @@ class PermissionEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getUsers(organizationName) {
|
||||
UserBackend.getUsers(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getGroups(organizationName) {
|
||||
GroupBackend.getGroups(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
groups: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getRoles(organizationName) {
|
||||
RoleBackend.getRoles(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
roles: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getModels(organizationName) {
|
||||
ModelBackend.getModels(organizationName)
|
||||
.then((res) => {
|
||||
@@ -211,9 +167,6 @@ class PermissionEditPage extends React.Component {
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} disabled={!Setting.isAdminUser(this.props.account)} value={this.state.permission.owner} onChange={(owner => {
|
||||
this.updatePermissionField("owner", owner);
|
||||
this.getUsers(owner);
|
||||
this.getGroups(owner);
|
||||
this.getRoles(owner);
|
||||
this.getModels(owner);
|
||||
this.getResources(owner);
|
||||
})}
|
||||
@@ -268,12 +221,35 @@ class PermissionEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} mode="multiple" style={{width: "100%"}} value={this.state.permission.users}
|
||||
<PaginateSelect
|
||||
virtual
|
||||
mode="multiple"
|
||||
style={{width: "100%"}}
|
||||
value={this.state.permission.users}
|
||||
allowClear
|
||||
fetchPage={async(...args) => {
|
||||
const res = await UserBackend.getUsers(...args);
|
||||
if (res.status !== "ok") {
|
||||
return res;
|
||||
}
|
||||
const data = res.data.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`));
|
||||
if (args?.[1] === 1 && Array.isArray(res?.data)) {
|
||||
res.data = [
|
||||
Setting.getOption(i18next.t("general:All"), "*"),
|
||||
...data,
|
||||
];
|
||||
} else {
|
||||
res.data = data;
|
||||
}
|
||||
return res;
|
||||
}}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.permission.owner, page, pageSize, field, searchText];
|
||||
}}
|
||||
reloadKey={this.state.permission?.owner}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updatePermissionField("users", value);})}
|
||||
options={[
|
||||
Setting.getOption(i18next.t("general:All"), "*"),
|
||||
...this.state.users.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`)),
|
||||
]}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
@@ -282,12 +258,35 @@ class PermissionEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("role:Sub groups"), i18next.t("role:Sub groups - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} mode="multiple" style={{width: "100%"}} value={this.state.permission.groups}
|
||||
<PaginateSelect
|
||||
virtual
|
||||
mode="multiple"
|
||||
style={{width: "100%"}}
|
||||
value={this.state.permission.groups}
|
||||
allowClear
|
||||
fetchPage={async(...args) => {
|
||||
const res = await GroupBackend.getGroups(...args);
|
||||
if (res.status !== "ok") {
|
||||
return res;
|
||||
}
|
||||
const data = res.data.map((group) => Setting.getOption(`${group.owner}/${group.name}`, `${group.owner}/${group.name}`));
|
||||
if (args?.[2] === 1 && Array.isArray(res?.data)) {
|
||||
res.data = [
|
||||
Setting.getOption(i18next.t("general:All"), "*"),
|
||||
...data,
|
||||
];
|
||||
} else {
|
||||
res.data = data;
|
||||
}
|
||||
return res;
|
||||
}}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.permission.owner, false, page, pageSize, field, searchText, "", ""];
|
||||
}}
|
||||
reloadKey={this.state.permission?.owner}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updatePermissionField("groups", value);})}
|
||||
options={[
|
||||
Setting.getOption(i18next.t("general:All"), "*"),
|
||||
...this.state.groups.map((group) => Setting.getOption(`${group.owner}/${group.name}`, `${group.owner}/${group.name}`)),
|
||||
]}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
@@ -296,12 +295,37 @@ class PermissionEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select disabled={!this.hasRoleDefinition(this.state.model)} placeholder={this.hasRoleDefinition(this.state.model) ? "" : "This field is disabled because the model is empty or it doesn't support RBAC (in another word, doesn't contain [role_definition])"} virtual={false} mode="multiple" style={{width: "100%"}} value={this.state.permission.roles}
|
||||
<PaginateSelect
|
||||
virtual
|
||||
mode="multiple"
|
||||
style={{width: "100%"}}
|
||||
value={this.state.permission.roles}
|
||||
disabled={!this.hasRoleDefinition(this.state.model)}
|
||||
allowClear
|
||||
fetchPage={async(...args) => {
|
||||
const res = await RoleBackend.getRoles(...args);
|
||||
if (res.status !== "ok") {
|
||||
return res;
|
||||
}
|
||||
const data = res.data.map((role) => Setting.getOption(`${role.owner}/${role.name}`, `${role.owner}/${role.name}`));
|
||||
if (args?.[1] === 1 && Array.isArray(res?.data)) {
|
||||
// res.data = [{owner: i18next.t("organization:All"), name: "*"}, ...res.data];
|
||||
res.data = [
|
||||
Setting.getOption(i18next.t("general:All"), "*"),
|
||||
...data,
|
||||
];
|
||||
} else {
|
||||
res.data = data;
|
||||
}
|
||||
return res;
|
||||
}}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.permission.owner, page, pageSize, field, searchText, "", ""];
|
||||
}}
|
||||
reloadKey={this.state.permission?.owner}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updatePermissionField("roles", value);})}
|
||||
options={[
|
||||
Setting.getOption(i18next.t("general:All"), "*"),
|
||||
...this.state.roles.filter(roles => (roles.owner !== this.state.roles.owner || roles.name !== this.state.roles.name)).map((permission) => Setting.getOption(`${permission.owner}/${permission.name}`, `${permission.owner}/${permission.name}`)),
|
||||
]}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, InputNumber, Row, Select, Switch} from "antd";
|
||||
import PaginateSelect from "./common/PaginateSelect";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import * as RoleBackend from "./backend/RoleBackend";
|
||||
import * as PlanBackend from "./backend/PlanBackend";
|
||||
import * as UserBackend from "./backend/UserBackend";
|
||||
import * as ProviderBackend from "./backend/ProviderBackend";
|
||||
import * as Setting from "./Setting";
|
||||
import i18next from "i18next";
|
||||
@@ -57,40 +57,10 @@ class PlanEditPage extends React.Component {
|
||||
plan: res.data,
|
||||
});
|
||||
|
||||
this.getUsers(this.state.organizationName);
|
||||
this.getRoles(this.state.organizationName);
|
||||
this.getPaymentProviders(this.state.organizationName);
|
||||
});
|
||||
}
|
||||
|
||||
getRoles(organizationName) {
|
||||
RoleBackend.getRoles(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
roles: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getUsers(organizationName) {
|
||||
UserBackend.getUsers(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getPaymentProviders(organizationName) {
|
||||
ProviderBackend.getProviders(organizationName)
|
||||
.then((res) => {
|
||||
@@ -151,8 +121,6 @@ class PlanEditPage extends React.Component {
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.plan.owner} disabled={isViewMode} onChange={(owner => {
|
||||
this.updatePlanField("owner", owner);
|
||||
this.getUsers(owner);
|
||||
this.getRoles(owner);
|
||||
this.getPaymentProviders(owner);
|
||||
})}
|
||||
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
|
||||
@@ -184,9 +152,22 @@ class PlanEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:Role"), i18next.t("general:Role - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.plan.role} disabled={isViewMode} onChange={(value => {this.updatePlanField("role", value);})}
|
||||
options={this.state.roles.map((role) => Setting.getOption(role.name, role.name))
|
||||
} />
|
||||
<PaginateSelect
|
||||
virtual
|
||||
style={{width: "100%"}}
|
||||
value={this.state.plan.role}
|
||||
disabled={isViewMode}
|
||||
allowClear
|
||||
fetchPage={RoleBackend.getRoles}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.plan.owner, page, pageSize, field, searchText, "", ""];
|
||||
}}
|
||||
reloadKey={this.state.plan.owner}
|
||||
optionMapper={(role) => Setting.getOption(role.name, role.name)}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updatePlanField("role", value || "");})}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import React from "react";
|
||||
import {Button, Descriptions, Divider, InputNumber, Radio, Space, Spin, Typography} from "antd";
|
||||
import moment from "moment";
|
||||
import i18next from "i18next";
|
||||
import * as ProductBackend from "./backend/ProductBackend";
|
||||
import * as PlanBackend from "./backend/PlanBackend";
|
||||
@@ -193,7 +194,13 @@ class ProductBuyPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const existingItemIndex = cart.findIndex(item => item.name === product.name && item.price === actualPrice && (item.pricingName || "") === pricingName && (item.planName || "") === planName);
|
||||
const cartPrice = product.isRecharge ? actualPrice : null;
|
||||
const existingItemIndex = cart.findIndex(item =>
|
||||
item.name === product.name &&
|
||||
(product.isRecharge ? item.price === actualPrice : true) &&
|
||||
(item.pricingName || "") === pricingName &&
|
||||
(item.planName || "") === planName
|
||||
);
|
||||
const quantityToAdd = this.state.buyQuantity;
|
||||
|
||||
if (existingItemIndex !== -1) {
|
||||
@@ -201,7 +208,8 @@ class ProductBuyPage extends React.Component {
|
||||
} else {
|
||||
const newProductInfo = {
|
||||
name: product.name,
|
||||
price: actualPrice,
|
||||
createdTime: moment().format(),
|
||||
price: cartPrice,
|
||||
currency: product.currency,
|
||||
pricingName: pricingName,
|
||||
planName: planName,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Row, Tag, Typography} from "antd";
|
||||
import moment from "moment";
|
||||
import * as Setting from "./Setting";
|
||||
import * as ProductBackend from "./backend/ProductBackend";
|
||||
import * as UserBackend from "./backend/UserBackend";
|
||||
@@ -22,8 +23,6 @@ import {FloatingCartButton, QuantityStepper} from "./common/product/CartControls
|
||||
|
||||
const {Text, Title} = Typography;
|
||||
|
||||
const MAX_DISPLAYED_RECHARGE_OPTIONS = 3;
|
||||
|
||||
class ProductStorePage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -128,7 +127,13 @@ class ProductStorePage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const existingItemIndex = cart.findIndex(item => item.name === product.name && item.price === product.price);
|
||||
if (product.isRecharge) {
|
||||
Setting.showMessage("error", i18next.t("product:Recharge products need to go to the product detail page to set custom amount"));
|
||||
this.setState(prevState => ({addingToCartProducts: prevState.addingToCartProducts.filter(name => name !== product.name)}));
|
||||
return;
|
||||
}
|
||||
|
||||
const existingItemIndex = cart.findIndex(item => item.name === product.name);
|
||||
const quantityToAdd = this.state.productQuantities[product.name] || 1;
|
||||
|
||||
if (existingItemIndex !== -1) {
|
||||
@@ -136,7 +141,7 @@ class ProductStorePage extends React.Component {
|
||||
} else {
|
||||
const newCartProductInfo = {
|
||||
name: product.name,
|
||||
price: product.price,
|
||||
createdTime: moment().format(),
|
||||
currency: product.currency,
|
||||
pricingName: "",
|
||||
planName: "",
|
||||
@@ -275,17 +280,15 @@ class ProductStorePage extends React.Component {
|
||||
<Text type="secondary" style={{fontSize: "13px", display: "block", marginBottom: 4}}>
|
||||
{i18next.t("product:Recharge options")}:
|
||||
</Text>
|
||||
<div style={{display: "flex", flexWrap: "wrap", gap: "4px"}}>
|
||||
{product.rechargeOptions.slice(0, MAX_DISPLAYED_RECHARGE_OPTIONS).map((amount, index) => (
|
||||
<Tag key={index} color="blue" style={{fontSize: "14px", fontWeight: 600, margin: 0}}>
|
||||
<div style={{display: "flex", flexWrap: "wrap", gap: "4px", alignItems: "center"}}>
|
||||
{product.rechargeOptions.map((amount, index) => (
|
||||
<Tag key={amount} color="blue" style={{fontSize: "14px", fontWeight: 600, margin: 0}}>
|
||||
{Setting.getCurrencySymbol(product.currency)}{amount}
|
||||
</Tag>
|
||||
))}
|
||||
{product.rechargeOptions.length > MAX_DISPLAYED_RECHARGE_OPTIONS && (
|
||||
<Tag color="blue" style={{fontSize: "14px", fontWeight: 600, margin: 0}}>
|
||||
+{product.rechargeOptions.length - MAX_DISPLAYED_RECHARGE_OPTIONS}
|
||||
</Tag>
|
||||
)}
|
||||
<Text type="secondary" style={{fontSize: "13px", marginLeft: 8}}>
|
||||
{Setting.getCurrencyWithFlag(product.currency)}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -294,13 +297,23 @@ class ProductStorePage extends React.Component {
|
||||
<Text strong style={{fontSize: "16px", color: "#1890ff"}}>
|
||||
{i18next.t("product:Custom amount available")}
|
||||
</Text>
|
||||
{(!product.rechargeOptions || product.rechargeOptions.length === 0) && (
|
||||
<Text type="secondary" style={{fontSize: "13px", marginLeft: 8}}>
|
||||
{Setting.getCurrencyWithFlag(product.currency)}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{(!product.rechargeOptions || product.rechargeOptions.length === 0) && product.disableCustomRecharge === true && (
|
||||
<div style={{marginBottom: 8}}>
|
||||
<Text type="secondary" style={{fontSize: "13px", display: "block", marginBottom: 4}}>
|
||||
{i18next.t("product:No recharge options available")}
|
||||
</Text>
|
||||
<Text type="secondary" style={{fontSize: "13px"}}>
|
||||
{Setting.getCurrencyWithFlag(product.currency)}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<Text type="secondary" style={{fontSize: "13px"}}>
|
||||
{Setting.getCurrencyWithFlag(product.currency)}
|
||||
</Text>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
|
||||
@@ -698,7 +698,7 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("type", "Default");
|
||||
this.updateProviderField("host", "smtp.example.com");
|
||||
this.updateProviderField("port", 465);
|
||||
this.updateProviderField("disableSsl", false);
|
||||
this.updateProviderField("sslMode", "Auto");
|
||||
this.updateProviderField("title", "Casdoor Verification Code");
|
||||
this.updateProviderField("content", Setting.getDefaultHtmlEmailContent());
|
||||
this.updateProviderField("metadata", Setting.getDefaultInvitationHtmlEmailContent());
|
||||
@@ -823,6 +823,19 @@ class ProviderEditPage extends React.Component {
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Scope"), i18next.t("provider:Scope - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.provider.scopes} onChange={value => {
|
||||
this.updateProviderField("scopes", value);
|
||||
}}>
|
||||
<Option key="snsapi_userinfo" value="snsapi_userinfo">snsapi_userinfo</Option>
|
||||
<Option key="snsapi_privateinfo" value="snsapi_privateinfo">snsapi_privateinfo</Option>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Use id as name"), i18next.t("provider:Use id as name - Tooltip"))} :
|
||||
@@ -1281,12 +1294,16 @@ class ProviderEditPage extends React.Component {
|
||||
{["Azure ACS", "SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Disable SSL"), i18next.t("provider:Disable SSL - Tooltip"))} :
|
||||
{Setting.getLabel(i18next.t("provider:SSL mode"), i18next.t("provider:SSL mode - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={1} >
|
||||
<Switch checked={this.state.provider.disableSsl} onChange={checked => {
|
||||
this.updateProviderField("disableSsl", checked);
|
||||
}} />
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "200px"}} value={this.state.provider.sslMode || "Auto"} onChange={value => {
|
||||
this.updateProviderField("sslMode", value);
|
||||
}}>
|
||||
<Option value="Auto">{i18next.t("provider:Auto")}</Option>
|
||||
<Option value="Enable">{i18next.t("provider:Enable")}</Option>
|
||||
<Option value="Disable">{i18next.t("provider:Disable")}</Option>
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
|
||||
@@ -20,6 +20,7 @@ import * as GroupBackend from "./backend/GroupBackend";
|
||||
import * as RoleBackend from "./backend/RoleBackend";
|
||||
import * as Setting from "./Setting";
|
||||
import i18next from "i18next";
|
||||
import PaginateSelect from "./common/PaginateSelect";
|
||||
|
||||
class RoleEditPage extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -30,9 +31,6 @@ class RoleEditPage extends React.Component {
|
||||
roleName: decodeURIComponent(props.match.params.roleName),
|
||||
role: null,
|
||||
organizations: [],
|
||||
users: [],
|
||||
groups: [],
|
||||
roles: [],
|
||||
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
||||
};
|
||||
}
|
||||
@@ -57,10 +55,6 @@ class RoleEditPage extends React.Component {
|
||||
this.setState({
|
||||
role: res.data,
|
||||
});
|
||||
|
||||
this.getUsers(this.state.organizationName);
|
||||
this.getGroups(this.state.organizationName);
|
||||
this.getRoles(this.state.organizationName);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,48 +67,6 @@ class RoleEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getUsers(organizationName) {
|
||||
UserBackend.getUsers(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getGroups(organizationName) {
|
||||
GroupBackend.getGroups(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
groups: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getRoles(organizationName) {
|
||||
RoleBackend.getRoles(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
roles: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
parseRoleField(key, value) {
|
||||
if ([""].includes(key)) {
|
||||
value = Setting.myParseInt(value);
|
||||
@@ -187,9 +139,20 @@ class RoleEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={true} mode="multiple" style={{width: "100%"}} value={this.state.role.users}
|
||||
<PaginateSelect
|
||||
virtual
|
||||
mode="multiple"
|
||||
style={{width: "100%"}}
|
||||
value={this.state.role.users}
|
||||
fetchPage={UserBackend.getUsers}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.role.owner, page, pageSize, field, searchText];
|
||||
}}
|
||||
reloadKey={this.state.role.owner}
|
||||
optionMapper={(user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`)}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updateRoleField("users", value);})}
|
||||
options={this.state.users.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`))}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
@@ -198,9 +161,19 @@ class RoleEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("role:Sub groups"), i18next.t("role:Sub groups - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} mode="multiple" style={{width: "100%"}} value={this.state.role.groups}
|
||||
<PaginateSelect
|
||||
mode="multiple"
|
||||
style={{width: "100%"}}
|
||||
value={this.state.role.groups}
|
||||
fetchPage={GroupBackend.getGroups}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.role.owner, false, page, pageSize, field, searchText, "", ""];
|
||||
}}
|
||||
reloadKey={this.state.role.owner}
|
||||
optionMapper={(group) => Setting.getOption(`${group.owner}/${group.name}`, `${group.owner}/${group.name}`)}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updateRoleField("groups", value);})}
|
||||
options={this.state.groups.map((group) => Setting.getOption(`${group.owner}/${group.name}`, `${group.owner}/${group.name}`))}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
@@ -209,9 +182,25 @@ class RoleEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} mode="multiple" style={{width: "100%"}} value={this.state.role.roles} onChange={(value => {this.updateRoleField("roles", value);})}
|
||||
options={this.state.roles.filter(role => (role.owner !== this.state.role.owner || role.name !== this.state.role.name)).map((role) => Setting.getOption(`${role.owner}/${role.name}`, `${role.owner}/${role.name}`))
|
||||
} />
|
||||
<PaginateSelect
|
||||
mode="multiple"
|
||||
style={{width: "100%"}}
|
||||
value={this.state.role.roles}
|
||||
fetchPage={RoleBackend.getRoles}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.role.owner, page, pageSize, field, searchText, "", ""];
|
||||
}}
|
||||
reloadKey={`${this.state.role.owner}/${this.state.role.name}`}
|
||||
optionMapper={(role) => {
|
||||
if (role.owner === this.state.role.owner && role.name === this.state.role.name) {
|
||||
return null;
|
||||
}
|
||||
return Setting.getOption(`${role.owner}/${role.name}`, `${role.owner}/${role.name}`);
|
||||
}}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updateRoleField("roles", value);})}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
|
||||
@@ -34,6 +34,9 @@ export const ServerUrl = "";
|
||||
|
||||
export const StaticBaseUrl = "https://cdn.casbin.org";
|
||||
|
||||
export const MAX_PAGE_SIZE = 25;
|
||||
export const SEARCH_DEBOUNCE_MS = 300;
|
||||
|
||||
export const Countries = [
|
||||
{label: "English", key: "en", country: "US", alt: "English"},
|
||||
{label: "Español", key: "es", country: "ES", alt: "Español"},
|
||||
@@ -286,11 +289,11 @@ export const OtherProviderInfo = {
|
||||
url: "https://fastspring.com/",
|
||||
},
|
||||
"Lemon Squeezy": {
|
||||
logo: `${StaticBaseUrl}/img/payment_lemonsqueezy.png`,
|
||||
logo: `${StaticBaseUrl}/img/payment_lemonsqueezy.jpg`,
|
||||
url: "https://www.lemonsqueezy.com/",
|
||||
},
|
||||
"Adyen": {
|
||||
logo: `${StaticBaseUrl}/img/payment_adyen.png`,
|
||||
logo: `${StaticBaseUrl}/img/payment_adyen.svg`,
|
||||
url: "https://www.adyen.com/",
|
||||
},
|
||||
},
|
||||
@@ -514,6 +517,7 @@ export const GetTranslatedUserItems = () => {
|
||||
{name: "Balance", label: i18next.t("user:Balance")},
|
||||
{name: "Balance currency", label: i18next.t("organization:Balance currency")},
|
||||
{name: "Balance credit", label: i18next.t("organization:Balance credit")},
|
||||
{name: "Cart", label: i18next.t("general:Cart")},
|
||||
{name: "Transactions", label: i18next.t("general:Transactions")},
|
||||
{name: "Score", label: i18next.t("user:Score")},
|
||||
{name: "Karma", label: i18next.t("user:Karma")},
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import moment from "moment";
|
||||
import React from "react";
|
||||
import {Button, Card, Col, DatePicker, Input, Row, Select} from "antd";
|
||||
import PaginateSelect from "./common/PaginateSelect";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import * as PricingBackend from "./backend/PricingBackend";
|
||||
import * as PlanBackend from "./backend/PlanBackend";
|
||||
@@ -63,7 +64,6 @@ class SubscriptionEditPage extends React.Component {
|
||||
subscription: res.data,
|
||||
});
|
||||
|
||||
this.getUsers(this.state.organizationName);
|
||||
this.getPricings(this.state.organizationName);
|
||||
this.getPlans(this.state.organizationName);
|
||||
});
|
||||
@@ -87,20 +87,6 @@ class SubscriptionEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getUsers(organizationName) {
|
||||
UserBackend.getUsers(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getOrganizations() {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
@@ -147,7 +133,6 @@ class SubscriptionEditPage extends React.Component {
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.subscription.owner} disabled={isViewMode} onChange={(owner => {
|
||||
this.updateSubscriptionField("owner", owner);
|
||||
this.getUsers(owner);
|
||||
this.getPlans(owner);
|
||||
})}
|
||||
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
|
||||
@@ -217,10 +202,21 @@ class SubscriptionEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:User"), i18next.t("general:User - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select style={{width: "100%"}} value={this.state.subscription.user}
|
||||
<PaginateSelect
|
||||
virtual
|
||||
style={{width: "100%"}}
|
||||
value={this.state.subscription.user}
|
||||
disabled={isViewMode}
|
||||
onChange={(value => {this.updateSubscriptionField("user", value);})}
|
||||
options={this.state.users.map((user) => Setting.getOption(user.name, user.name))}
|
||||
allowClear
|
||||
fetchPage={UserBackend.getUsers}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.subscription.owner, page, pageSize, field, searchText];
|
||||
}}
|
||||
reloadKey={this.state.subscription?.owner}
|
||||
optionMapper={(user) => Setting.getOption(user.name, user.name)}
|
||||
filterOption={false}
|
||||
onChange={(value => {this.updateSubscriptionField("user", value || "");})}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -710,6 +710,79 @@ class SyncerEditPage extends React.Component {
|
||||
"values": [],
|
||||
},
|
||||
];
|
||||
case "AWS IAM":
|
||||
return [
|
||||
{
|
||||
"name": "UserId",
|
||||
"type": "string",
|
||||
"casdoorName": "Id",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "UserName",
|
||||
"type": "string",
|
||||
"casdoorName": "Name",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "UserName",
|
||||
"type": "string",
|
||||
"casdoorName": "DisplayName",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "Tags.Email",
|
||||
"type": "string",
|
||||
"casdoorName": "Email",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "Tags.Phone",
|
||||
"type": "string",
|
||||
"casdoorName": "Phone",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "Tags.FirstName",
|
||||
"type": "string",
|
||||
"casdoorName": "FirstName",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "Tags.LastName",
|
||||
"type": "string",
|
||||
"casdoorName": "LastName",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "Tags.Title",
|
||||
"type": "string",
|
||||
"casdoorName": "Title",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "Tags.Department",
|
||||
"type": "string",
|
||||
"casdoorName": "Affiliation",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"name": "CreateDate",
|
||||
"type": "string",
|
||||
"casdoorName": "CreatedTime",
|
||||
"isHashed": true,
|
||||
"values": [],
|
||||
},
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
@@ -766,14 +839,14 @@ class SyncerEditPage extends React.Component {
|
||||
});
|
||||
})}>
|
||||
{
|
||||
["Database", "Keycloak", "WeCom", "Azure AD", "Active Directory", "Google Workspace", "DingTalk", "Lark", "Okta", "SCIM"]
|
||||
["Database", "Keycloak", "WeCom", "Azure AD", "Active Directory", "Google Workspace", "DingTalk", "Lark", "Okta", "SCIM", "AWS IAM"]
|
||||
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Active Directory" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" ? null : (
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Active Directory" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" || this.state.syncer.type === "AWS IAM" ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("syncer:Database type"), i18next.t("syncer:Database type - Tooltip"))} :
|
||||
@@ -828,7 +901,7 @@ class SyncerEditPage extends React.Component {
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(this.state.syncer.type === "Azure AD" ? i18next.t("provider:Tenant ID") : this.state.syncer.type === "Google Workspace" ? i18next.t("syncer:Admin Email") : this.state.syncer.type === "Active Directory" ? i18next.t("ldap:Server") : this.state.syncer.type === "SCIM" ? i18next.t("syncer:SCIM Server URL") : i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
|
||||
{Setting.getLabel(this.state.syncer.type === "Azure AD" ? i18next.t("provider:Tenant ID") : this.state.syncer.type === "Google Workspace" ? i18next.t("syncer:Admin Email") : this.state.syncer.type === "Active Directory" ? i18next.t("ldap:Server") : this.state.syncer.type === "SCIM" ? i18next.t("syncer:SCIM Server URL") : this.state.syncer.type === "AWS IAM" ? i18next.t("syncer:AWS Region") : i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input prefix={<LinkOutlined />} value={this.state.syncer.host} onChange={e => {
|
||||
@@ -839,7 +912,7 @@ class SyncerEditPage extends React.Component {
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" ? null : (
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" || this.state.syncer.type === "AWS IAM" ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(this.state.syncer.type === "Active Directory" ? i18next.t("provider:LDAP port") : i18next.t("provider:Port"), i18next.t("provider:Port - Tooltip"))} :
|
||||
@@ -863,7 +936,8 @@ class SyncerEditPage extends React.Component {
|
||||
this.state.syncer.type === "Azure AD" ? i18next.t("provider:Client ID") :
|
||||
this.state.syncer.type === "Active Directory" ? i18next.t("syncer:Bind DN") :
|
||||
this.state.syncer.type === "SCIM" ? i18next.t("syncer:Username (optional)") :
|
||||
i18next.t("general:User"),
|
||||
this.state.syncer.type === "AWS IAM" ? i18next.t("syncer:AWS Access Key ID") :
|
||||
i18next.t("general:User"),
|
||||
i18next.t("general:User - Tooltip")
|
||||
)} :
|
||||
</Col>
|
||||
@@ -884,7 +958,8 @@ class SyncerEditPage extends React.Component {
|
||||
this.state.syncer.type === "Azure AD" ? i18next.t("provider:Client secret") :
|
||||
this.state.syncer.type === "Google Workspace" ? i18next.t("syncer:Service account key") :
|
||||
this.state.syncer.type === "SCIM" ? i18next.t("syncer:API Token / Password") :
|
||||
i18next.t("general:Password"),
|
||||
this.state.syncer.type === "AWS IAM" ? i18next.t("syncer:AWS Secret Access Key") :
|
||||
i18next.t("general:Password"),
|
||||
i18next.t("general:Password - Tooltip")
|
||||
)} :
|
||||
</Col>
|
||||
@@ -903,7 +978,7 @@ class SyncerEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" ? null : (
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" || this.state.syncer.type === "AWS IAM" ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(this.state.syncer.type === "Active Directory" ? i18next.t("ldap:Base DN") : i18next.t("syncer:Database"), i18next.t("syncer:Database - Tooltip"))} :
|
||||
@@ -999,7 +1074,7 @@ class SyncerEditPage extends React.Component {
|
||||
) : null
|
||||
}
|
||||
{
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" ? null : (
|
||||
this.state.syncer.type === "WeCom" || this.state.syncer.type === "Azure AD" || this.state.syncer.type === "Google Workspace" || this.state.syncer.type === "DingTalk" || this.state.syncer.type === "Lark" || this.state.syncer.type === "Okta" || this.state.syncer.type === "SCIM" || this.state.syncer.type === "AWS IAM" ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("syncer:Table"), i18next.t("syncer:Table - Tooltip"))} :
|
||||
|
||||
@@ -19,6 +19,7 @@ import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||
import * as UserBackend from "./backend/UserBackend";
|
||||
import * as Setting from "./Setting";
|
||||
import {Button, Card, Col, Input, InputNumber, Row, Select} from "antd";
|
||||
import PaginateSelect from "./common/PaginateSelect";
|
||||
import i18next from "i18next";
|
||||
|
||||
const {Option} = Select;
|
||||
@@ -43,7 +44,6 @@ class TransactionEditPage extends React.Component {
|
||||
if (this.state.mode === "recharge") {
|
||||
this.getOrganizations();
|
||||
this.getApplications(this.state.organizationName);
|
||||
this.getUsers(this.state.organizationName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,19 +103,6 @@ class TransactionEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getUsers(organizationName) {
|
||||
const targetOrganizationName = organizationName || this.state.organizationName;
|
||||
UserBackend.getUsers(targetOrganizationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
users: res.data || [],
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
submitTransactionEdit(exitAfterSave) {
|
||||
if (this.state.transaction === null) {
|
||||
return;
|
||||
@@ -205,7 +192,6 @@ class TransactionEditPage extends React.Component {
|
||||
this.updateTransactionField("owner", value);
|
||||
this.updateTransactionField("application", "");
|
||||
this.getApplications(value);
|
||||
this.getUsers(value);
|
||||
}}>
|
||||
{
|
||||
this.state.organizations.map((org, index) => <Option key={index} value={org.name}>{org.name}</Option>)
|
||||
@@ -340,17 +326,24 @@ class TransactionEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
{isRechargeMode ? (
|
||||
<Select virtual={false} style={{width: "100%"}}
|
||||
<PaginateSelect
|
||||
virtual
|
||||
style={{width: "100%"}}
|
||||
value={this.state.transaction.user}
|
||||
disabled={this.state.transaction.tag === "Organization"}
|
||||
allowClear
|
||||
fetchPage={UserBackend.getUsers}
|
||||
buildFetchArgs={({page, pageSize, searchText}) => {
|
||||
const field = searchText ? "name" : "";
|
||||
return [this.state.transaction?.organization || this.state.organizationName, page, pageSize, field, searchText];
|
||||
}}
|
||||
reloadKey={this.state.transaction?.organization || this.state.organizationName}
|
||||
optionMapper={(user) => Setting.getOption(user.name, user.name)}
|
||||
filterOption={false}
|
||||
onChange={(value) => {
|
||||
this.updateTransactionField("user", value || "");
|
||||
}}>
|
||||
{
|
||||
this.state.users.map((user, index) => <Option key={index} value={user.name}>{user.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Input disabled={true} value={this.state.transaction.user} onChange={e => {
|
||||
}} />
|
||||
|
||||
@@ -48,6 +48,7 @@ import FaceIdTable from "./table/FaceIdTable";
|
||||
import MfaAccountTable from "./table/MfaAccountTable";
|
||||
import MfaTable from "./table/MfaTable";
|
||||
import TransactionTable from "./table/TransactionTable";
|
||||
import CartTable from "./table/CartTable";
|
||||
import * as TransactionBackend from "./backend/TransactionBackend";
|
||||
import {Content, Header} from "antd/es/layout/layout";
|
||||
import Sider from "antd/es/layout/Sider";
|
||||
@@ -861,6 +862,17 @@ class UserEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
} else if (accountItem.name === "Cart") {
|
||||
return (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Cart"), i18next.t("general:Cart"))} :
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<CartTable cart={this.state.user.cart} />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
} else if (accountItem.name === "Transactions") {
|
||||
return (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
|
||||
@@ -439,6 +439,10 @@ export function getAuthUrl(application, provider, method, code) {
|
||||
const redirectOrigin = application.forcedRedirectOrigin ? application.forcedRedirectOrigin : window.location.origin;
|
||||
let redirectUri = `${redirectOrigin}/callback`;
|
||||
let scope = authInfo[type].scope;
|
||||
// Allow provider.scopes to override default scope if specified
|
||||
if (provider.scopes && provider.scopes.trim() !== "") {
|
||||
scope = provider.scopes;
|
||||
}
|
||||
const isShortState = (provider.type === "WeChat" && navigator.userAgent.includes("MicroMessenger")) || (provider.type === "Twitter");
|
||||
let applicationName = application.name;
|
||||
if (application?.isShared) {
|
||||
|
||||
277
web/src/common/PaginateSelect.js
Normal file
277
web/src/common/PaginateSelect.js
Normal file
@@ -0,0 +1,277 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Select, Spin} from "antd";
|
||||
import * as Setting from "../Setting";
|
||||
|
||||
const SCROLL_BOTTOM_OFFSET = 20;
|
||||
|
||||
const defaultOptionMapper = (item) => {
|
||||
if (item === null) {
|
||||
return null;
|
||||
}
|
||||
if (typeof item === "string") {
|
||||
return Setting.getOption(item, item);
|
||||
}
|
||||
const value = item.value ?? item.name ?? item.id ?? item.key;
|
||||
const label = item.label ?? item.displayName ?? value;
|
||||
if (value === undefined) {
|
||||
return null;
|
||||
}
|
||||
return Setting.getOption(label, value);
|
||||
};
|
||||
|
||||
function PaginateSelect(props) {
|
||||
const {
|
||||
fetchPage,
|
||||
buildFetchArgs,
|
||||
optionMapper = defaultOptionMapper,
|
||||
pageSize = Setting.MAX_PAGE_SIZE,
|
||||
debounceMs = Setting.SEARCH_DEBOUNCE_MS,
|
||||
onError,
|
||||
onSearch: onSearchProp,
|
||||
onPopupScroll: onPopupScrollProp,
|
||||
showSearch = true,
|
||||
filterOption = false,
|
||||
notFoundContent,
|
||||
loading: selectLoading,
|
||||
dropdownMatchSelectWidth = false,
|
||||
virtual = false,
|
||||
reloadKey,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
const [options, setOptions] = React.useState([]);
|
||||
const [hasMore, setHasMore] = React.useState(true);
|
||||
const [loading, setLoading] = React.useState(false);
|
||||
|
||||
const debounceRef = React.useRef(null);
|
||||
const latestSearchRef = React.useRef("");
|
||||
const loadingRef = React.useRef(false);
|
||||
const requestIdRef = React.useRef(0);
|
||||
const pageRef = React.useRef(0);
|
||||
const fetchPageRef = React.useRef(fetchPage);
|
||||
const buildFetchArgsRef = React.useRef(buildFetchArgs);
|
||||
const optionMapperRef = React.useRef(optionMapper ?? defaultOptionMapper);
|
||||
|
||||
React.useEffect(() => {
|
||||
fetchPageRef.current = fetchPage;
|
||||
}, [fetchPage]);
|
||||
|
||||
React.useEffect(() => {
|
||||
buildFetchArgsRef.current = buildFetchArgs;
|
||||
}, [buildFetchArgs]);
|
||||
|
||||
React.useEffect(() => {
|
||||
optionMapperRef.current = optionMapper ?? defaultOptionMapper;
|
||||
}, [optionMapper]);
|
||||
|
||||
const handleError = React.useCallback((error) => {
|
||||
if (onError) {
|
||||
onError(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Setting?.showMessage) {
|
||||
Setting.showMessage("error", error?.message ?? String(error));
|
||||
}
|
||||
}, [onError]);
|
||||
|
||||
const extractItems = React.useCallback((response) => {
|
||||
if (Array.isArray(response)) {
|
||||
return response;
|
||||
}
|
||||
if (Array.isArray(response?.items)) {
|
||||
return response.items;
|
||||
}
|
||||
if (Array.isArray(response?.data)) {
|
||||
return response.data;
|
||||
}
|
||||
if (Array.isArray(response?.list)) {
|
||||
return response.list;
|
||||
}
|
||||
return [];
|
||||
}, []);
|
||||
|
||||
const mergeOptions = React.useCallback((prev, next, reset) => {
|
||||
if (reset) {
|
||||
return next;
|
||||
}
|
||||
|
||||
const merged = [...prev];
|
||||
const indexByValue = new Map();
|
||||
merged.forEach((opt, idx) => {
|
||||
if (opt?.value !== undefined) {
|
||||
indexByValue.set(opt.value, idx);
|
||||
}
|
||||
});
|
||||
|
||||
next.forEach((opt) => {
|
||||
if (!opt) {
|
||||
return;
|
||||
}
|
||||
const optionValue = opt.value;
|
||||
if (optionValue === undefined) {
|
||||
merged.push(opt);
|
||||
return;
|
||||
}
|
||||
if (indexByValue.has(optionValue)) {
|
||||
merged[indexByValue.get(optionValue)] = opt;
|
||||
return;
|
||||
}
|
||||
indexByValue.set(optionValue, merged.length);
|
||||
merged.push(opt);
|
||||
});
|
||||
|
||||
return merged;
|
||||
}, []);
|
||||
|
||||
const loadPage = React.useCallback(async({pageToLoad = 1, reset = false, search = latestSearchRef.current} = {}) => {
|
||||
const fetcher = fetchPageRef.current;
|
||||
if (typeof fetcher !== "function") {
|
||||
return;
|
||||
}
|
||||
if (loadingRef.current && !reset) {
|
||||
return;
|
||||
}
|
||||
if (reset) {
|
||||
loadingRef.current = false;
|
||||
}
|
||||
|
||||
const currentRequestId = requestIdRef.current + 1;
|
||||
requestIdRef.current = currentRequestId;
|
||||
|
||||
loadingRef.current = true;
|
||||
setLoading(true);
|
||||
|
||||
const defaultArgsObject = {
|
||||
page: pageToLoad,
|
||||
pageSize,
|
||||
search,
|
||||
searchText: search,
|
||||
query: search,
|
||||
};
|
||||
|
||||
try {
|
||||
const argsBuilder = buildFetchArgsRef.current;
|
||||
const builtArgs = argsBuilder ? argsBuilder({
|
||||
page: pageToLoad,
|
||||
pageSize,
|
||||
searchText: search,
|
||||
}) : defaultArgsObject;
|
||||
|
||||
const payload = Array.isArray(builtArgs) ?
|
||||
await fetcher(...builtArgs) :
|
||||
await fetcher(builtArgs ?? defaultArgsObject);
|
||||
|
||||
if (currentRequestId !== requestIdRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload?.status && payload.status !== "ok") {
|
||||
handleError(payload?.msg ?? payload?.error ?? "Request failed");
|
||||
setHasMore(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const items = extractItems(payload);
|
||||
const mapper = optionMapperRef.current ?? defaultOptionMapper;
|
||||
const mappedOptions = items.map(mapper).filter(Boolean);
|
||||
setOptions((prev) => mergeOptions(prev, mappedOptions, reset));
|
||||
pageRef.current = pageToLoad;
|
||||
|
||||
const hasMoreFromPayload = typeof payload?.hasMore === "boolean" ? payload.hasMore : null;
|
||||
const hasMoreFromTotal = typeof payload?.total === "number" ? (pageToLoad * pageSize < payload.total) : null;
|
||||
const fallbackHasMore = mappedOptions.length === pageSize;
|
||||
setHasMore(hasMoreFromPayload ?? hasMoreFromTotal ?? fallbackHasMore);
|
||||
} catch (error) {
|
||||
if (currentRequestId === requestIdRef.current) {
|
||||
handleError(error);
|
||||
}
|
||||
} finally {
|
||||
if (currentRequestId === requestIdRef.current) {
|
||||
loadingRef.current = false;
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
}, [pageSize, extractItems, mergeOptions, handleError]);
|
||||
|
||||
const resetAndLoad = React.useCallback((search = "") => {
|
||||
latestSearchRef.current = search;
|
||||
setOptions([]);
|
||||
setHasMore(true);
|
||||
pageRef.current = 0;
|
||||
loadPage({pageToLoad: 1, reset: true, search});
|
||||
}, [loadPage]);
|
||||
|
||||
React.useEffect(() => {
|
||||
resetAndLoad("");
|
||||
return () => {
|
||||
if (debounceRef.current) {
|
||||
clearTimeout(debounceRef.current);
|
||||
}
|
||||
};
|
||||
}, [resetAndLoad, reloadKey]);
|
||||
|
||||
const handleSearch = React.useCallback((value) => {
|
||||
onSearchProp?.(value);
|
||||
if (debounceRef.current) {
|
||||
clearTimeout(debounceRef.current);
|
||||
}
|
||||
|
||||
const triggerSearch = () => resetAndLoad(value || "");
|
||||
|
||||
if (!debounceMs) {
|
||||
triggerSearch();
|
||||
return;
|
||||
}
|
||||
|
||||
debounceRef.current = setTimeout(triggerSearch, debounceMs);
|
||||
}, [debounceMs, onSearchProp, resetAndLoad]);
|
||||
|
||||
const handlePopupScroll = React.useCallback((event) => {
|
||||
onPopupScrollProp?.(event);
|
||||
const target = event?.target;
|
||||
if (!target || loadingRef.current || !hasMore) {
|
||||
return;
|
||||
}
|
||||
|
||||
const reachedBottom = target.scrollTop + target.offsetHeight >= target.scrollHeight - SCROLL_BOTTOM_OFFSET;
|
||||
if (reachedBottom) {
|
||||
const nextPage = pageRef.current + 1;
|
||||
loadPage({pageToLoad: nextPage});
|
||||
}
|
||||
}, [hasMore, loadPage, onPopupScrollProp]);
|
||||
|
||||
const mergedLoading = selectLoading ?? loading;
|
||||
const mergedNotFound = mergedLoading ? <Spin size="small" /> : notFoundContent;
|
||||
|
||||
return (
|
||||
<Select
|
||||
{...restProps}
|
||||
virtual={virtual}
|
||||
showSearch={showSearch}
|
||||
filterOption={filterOption}
|
||||
options={options}
|
||||
loading={mergedLoading}
|
||||
notFoundContent={mergedNotFound}
|
||||
onSearch={showSearch ? handleSearch : undefined}
|
||||
onPopupScroll={handlePopupScroll}
|
||||
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default PaginateSelect;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "Impersonation beenden",
|
||||
"Logout": "Abmeldung",
|
||||
"My Account": "Mein Konto",
|
||||
"Sign Up": "Anmelden"
|
||||
@@ -22,22 +22,22 @@
|
||||
"Add Face ID with Image": "Face ID mit Bild hinzufügen",
|
||||
"Always": "Immer",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Authentication": "Authentifizierung",
|
||||
"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": "Hintergrund-URL mobil",
|
||||
"Background URL Mobile - Tooltip": "URL des Hintergrundbildes für mobile Geräte",
|
||||
"Basic": "Basic",
|
||||
"Basic": "Basis",
|
||||
"Big icon": "Großes Symbol",
|
||||
"Binding providers": "Bindungsanbieter",
|
||||
"CSS style": "CSS-Stil",
|
||||
"Center": "Zentrum",
|
||||
"Code resend timeout": "Code-Neusendungs-Timeout",
|
||||
"Code resend timeout - Tooltip": "Zeitraum (in Sekunden), den Benutzer warten müssen, bevor sie einen weiteren Verifizierungscode anfordern können. Auf 0 setzen, um die globale Standardeinstellung (60 Sekunden) zu verwenden",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Cookie-Ablauf",
|
||||
"Cookie expire - Tooltip": "Cookie-Ablauf - Hinweis",
|
||||
"Copy SAML metadata URL": "SAML-Metadaten-URL kopieren",
|
||||
"Copy prompt page URL": "URL der Prompt-Seite kopieren",
|
||||
"Copy signin page URL": "Kopieren Sie die URL der Anmeldeseite",
|
||||
@@ -48,8 +48,8 @@
|
||||
"Custom CSS Mobile": "Benutzerdefiniertes CSS mobil",
|
||||
"Custom CSS Mobile - Edit": "Benutzerdefiniertes CSS mobil – Bearbeiten",
|
||||
"Custom CSS Mobile - Tooltip": "CSS-Styling für mobile Geräte",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Disable SAML attributes": "SAML-Attribute deaktivieren",
|
||||
"Disable SAML attributes - Tooltip": "SAML-Attribute deaktivieren - Hinweis",
|
||||
"Disable signin": "Anmeldung deaktivieren",
|
||||
"Disable signin - Tooltip": "Anmeldung für Benutzer deaktivieren",
|
||||
"Dynamic": "Dynamisch",
|
||||
@@ -60,16 +60,17 @@
|
||||
"Enable SAML C14N10 - Tooltip": "C14N10 anstelle von C14N11 in SAML verwenden",
|
||||
"Enable SAML POST binding": "SAML POST-Binding aktivieren",
|
||||
"Enable SAML POST binding - Tooltip": "Das HTTP-POST-Binding verwendet HTML-Formular-Eingabefelder, um SAML-Nachrichten zu senden. Aktivieren Sie diese Option, wenn Ihr SP dies verwendet.",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "SAML-Assertion-Signatur aktivieren",
|
||||
"Enable SAML assertion signature - Tooltip": "SAML-Assertion-Signatur aktivieren - Hinweis",
|
||||
"Enable SAML compression": "Aktivieren Sie SAML-Komprimierung",
|
||||
"Enable SAML compression - Tooltip": "Ob SAML-Antwortnachrichten komprimiert werden sollen, wenn Casdoor als SAML-IdP verwendet wird",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "Exklusive Anmeldung aktivieren",
|
||||
"Enable exclusive signin - Tooltip": "Wenn die exklusive Anmeldung aktiviert ist, kann der Benutzer nicht mehrere aktive Sitzungen haben",
|
||||
"Enable side panel": "Sidepanel aktivieren",
|
||||
"Enable signin session - Tooltip": "Ob Casdoor eine Sitzung aufrechterhält, nachdem man sich von der Anwendung aus bei Casdoor angemeldet hat",
|
||||
"Enable signup": "Registrierung aktivieren",
|
||||
"Enable signup - Tooltip": "Ob Benutzern erlaubt werden soll, ein neues Konto zu registrieren",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Sperrzeit bei fehlgeschlagenem Login",
|
||||
"Failed signin frozen time - Tooltip": "Zeit, für die das Konto nach fehlgeschlagenen Anmeldeversuchen gesperrt wird",
|
||||
"Failed signin limit": "Limit für fehlgeschlagene Logins",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "Erfolgreich ausgeloggt",
|
||||
"MFA remember time": "MFA-Merkezeit",
|
||||
"MFA remember time - Tooltip": "Konfiguriert die Dauer, für die ein Konto nach einer erfolgreichen MFA-Anmeldung als vertrauenswürdig gespeichert wird",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "Menümodus",
|
||||
"Menu mode - Tooltip": "Menümodus - Hinweis",
|
||||
"Multiple Choices": "Mehrfachauswahl",
|
||||
"New Application": "Neue Anwendung",
|
||||
"No verification": "Keine Verifizierung",
|
||||
@@ -111,13 +112,20 @@
|
||||
"Order": "Reihenfolge",
|
||||
"Order - Tooltip": "Je kleiner der Wert, desto höher rangiert er auf der Apps-Seite",
|
||||
"Org choice mode": "Organisationsauswahlmodus",
|
||||
"Org choice mode - Tooltip": "Organisationsauswahlmodus",
|
||||
"Org choice mode - Tooltip": "Organisationsauswahlmodus - Hinweis",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Bitte aktivieren Sie zuerst \"Anmeldesitzung\", bevor Sie \"Automatische Anmeldung\" aktivieren.",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "Bitte geben Sie Ihre Anwendung ein!",
|
||||
"Please input your organization!": "Bitte geben Sie Ihre Organisation ein!",
|
||||
"Please select a HTML file": "Bitte wählen Sie eine HTML-Datei aus",
|
||||
"Pop up": "Pop-up",
|
||||
"Providers": "Providers",
|
||||
"Providers": "Anbieter",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "Zufällig",
|
||||
"Real name": "Echter Name",
|
||||
"Redirect URL": "Weiterleitungs-URL",
|
||||
@@ -127,30 +135,34 @@
|
||||
"Refresh token expire": "Gültigkeitsdauer des Refresh-Tokens",
|
||||
"Refresh token expire - Tooltip": "Angabe der Gültigkeitsdauer des Refresh Tokens",
|
||||
"Reset to Empty": "Auf leer zurücksetzen",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "Rechts",
|
||||
"Rule": "Regel",
|
||||
"SAML hash algorithm": "SAML-Hash-Algorithmus",
|
||||
"SAML hash algorithm - Tooltip": "Hash-Algorithmus für SAML-Signatur",
|
||||
"SAML metadata": "SAML-Metadaten",
|
||||
"SAML metadata - Tooltip": "Die Metadaten des SAML-Protokolls",
|
||||
"SAML metadata - Tooltip": "Die Metadaten des SAML-Protokolls - Hinweis",
|
||||
"SAML reply URL": "SAML Reply-URL",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "Sicherheit",
|
||||
"Select": "Auswählen",
|
||||
"Side panel HTML": "Sidepanel-HTML",
|
||||
"Side panel HTML - Edit": "Sidepanel HTML - Bearbeiten",
|
||||
"Side panel HTML - Tooltip": "Passen Sie den HTML-Code für das Sidepanel der Login-Seite an",
|
||||
"Side panel HTML - Tooltip": "Den HTML-Code für die Seitenleiste der Anmeldeseite anpassen - Hinweis",
|
||||
"Sign Up Error": "Registrierungsfehler",
|
||||
"Signin": "Anmelden",
|
||||
"Signin (Default True)": "Anmelden (Standard: Wahr)",
|
||||
"Signin items": "Anmeldeelemente",
|
||||
"Signin items - Tooltip": "Anmeldeelemente",
|
||||
"Signin methods": "Anmeldemethoden",
|
||||
"Signin methods - Tooltip": "Hinzufügen der zulässigen Anmeldemethoden für Benutzer, standardmäßig sind alle Methoden verfügbar",
|
||||
"Signin methods - Tooltip": "Erlaubte Anmeldemethoden für Benutzer hinzufügen. Standardmäßig sind alle Methoden verfügbar - Hinweis",
|
||||
"Signin session": "Anmeldesession",
|
||||
"Signup items": "Registrierungs Items",
|
||||
"Signup items - Tooltip": "Items, die Benutzer ausfüllen müssen, wenn sie neue Konten registrieren",
|
||||
"Signup items - Tooltip": "Elemente für Benutzer, die beim Registrieren neuer Konten ausgefüllt werden müssen - Hinweis",
|
||||
"Single Choice": "Einfachauswahl",
|
||||
"Small icon": "Kleines Symbol",
|
||||
"Static Value": "Static Value",
|
||||
"String": "String",
|
||||
"Tags - Tooltip": "Nur Benutzer mit einem Tag, das in den Anwendungstags aufgeführt ist, können sich anmelden",
|
||||
"The application does not allow to sign up new account": "Die Anwendung erlaubt es nicht, ein neues Konto zu registrieren",
|
||||
@@ -162,10 +174,12 @@
|
||||
"Token format - Tooltip": "Das Format des Access-Tokens",
|
||||
"Token signing method": "Token-Signaturmethode",
|
||||
"Token signing method - Tooltip": "Signaturmethode des JWT-Tokens muss mit dem Zertifikat übereinstimmen",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "UI-Anpassung",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "E-Mail als NameID verwenden",
|
||||
"Use Email as NameID - Tooltip": "E-Mail als NameID verwenden",
|
||||
"Vertical": "Vertical",
|
||||
"Vertical": "Vertikal",
|
||||
"You are unexpected to see this prompt page": "Sie sind unerwartet auf diese Aufforderungsseite gelangt"
|
||||
},
|
||||
"cert": {
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "Breite"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "Ein normaler Benutzer kann nur die von ihm selbst eingereichte Berechtigung ändern",
|
||||
"AI Assistant": "KI-Assistent",
|
||||
"API key": "API-Schlüssel",
|
||||
"API key - Tooltip": "API-Schlüssel für den Zugriff auf den Dienst",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "Geschäft & Zahlungen",
|
||||
"Cancel": "Abbrechen",
|
||||
"Captcha": "Captcha",
|
||||
"Cart": "Cart",
|
||||
"Cart": "Warenkorb",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "Zertifikat",
|
||||
"Cert - Tooltip": "Das Public-Key-Zertifikat, das vom Client-SDK, das mit dieser Anwendung korrespondiert, verifiziert werden muss",
|
||||
"Certs": "Zertifikate",
|
||||
"Clear": "Clear",
|
||||
"Clear": "Leeren",
|
||||
"Click to Upload": "Klicken Sie zum Hochladen",
|
||||
"Client IP": "Client-IP",
|
||||
"Close": "Schließen",
|
||||
@@ -307,12 +323,12 @@
|
||||
"Delete": "Löschen",
|
||||
"Description": "Beschreibung",
|
||||
"Description - Tooltip": "Detaillierte Beschreibungsinformationen zur Referenz, Casdoor selbst wird es nicht verwenden",
|
||||
"Detail": "详情",
|
||||
"Detail": "Details",
|
||||
"Disable": "Deaktivieren",
|
||||
"Display name": "Anzeigename",
|
||||
"Display name - Tooltip": "Ein benutzerfreundlicher, leicht lesbarer Name, der öffentlich in der Benutzeroberfläche angezeigt wird",
|
||||
"Down": "Nach unten",
|
||||
"Download template": "Download template",
|
||||
"Download template": "Vorlage herunterladen",
|
||||
"Edit": "Bearbeiten",
|
||||
"Email": "E-Mail",
|
||||
"Email - Tooltip": "Gültige E-Mail-Adresse",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "Erfolgreich aktiviert",
|
||||
"Enforcers": "Enforcer",
|
||||
"Failed to add": "Fehler beim hinzufügen",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "Abbrechen fehlgeschlagen",
|
||||
"Failed to connect to server": "Die Verbindung zum Server konnte nicht hergestellt werden",
|
||||
"Failed to copy": "Kopieren fehlgeschlagen",
|
||||
"Failed to delete": "Konnte nicht gelöscht werden",
|
||||
"Failed to enable": "Aktivierung fehlgeschlagen",
|
||||
"Failed to get": "Abruf fehlgeschlagen",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "Laden fehlgeschlagen",
|
||||
"Failed to log out": "Abmelden fehlgeschlagen",
|
||||
"Failed to remove": "Entfernen fehlgeschlagen",
|
||||
"Failed to save": "Konnte nicht gespeichert werden",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "Senden fehlgeschlagen",
|
||||
"Failed to sync": "Synchronisation fehlgeschlagen",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "Verknüpfung aufheben fehlgeschlagen",
|
||||
"Failed to update": "Aktualisieren fehlgeschlagen",
|
||||
"Failed to upload": "Hochladen fehlgeschlagen",
|
||||
"Failed to verify": "Verifizierung fehlgeschlagen",
|
||||
"False": "Falsch",
|
||||
"Favicon": "Favicon",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "Benutzerdefinierte URL für die \"Passwort vergessen\" Seite. Wenn nicht festgelegt, wird die standardmäßige Casdoor \"Passwort vergessen\" Seite verwendet. Wenn sie festgelegt ist, wird der \"Passwort vergessen\" Link auf der Login-Seite zu dieser URL umgeleitet",
|
||||
"Forms": "Formulare",
|
||||
"Found some texts still not translated? Please help us translate at": "Haben Sie noch Texte gefunden, die nicht übersetzt wurden? Bitte helfen Sie uns beim Übersetzen",
|
||||
"Generate": "Generate",
|
||||
"Generate": "Generieren",
|
||||
"Go to enable": "Zum Aktivieren gehen",
|
||||
"Go to writable demo site?": "Gehe zur beschreibbaren Demo-Website?",
|
||||
"Groups": "Gruppen",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "IP-Whitelist",
|
||||
"IP whitelist - Tooltip": "IP-Whitelist",
|
||||
"Identity": "Identität",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "Identitätswechsel",
|
||||
"Invitations": "Einladungen",
|
||||
"Is enabled": "Ist aktiviert",
|
||||
"Is enabled - Tooltip": "Festlegen, ob es verwendet werden kann",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Eindeutige, auf Strings basierende ID",
|
||||
"Name format": "Namensformat",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "Keine Produkte verfügbar",
|
||||
"No sheets found in file": "Keine Tabellenblätter in der Datei gefunden",
|
||||
"No verification method": "Keine Verifizierungsmethode",
|
||||
"Non-LDAP": "Nicht-LDAP",
|
||||
"None": "Keine",
|
||||
"OAuth providers": "OAuth-Provider",
|
||||
"OFF": "AUS",
|
||||
"OK": "OK",
|
||||
"ON": "EIN",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "Es kann nur 1 MFA-Methode erforderlich sein",
|
||||
"Or": "Oder",
|
||||
"Orders": "Bestellungen",
|
||||
"Organization": "Organisation",
|
||||
"Organization - Tooltip": "Ähnlich wie bei Konzepten wie Mietern oder Benutzerpools gehört jeder Benutzer und jede Anwendung einer Organisation an",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "Organisation ist leer",
|
||||
"Organizations": "Organisationen",
|
||||
"Password": "Passwort",
|
||||
"Password - Tooltip": "Stellen Sie sicher, dass das Passwort korrekt ist",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "Telefonnummer",
|
||||
"Phone only": "Nur Telefon",
|
||||
"Phone or Email": "Telefon oder E-Mail",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "Bestellung aufgeben",
|
||||
"Plain": "Klartext",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Abonnementplan",
|
||||
"Plans": "Pläne",
|
||||
"Plans - Tooltip": "Pläne",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "Bitte lösen Sie das Captcha korrekt",
|
||||
"Please input your search": "Bitte geben Sie Ihre Suche ein",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "Bitte wählen Sie zuerst mindestens 1 Benutzer aus",
|
||||
"Preview": "Vorschau",
|
||||
"Preview - Tooltip": "Vorschau der konfigurierten Effekte",
|
||||
"Pricing": "Preisgestaltung",
|
||||
"Pricing - Tooltip": "Preisgestaltung",
|
||||
"Pricings": "Preise",
|
||||
"Product Store": "Product Store",
|
||||
"Product Store": "Produktshop",
|
||||
"Products": "Produkte",
|
||||
"Provider": "Anbieter",
|
||||
"Provider - Tooltip": "Zahlungsprovider, die konfiguriert werden müssen, inkl. PayPal, Alipay, WeChat Pay usw.",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "Der Authentifizierungstyp für SSH-Verbindungen",
|
||||
"Save": "Speichern",
|
||||
"Save & Exit": "Speichern und verlassen",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Suchen",
|
||||
"Send": "Senden",
|
||||
"Session ID": "Session-ID",
|
||||
@@ -496,10 +514,10 @@
|
||||
"Status": "Status",
|
||||
"Subscriptions": "Abonnements",
|
||||
"Successfully added": "Erfolgreich hinzugefügt",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "Erfolgreich abgebrochen",
|
||||
"Successfully copied": "Erfolgreich kopiert",
|
||||
"Successfully deleted": "Erfolgreich gelöscht",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "Erfolgreich ausgeführt",
|
||||
"Successfully removed": "Erfolgreich entfernt",
|
||||
"Successfully saved": "Erfolgreich gespeichert",
|
||||
"Successfully sent": "Erfolgreich gesendet",
|
||||
@@ -514,9 +532,9 @@
|
||||
"Syncers": "Syncer",
|
||||
"System Info": "Systeminformationen",
|
||||
"Tab": "Tab",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "Die Aktionen dürfen nicht leer sein",
|
||||
"The resources cannot be empty": "Die Ressourcen dürfen nicht leer sein",
|
||||
"The users and roles cannot be empty at the same time": "Benutzer und Rollen dürfen nicht gleichzeitig leer sein",
|
||||
"There was a problem signing you in..": "Es gab ein Problem beim Anmelden...",
|
||||
"This is a read-only demo site!": "Dies ist eine schreibgeschützte Demo-Seite!",
|
||||
"Tickets": "Tickets",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "Transaktionen",
|
||||
"True": "Wahr",
|
||||
"Type": "Typ",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "URL-Link",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "Unbekannter Anwendungsname",
|
||||
"Unknown authentication type": "Unbekannter Authentifizierungstyp",
|
||||
"Up": "Oben",
|
||||
"Updated time": "Aktualisierungszeit",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"User": "Nutzer",
|
||||
"User - Tooltip": "Stellen Sie sicher, dass der Benutzername korrekt ist",
|
||||
"User Management": "Benutzerverwaltung",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "Benutzer existiert bereits",
|
||||
"User containers": "Nutzerpools",
|
||||
"User type": "Benutzertyp",
|
||||
"User type - Tooltip": "Tags, denen der Benutzer angehört, standardmäßig auf \"normaler Benutzer\" festgelegt",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "Benutzer",
|
||||
"Users under all organizations": "Benutzer unter allen Organisationen",
|
||||
"Verifications": "Verifizierungen",
|
||||
"View": "View",
|
||||
"View": "Anzeigen",
|
||||
"Webhooks": "Webhooks",
|
||||
"You can only select one physical group": "Sie können nur eine physische Gruppe auswählen",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "Sie müssen zuerst ein Bild auswählen",
|
||||
"empty": "leere",
|
||||
"remove": "entfernen",
|
||||
"{total} in total": "Insgesamt {total}"
|
||||
@@ -626,7 +645,7 @@
|
||||
"login": {
|
||||
"Auto sign in": "Automatische Anmeldung",
|
||||
"Back button": "Zurück-Button",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "Klicken Sie auf die Schaltfläche unten, um sich mit Telegram anzumelden",
|
||||
"Continue with": "Weitermachen mit",
|
||||
"Email or phone": "E-Mail oder Telefon",
|
||||
"Face ID": "Face ID",
|
||||
@@ -649,12 +668,12 @@
|
||||
"Please input your Email!": "Bitte geben Sie Ihre E-Mail ein!",
|
||||
"Please input your LDAP username!": "Bitte geben Sie Ihren LDAP-Benutzernamen ein!",
|
||||
"Please input your Phone!": "Bitte geben Sie Ihre Telefonnummer ein!",
|
||||
"Please input your RADIUS password!": "Please input your RADIUS password!",
|
||||
"Please input your RADIUS username!": "Please input your RADIUS username!",
|
||||
"Please input your RADIUS password!": "Bitte geben Sie Ihr RADIUS-Passwort ein!",
|
||||
"Please input your RADIUS username!": "Bitte geben Sie Ihren RADIUS-Benutzernamen ein!",
|
||||
"Please input your code!": "Bitte geben Sie Ihren Code ein!",
|
||||
"Please input your organization name!": "Bitte geben Sie Ihren Organisationsnamen ein!",
|
||||
"Please input your password!": "Bitte geben Sie Ihr Passwort ein!",
|
||||
"Please input your push notification receiver!": "Please input your push notification receiver!",
|
||||
"Please input your push notification receiver!": "Bitte geben Sie den Empfänger für Push-Benachrichtigungen ein!",
|
||||
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Bitte laden Sie die Webseite über HTTPS, sonst kann auf die Kamera nicht zugegriffen werden.",
|
||||
"Please provide permission to access the camera": "Bitte erteilen Sie die Kamerazugriffsberechtigung.",
|
||||
"Please select an organization": "Bitte wählen Sie eine Organisation aus.",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "Organisation auswählen",
|
||||
"Sign In": "Anmelden",
|
||||
"Sign in with Face ID": "Mit Face ID anmelden",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "Mit Telegram anmelden",
|
||||
"Sign in with WebAuthn": "Melden Sie sich mit WebAuthn an",
|
||||
"Sign in with {type}": "Melden Sie sich mit {type} an",
|
||||
"Signin button": "Anmelde-Button",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "Bitte bestätigen Sie die folgenden Informationen",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "Bitte speichern Sie diesen Wiederherstellungscode. Falls Ihr Gerät keinen Code liefern kann, können Sie MFA mit diesem Code zurücksetzen.",
|
||||
"Protect your account with Multi-factor authentication": "Schützen Sie Ihr Konto mit MFA",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "Empfänger für Push-Benachrichtigungen",
|
||||
"Recovery code": "Wiederherstellungscode",
|
||||
"Remember this account for {hour} hours": "Dieses Konto für {hour} Stunden merken",
|
||||
"Scan the QR code with your Authenticator App": "Scannen Sie den QR-Code mit Ihrer Authenticator-App",
|
||||
@@ -708,17 +727,17 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "Zur Sicherheit Ihres Kontos ist MFA erforderlich.",
|
||||
"Use Authenticator App": "Authenticator-App verwenden",
|
||||
"Use Email": "E-Mail verwenden",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "Push-Benachrichtigung verwenden",
|
||||
"Use Radius": "RADIUS verwenden",
|
||||
"Use SMS": "SMS verwenden",
|
||||
"Use SMS verification code": "SMS-Verifizierungscode verwenden",
|
||||
"Use a recovery code": "Wiederherstellungscode verwenden",
|
||||
"Verify Code": "Code verifizieren",
|
||||
"Verify Password": "Passwort verifizieren",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "Sie haben MFA aktiviert. Klicken Sie auf „Code senden“, um fortzufahren.",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "Sie haben MFA aktiviert. Bitte geben Sie das RADIUS-Passwort ein.",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "Sie haben MFA aktiviert. Bitte geben Sie den TOTP-Code ein.",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "Sie haben MFA aktiviert. Bitte geben Sie den Verifizierungscode aus der Push-Benachrichtigung ein",
|
||||
"Your email is": "Ihre E-Mail ist",
|
||||
"Your phone is": "Ihr Telefon ist",
|
||||
"preferred": "bevorzugt"
|
||||
@@ -732,29 +751,30 @@
|
||||
"New Model": "Neues Modell"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "Stornierungszeit",
|
||||
"Edit Order": "Bestellung bearbeiten",
|
||||
"New Order": "Neue Bestellung",
|
||||
"Order not found": "Bestellung nicht gefunden",
|
||||
"Pay": "Bezahlen",
|
||||
"Payment failed time": "Zeitpunkt des Zahlungsfehlers",
|
||||
"Payment time": "Zahlungszeit",
|
||||
"Price": "Preis",
|
||||
"Return to Order List": "Zur Bestellliste zurückkehren",
|
||||
"Timeout time": "Zeitpunkt des Timeouts",
|
||||
"View Order": "Bestellung anzeigen"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "Konto Items",
|
||||
"Account items - Tooltip": "Elemente auf der persönlichen Einstellungsseite",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Account menu": "Kontomenü",
|
||||
"Account menu - Tooltip": "Kontomenü - Tooltip",
|
||||
"Admin navbar items": "Admin-Navigationsleisten-Elemente",
|
||||
"Admin navbar items - Tooltip": "Admin-Navigationsleisten-Elemente - Tooltip",
|
||||
"All": "All",
|
||||
"Balance credit": "Guthaben (Credits)",
|
||||
"Balance credit - Tooltip": "Guthaben (Credits) - Tooltip",
|
||||
"Balance currency": "Guthabenwährung",
|
||||
"Balance currency - Tooltip": "Guthabenwährung - Tooltip",
|
||||
"Edit Organization": "Organisation bearbeiten",
|
||||
"Follow global theme": "Folge dem globalen Theme",
|
||||
"Has privilege consent": "Privilegienzustimmung vorhanden",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "Regel ändern",
|
||||
"New Organization": "Neue Organisation",
|
||||
"Optional": "Optional",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "Organisationsguthaben",
|
||||
"Org balance - Tooltip": "Organisationsguthaben - Tooltip",
|
||||
"Password expire days": "Passwort läuft ab in Tagen",
|
||||
"Password expire days - Tooltip": "Anzahl der Tage vor dem Ablauf des Passworts",
|
||||
"Prompt": "Aufforderung",
|
||||
@@ -778,10 +798,10 @@
|
||||
"Tags": "Tags",
|
||||
"Use Email as username": "E-Mail als Benutzername verwenden",
|
||||
"Use Email as username - Tooltip": "E-Mail als Benutzername verwenden, wenn das Feld „Benutzername“ bei der Registrierung nicht sichtbar ist.",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User balance": "Benutzerguthaben",
|
||||
"User balance - Tooltip": "Benutzerguthaben - Tooltip",
|
||||
"User navbar items": "Benutzer-Navigationsleisten-Elemente",
|
||||
"User navbar items - Tooltip": "Benutzer-Navigationsleisten-Elemente - Tooltip",
|
||||
"User types": "Benutzertypen",
|
||||
"User types - Tooltip": "Verfügbare Benutzertypen im System",
|
||||
"View rule": "Ansichtsregel",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Bitte prüfen Sie sorgfältig Ihre Rechnungsinformationen. Sobald die Rechnung ausgestellt wurde, kann sie nicht zurückgenommen oder geändert werden.",
|
||||
"Please pay the order first!": "Bitte zahlen Sie zuerst die Bestellung!",
|
||||
"Processing...": "In Bearbeitung...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "Produkte - Tooltip",
|
||||
"Recharged successfully": "Erfolgreich aufgeladen",
|
||||
"Result": "Ergebnis",
|
||||
"The payment has been canceled": "Die Zahlung wurde storniert",
|
||||
"The payment has failed": "Die Zahlung ist fehlgeschlagen",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "Die Zahlung ist abgelaufen",
|
||||
"The payment is still under processing": "Die Zahlung wird immer noch bearbeitet",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "Zahlung anzeigen",
|
||||
"You can view your order details or return to the order list": "Sie können Ihre Bestelldetails ansehen oder zur Bestellliste zurückkehren",
|
||||
"You have successfully completed the payment": "Sie haben die Zahlung erfolgreich abgeschlossen",
|
||||
"You have successfully recharged": "Sie haben erfolgreich aufgeladen",
|
||||
"Your current balance is": "Ihr aktuelles Guthaben beträgt",
|
||||
@@ -867,13 +887,15 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Plan bearbeiten",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "Neuer Plan",
|
||||
"Period": "Zeitraum",
|
||||
"Period - Tooltip": "Zeitraum",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "Planname",
|
||||
"Price - Tooltip": "Preis",
|
||||
"Related product": "Zugehöriges Produkt",
|
||||
"View Plan": "View Plan",
|
||||
"View Plan": "Plan anzeigen",
|
||||
"per month": "pro Monat",
|
||||
"per year": "pro Jahr"
|
||||
},
|
||||
@@ -883,55 +905,62 @@
|
||||
"Free": "Kostenlos",
|
||||
"Getting started": "Loslegen",
|
||||
"New Pricing": "Neue Preisgestaltung",
|
||||
"Pricing name": "Pricing name",
|
||||
"Pricing name": "Pricing-Name",
|
||||
"Trial duration": "Testphase Dauer",
|
||||
"Trial duration - Tooltip": "Dauer der Testphase",
|
||||
"View Pricing": "View Pricing",
|
||||
"View Pricing": "Preisgestaltung anzeigen",
|
||||
"days trial available!": "Tage Testphase verfügbar!",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "Bezahlte Benutzer haben keine aktive oder ausstehende Abonnements, bitte wählen Sie einen Plan zum Kauf aus."
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "In den Warenkorb",
|
||||
"AirWallex": "AirWallex",
|
||||
"Alipay": "Alipay",
|
||||
"Amount": "Amount",
|
||||
"Amount": "Betrag",
|
||||
"Buy": "Kaufen",
|
||||
"Buy Product": "Produkt kaufen",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Benutzerdefinierter Betrag verfügbar",
|
||||
"Custom price should be greater than zero": "Benutzerdefinierter Preis muss größer als null sein",
|
||||
"Detail - Tooltip": "Detail des Produkts",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Disable custom amount": "Benutzerdefinierten Betrag deaktivieren",
|
||||
"Disable custom amount - Tooltip": "Benutzerdefinierten Betrag deaktivieren - Tooltip",
|
||||
"Dummy": "Dummy",
|
||||
"Edit Product": "Produkt bearbeiten",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
"Failed to create order": "Failed to create order",
|
||||
"Enter preset amounts": "Vorgegebene Beträge eingeben",
|
||||
"Failed to create order": "Bestellung konnte nicht erstellt werden",
|
||||
"Image": "Bild",
|
||||
"Image - Tooltip": "Bild des Produkts",
|
||||
"Information": "Information",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "Ist Aufladung",
|
||||
"Is recharge - Tooltip": "Ob das Produkt zum Aufladen des Guthabens dient",
|
||||
"Name": "Name",
|
||||
"New Product": "Neues Produkt",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Bestellung erfolgreich erstellt",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "Zahlung storniert",
|
||||
"Payment failed": "Zahlung fehlgeschlagen",
|
||||
"Payment providers": "Zahlungsprovider",
|
||||
"Payment providers - Tooltip": "Provider von Zahlungsdiensten",
|
||||
"Placing order...": "Bestellung aufgeben...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Bitte fügen Sie mindestens eine Aufladeoption hinzu, wenn der benutzerdefinierte Betrag deaktiviert ist",
|
||||
"Please select a currency": "Bitte wählen Sie eine Währung",
|
||||
"Please select at least one payment provider": "Bitte wählen Sie mindestens einen Zahlungsanbieter aus",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Zahlung wird verarbeitet...",
|
||||
"Product list cannot be empty": "Produktliste darf nicht leer sein",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Menge",
|
||||
"Quantity - Tooltip": "Menge des Produkts",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge options": "Aufladeoptionen",
|
||||
"Recharge options - Tooltip": "Aufladeoptionen - Tooltip",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "Rückkeht-URL",
|
||||
"Return URL - Tooltip": "URL für die Rückkehr nach einem erfolgreichen Kauf",
|
||||
"SKU": "SKU",
|
||||
"Select amount": "Select amount",
|
||||
"Select amount": "Betrag auswählen",
|
||||
"Sold": "Verkauft",
|
||||
"Sold - Tooltip": "Menge verkauft",
|
||||
"Stripe": "Stripe",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "URL, zu der nach dem Kauf zurückgekehrt wird",
|
||||
"Tag - Tooltip": "Tag des Produkts",
|
||||
"Test buy page..": "Testkaufseite.",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "Die Währung des Produkts, das Sie hinzufügen, unterscheidet sich von der Währung der Artikel im Warenkorb",
|
||||
"There is no payment channel for this product.": "Es gibt keinen Zahlungskanal für dieses Produkt.",
|
||||
"This product is currently not in sale.": "Dieses Produkt steht derzeit nicht zum Verkauf.",
|
||||
"This product is currently not purchasable (No options available)": "This product is currently not purchasable (No options available)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"This product is currently not purchasable (No options available)": "Dieses Produkt ist derzeit nicht kaufbar (keine Optionen verfügbar)",
|
||||
"Total Price": "Gesamtpreis",
|
||||
"View Product": "Produkt anzeigen",
|
||||
"WeChat Pay": "WeChat Pay"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Authentifizierungsschlüssel für den Dienst",
|
||||
"Auth URL": "Auth-URL",
|
||||
"Auth URL - Tooltip": "URL für die Authentifizierung",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "Basis-URL",
|
||||
"Base URL - Tooltip": "Basis-URL des Dienstes",
|
||||
"Bucket": "Eimer",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "Backup-Client-Verifizierungsschlüssel, verwendet zur Verifizierung bei Ausfall des primären Schlüssels oder in speziellen Szenarien",
|
||||
"Content": "Inhalt",
|
||||
"Content - Tooltip": "Spezifische Informationen oder Daten in Nachrichten, Benachrichtigungen oder Dokumenten",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "SSL deaktivieren",
|
||||
"Disable SSL - Tooltip": "Ob die Deaktivierung des SSL-Protokolls bei der Kommunikation mit dem STMP-Server erfolgen soll",
|
||||
"DB test": "DB-Test",
|
||||
"DB test - Tooltip": "DB-Test - Tooltip",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Domäne",
|
||||
"Domain - Tooltip": "Benutzerdefinierte Domain für Objektspeicher",
|
||||
"Edit Provider": "Provider bearbeiten",
|
||||
@@ -1001,10 +1030,11 @@
|
||||
"Email regex - Tooltip": "Nur E-Mails, die diesem regulären Ausdruck entsprechen, können sich registrieren oder anmelden",
|
||||
"Email title": "Email-Titel",
|
||||
"Email title - Tooltip": "Betreff der E-Mail",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "PKCE aktivieren",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Enable proxy": "Proxy aktivieren",
|
||||
"Enable proxy - Tooltip": "SOCKS5-Proxy beim Senden von E-Mails oder SMS aktivieren",
|
||||
"Endpoint": "Endpunkt",
|
||||
"Endpoint (Intranet)": "Endpunkt (Intranet)",
|
||||
"Endpoint - Tooltip": "URL des Dienstendpunkts",
|
||||
@@ -1031,13 +1061,13 @@
|
||||
"Key ID - Tooltip": "Eindeutige Kennung für den Schlüssel",
|
||||
"Key text": "Schlüsseltext",
|
||||
"Key text - Tooltip": "Inhalt des Schlüsseltexts",
|
||||
"LDAP port": "LDAP port",
|
||||
"LDAP port": "LDAP-Port",
|
||||
"Metadata": "Metadaten",
|
||||
"Metadata - Tooltip": "SAML-Metadaten",
|
||||
"Metadata url": "Metadaten-URL",
|
||||
"Metadata url - Tooltip": "SAML-Metadaten-URL",
|
||||
"Method - Tooltip": "Anmeldeverfahren, QR-Code oder Silent-Login",
|
||||
"Mobile": "Mobile",
|
||||
"Mobile": "Mobil",
|
||||
"New Provider": "Neuer Anbieter",
|
||||
"Parameter": "Parameter",
|
||||
"Parameter - Tooltip": "Konfigurationsparameter",
|
||||
@@ -1055,10 +1085,10 @@
|
||||
"Prompted": "ausgelöst",
|
||||
"Provider URL": "Anbieter-URL",
|
||||
"Provider URL - Tooltip": "URL zur Konfiguration des Dienstanbieters, dieses Feld dient nur als Referenz und wird in Casdoor nicht verwendet",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "Provider-Test erfolgreich",
|
||||
"Public key": "Öffentlicher Schlüssel",
|
||||
"Public key - Tooltip": "Öffentlicher Schlüssel für Verschlüsselung",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret of RADIUS",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret von RADIUS",
|
||||
"Region": "Region",
|
||||
"Region - Tooltip": "Geografische Region des Dienstes",
|
||||
"Region ID": "Regions-ID",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "SP-ACS-URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL",
|
||||
"SP Entity ID": "SP-Entitäts-ID",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Szene",
|
||||
"Scene - Tooltip": "Spezifisches Geschäftsszenario, in dem die Funktion oder Operation angewendet wird, verwendet zur Anpassung der logischen Verarbeitung für verschiedene Szenarien",
|
||||
"Scope": "Umfang",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Secret-Access-Key",
|
||||
"Secret access key - Tooltip": "Privater Schlüssel, der mit dem Zugriffsschlüssel gepaart ist, verwendet zum Signieren sensibler Operationen zur Verbesserung der Zugriffssicherheit",
|
||||
"Secret key": "Secret-Key",
|
||||
@@ -1111,8 +1144,8 @@
|
||||
"Sub type - Tooltip": "Weitere Unterkategorie unter dem Haupttyp, verwendet zur präziseren Unterscheidung von Objekten oder Funktionen",
|
||||
"Subject": "Betreff",
|
||||
"Subject - Tooltip": "E-Mail-Betreff",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype": "Untertyp",
|
||||
"Subtype - Tooltip": "Untertyp - Tooltip",
|
||||
"Syncer test": "Synchronisierer-Test",
|
||||
"Syncer test - Tooltip": "Synchronisierer-Test",
|
||||
"Team ID": "Team-ID",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "Testen Sie die SMTP-Verbindung",
|
||||
"Third-party": "Drittanbieter",
|
||||
"This field is required": "Dieses Feld ist erforderlich",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "An-Adresse",
|
||||
"To address - Tooltip": "E-Mail-Adresse im Feld „An“",
|
||||
"Token URL": "Token-URL",
|
||||
"Token URL - Tooltip": "Benutzerdefinierte OAuth Token-URL",
|
||||
"Use WeChat Media Platform in PC": "WeChat Media Platform am PC verwenden",
|
||||
@@ -1197,7 +1230,7 @@
|
||||
"Please input your last name!": "Bitte geben Sie Ihren Nachnamen ein!",
|
||||
"Please input your phone number!": "Bitte geben Sie Ihre Telefonnummer ein!",
|
||||
"Please input your real name!": "Bitte geben Sie Ihren richtigen Namen ein!",
|
||||
"Please input your {label}!": "Please input your {label}!",
|
||||
"Please input your {label}!": "Bitte geben Sie {label} ein!",
|
||||
"Please select your country code!": "Bitte wählen Sie Ihren Ländercode aus!",
|
||||
"Please select your country/region!": "Bitte wählen Sie Ihr Land/Ihre Region aus!",
|
||||
"Regex": "Regex",
|
||||
@@ -1210,7 +1243,7 @@
|
||||
"Text 4": "Text 4",
|
||||
"Text 5": "Text 5",
|
||||
"The input Email doesn't match the signup item regex!": "Die eingegebene E-Mail entspricht nicht dem Regex des Registrierungselements!",
|
||||
"The input doesn't match the signup item regex!": "The input doesn't match the signup item regex!",
|
||||
"The input doesn't match the signup item regex!": "Die Eingabe entspricht nicht dem Regex des Registrierungselements!",
|
||||
"The input is not invoice Tax ID!": "Die Eingabe ist keine Rechnungssteuer-ID!",
|
||||
"The input is not invoice title!": "Der Eingabewert ist nicht die Rechnungsbezeichnung!",
|
||||
"The input is not valid Phone!": "Die Eingabe ist kein gültiges Telefon!",
|
||||
@@ -1230,26 +1263,29 @@
|
||||
"New Subscription": "Neues Abonnement",
|
||||
"Start time": "Startzeit",
|
||||
"Start time - Tooltip": "Startzeit",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Subscription plan": "Abonnementplan",
|
||||
"Subscription pricing": "Abonnement-Preisgestaltung",
|
||||
"Suspended": "Ausgesetzt",
|
||||
"Upcoming": "Bevorstehend",
|
||||
"View Subscription": "View Subscription"
|
||||
"View Subscription": "Abonnement anzeigen"
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"Admin Email": "Admin Email",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "Admin-E-Mail",
|
||||
"Affiliation table": "Zuordnungstabelle",
|
||||
"Affiliation table - Tooltip": "Datenbanktabellenname der Arbeitseinheit",
|
||||
"Avatar base URL": "Avatar-Basis-URL",
|
||||
"Avatar base URL - Tooltip": "URL-Präfix für die Avatar-Bilder",
|
||||
"Bind DN": "Bind DN",
|
||||
"Bind DN": "Bind-DN",
|
||||
"Casdoor column": "Casdoor-Spalte",
|
||||
"Column name": "Spaltenname",
|
||||
"Column type": "Spaltentyp",
|
||||
"Connect successfully": "Verbindung erfolgreich",
|
||||
"Corp ID": "Corp ID",
|
||||
"Corp secret": "Corp secret",
|
||||
"Corp ID": "Corp-ID",
|
||||
"Corp secret": "Corp-Secret",
|
||||
"Database": "Datenbank",
|
||||
"Database - Tooltip": "Der ursprüngliche Datenbankname",
|
||||
"Database type": "Datenbanktyp",
|
||||
@@ -1263,15 +1299,15 @@
|
||||
"Is read-only": "Nur lesbar",
|
||||
"Is read-only - Tooltip": "Nur lesbar",
|
||||
"New Syncer": "Neuer Syncer",
|
||||
"Paste your Google Workspace service account JSON key here": "Paste your Google Workspace service account JSON key here",
|
||||
"SCIM Server URL": "SCIM Server URL",
|
||||
"Paste your Google Workspace service account JSON key here": "Fügen Sie hier Ihren Google Workspace Service-Account-JSON-Schlüssel ein",
|
||||
"SCIM Server URL": "SCIM-Server-URL",
|
||||
"SSH host": "SSH-Host",
|
||||
"SSH password": "SSH-Passwort",
|
||||
"SSH port": "SSH-Port",
|
||||
"SSH user": "SSH-Benutzer",
|
||||
"SSL mode": "SSL-Modus",
|
||||
"SSL mode - Tooltip": "SSL-Modus",
|
||||
"Service account key": "Service account key",
|
||||
"Service account key": "Service-Account-Schlüssel",
|
||||
"Sync interval": "Synchronisierungsintervall",
|
||||
"Sync interval - Tooltip": "Einheit in Sekunden",
|
||||
"Table": "Tabelle",
|
||||
@@ -1279,8 +1315,8 @@
|
||||
"Table columns": "Tabellenspalten",
|
||||
"Table columns - Tooltip": "Tabellenspalten, die an der Datensynchronisation beteiligt sind. Spalten, die nicht an der Synchronisation beteiligt sind, müssen nicht hinzugefügt werden",
|
||||
"Test Connection": "Verbindung testen",
|
||||
"Test DB Connection": "Test DB Connection",
|
||||
"Username (optional)": "Username (optional)"
|
||||
"Test DB Connection": "DB-Verbindung testen",
|
||||
"Username (optional)": "Benutzername (optional)"
|
||||
},
|
||||
"system": {
|
||||
"API Latency": "API Latenz",
|
||||
@@ -1311,16 +1347,16 @@
|
||||
"Theme - Tooltip": "Stiltheme der Anwendung"
|
||||
},
|
||||
"ticket": {
|
||||
"Closed": "Closed",
|
||||
"Edit Ticket": "Edit Ticket",
|
||||
"In Progress": "In Progress",
|
||||
"Messages": "Messages",
|
||||
"New Ticket": "New Ticket",
|
||||
"Open": "Open",
|
||||
"Please enter a message": "Please enter a message",
|
||||
"Press Ctrl+Enter to send": "Press Ctrl+Enter to send",
|
||||
"Resolved": "Resolved",
|
||||
"Type your message here...": "Type your message here..."
|
||||
"Closed": "Geschlossen",
|
||||
"Edit Ticket": "Ticket bearbeiten",
|
||||
"In Progress": "In Bearbeitung",
|
||||
"Messages": "Nachrichten",
|
||||
"New Ticket": "Neues Ticket",
|
||||
"Open": "Offen",
|
||||
"Please enter a message": "Bitte geben Sie eine Nachricht ein",
|
||||
"Press Ctrl+Enter to send": "Drücken Sie Strg+Enter zum Senden",
|
||||
"Resolved": "Gelöst",
|
||||
"Type your message here...": "Geben Sie hier Ihre Nachricht ein..."
|
||||
},
|
||||
"token": {
|
||||
"Access token": "Access-Token",
|
||||
@@ -1342,7 +1378,7 @@
|
||||
"Amount - Tooltip": "Der Betrag der gehandelten Produkte",
|
||||
"Edit Transaction": "Transaktion bearbeiten",
|
||||
"New Transaction": "Neue Transaktion",
|
||||
"Recharge": "Recharge"
|
||||
"Recharge": "Aufladen"
|
||||
},
|
||||
"user": {
|
||||
"3rd-party logins": "Drittanbieter-Logins",
|
||||
@@ -1386,20 +1422,20 @@
|
||||
"ID card type": "Ausweistyp",
|
||||
"ID card type - Tooltip": "Art des Ausweises",
|
||||
"ID card with person": "Ausweis mit Person",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"ID verification": "Identitätsprüfung",
|
||||
"ID verification - Tooltip": "Identitätsprüfung - Tooltip",
|
||||
"Identity verification successful": "Identitätsprüfung erfolgreich",
|
||||
"Identity verified": "Identität verifiziert",
|
||||
"Input your email": "Geben Sie Ihre E-Mail-Adresse ein",
|
||||
"Input your phone number": "Geben Sie Ihre Telefonnummer ein",
|
||||
"Is admin": "Ist Admin",
|
||||
"Is admin - Tooltip": "Ist ein Administrator der Organisation, zu der der Benutzer gehört",
|
||||
"Is deleted": "ist gelöscht",
|
||||
"Is deleted - Tooltip": "\"Gelöschte Benutzer behalten nur Datenbankdatensätze und können keine Operationen ausführen.\"",
|
||||
"Is deleted - Tooltip": "Gelöschte Benutzer behalten nur Datenbankdatensätze und können keine Operationen ausführen - Hinweis",
|
||||
"Is forbidden": "Ist verboten",
|
||||
"Is forbidden - Tooltip": "Verbotene Benutzer können sich nicht mehr einloggen",
|
||||
"Is online": "Ist online",
|
||||
"Is verified": "Is verified",
|
||||
"Is verified": "Ist verifiziert",
|
||||
"Karma": "Karma",
|
||||
"Karma - Tooltip": "Punkte zur Messung der Vertrauensstufe des Benutzers, beeinflussen Berechtigungen oder den Umfang der Dienstnutzung",
|
||||
"Keys": "Schlüssel",
|
||||
@@ -1424,16 +1460,16 @@
|
||||
"Other": "Andere",
|
||||
"Password set successfully": "Passwort erfolgreich festgelegt",
|
||||
"Phone cannot be empty": "Telefonnummer kann nicht leer sein",
|
||||
"Please enter your real name": "Please enter your real name",
|
||||
"Please fill in ID card information first": "Please fill in ID card information first",
|
||||
"Please fill in your real name first": "Please fill in your real name first",
|
||||
"Please enter your real name": "Bitte geben Sie Ihren echten Namen ein",
|
||||
"Please fill in ID card information first": "Bitte füllen Sie zuerst die Ausweisinformationen aus",
|
||||
"Please fill in your real name first": "Bitte geben Sie zuerst Ihren echten Namen ein",
|
||||
"Please select avatar from resources": "Bitte wählen Sie einen Avatar aus den Ressourcen aus",
|
||||
"Properties": "Eigenschaften",
|
||||
"Properties - Tooltip": "Eigenschaften des Benutzers",
|
||||
"Ranking": "Rang",
|
||||
"Ranking - Tooltip": "Position des Benutzers in der Rangfolge basierend auf Punkten, Aktivitätsniveau und anderen Metriken",
|
||||
"Re-enter New": "Neueingabe wiederholen",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Real name - Tooltip": "Echter Name - Tooltip",
|
||||
"Register source": "Registrierungsquelle",
|
||||
"Register source - Tooltip": "Die Quelle, von der aus der Benutzer registriert wurde",
|
||||
"Register type": "Registrierungstyp",
|
||||
@@ -1462,8 +1498,8 @@
|
||||
"User Profile": "Benutzerprofil",
|
||||
"Values": "Werte",
|
||||
"Verification code sent": "Bestätigungscode gesendet",
|
||||
"Verified": "Verified",
|
||||
"Verify Identity": "Verify Identity",
|
||||
"Verified": "Verifiziert",
|
||||
"Verify Identity": "Identität verifizieren",
|
||||
"WebAuthn credentials": "WebAuthn-Anmeldeinformationen",
|
||||
"Work": "Arbeit",
|
||||
"You have changed the username, please save your change first before modifying the password": "Sie haben den Benutzernamen geändert. Bitte speichern Sie zuerst, bevor Sie das Passwort ändern.",
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
"Enable signin session - Tooltip": "Whether Casdoor maintains a session after logging into Casdoor from the application",
|
||||
"Enable signup": "Enable signup",
|
||||
"Enable signup - Tooltip": "Whether to allow users to register a new account",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Failed signin frozen time",
|
||||
"Failed signin frozen time - Tooltip": "Waiting time after exceeding the number of failed login attempts. Users can only log in again after the waiting time expires. Default value is 15 minutes. The set value must be a positive integer",
|
||||
"Failed signin limit": "Failed signin limit",
|
||||
@@ -112,12 +113,19 @@
|
||||
"Order - Tooltip": "The smaller the value, the higher it ranks in the Apps page",
|
||||
"Org choice mode": "Org choice mode",
|
||||
"Org choice mode - Tooltip": "Method used to select the organization to log in",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Additional domains that should also route to this application",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Please enable \"Signin session\" first before enabling \"Auto signin\"",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
"Pop up": "Pop up",
|
||||
"Providers": "Providers",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "SSL/TLS mode for the reverse proxy",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "The public-facing domain for this application (e.g., blog.example.com)",
|
||||
"Random": "Random",
|
||||
"Real name": "Real name",
|
||||
"Redirect URL": "Redirect URL",
|
||||
@@ -127,6 +135,7 @@
|
||||
"Refresh token expire": "Refresh token expire",
|
||||
"Refresh token expire - Tooltip": "Refresh token expiration time",
|
||||
"Reset to Empty": "Reset to Empty",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "Right",
|
||||
"Rule": "Rule",
|
||||
"SAML hash algorithm": "SAML hash algorithm",
|
||||
@@ -134,6 +143,8 @@
|
||||
"SAML metadata": "SAML metadata",
|
||||
"SAML metadata - Tooltip": "The metadata of SAML protocol",
|
||||
"SAML reply URL": "SAML reply URL",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "Certificate to use for TLS termination",
|
||||
"Security": "Security",
|
||||
"Select": "Select",
|
||||
"Side panel HTML": "Side panel HTML",
|
||||
@@ -151,6 +162,7 @@
|
||||
"Signup items - Tooltip": "Items for users to fill in when registering new accounts",
|
||||
"Single Choice": "Single Choice",
|
||||
"Small icon": "Small icon",
|
||||
"Static Value": "Static Value",
|
||||
"String": "String",
|
||||
"Tags - Tooltip": "Only users with the tag that is listed in the application tags can login",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
@@ -163,6 +175,8 @@
|
||||
"Token signing method": "Token signing method",
|
||||
"Token signing method - Tooltip": "Signing method of JWT token, needs to be the same algorithm as the certificate",
|
||||
"UI Customization": "UI Customization",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "The upstream backend address to forward requests to (e.g., localhost:8080 or 192.168.1.100)",
|
||||
"Use Email as NameID": "Use Email as NameID",
|
||||
"Use Email as NameID - Tooltip": "Use Email as NameID",
|
||||
"Vertical": "Vertical",
|
||||
@@ -283,6 +297,8 @@
|
||||
"Cancel": "Cancel",
|
||||
"Captcha": "Captcha",
|
||||
"Cart": "Cart",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "Cert",
|
||||
"Cert - Tooltip": "The public key certificate that needs to be verified by the client SDK corresponding to this application",
|
||||
"Certs": "Certs",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "The auth type of SSH connection",
|
||||
"Save": "Save",
|
||||
"Save & Exit": "Save & Exit",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Search",
|
||||
"Send": "Send",
|
||||
"Session ID": "Session ID",
|
||||
@@ -530,6 +548,7 @@
|
||||
"Transactions": "Transactions",
|
||||
"True": "True",
|
||||
"Type": "Type",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "URL link",
|
||||
"Unknown application name": "Unknown application name",
|
||||
@@ -751,6 +770,7 @@
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"All": "All",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
@@ -867,6 +887,8 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Edit Plan",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "New Plan",
|
||||
"Period": "Period",
|
||||
"Period - Tooltip": "Period for the plan",
|
||||
@@ -897,6 +919,7 @@
|
||||
"Amount": "Amount",
|
||||
"Buy": "Buy",
|
||||
"Buy Product": "Buy Product",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Detail - Tooltip": "Detail of product",
|
||||
@@ -909,9 +932,12 @@
|
||||
"Image": "Image",
|
||||
"Image - Tooltip": "Image of product",
|
||||
"Information": "Information",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "Is recharge",
|
||||
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||
"Name": "Name",
|
||||
"New Product": "New Product",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "Payment cancelled",
|
||||
@@ -922,12 +948,15 @@
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Quantity",
|
||||
"Quantity - Tooltip": "Quantity of product",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Preset recharge amounts",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "Return URL",
|
||||
"Return URL - Tooltip": "URL to return to after successful purchase",
|
||||
"SKU": "SKU",
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Authentication key for the service",
|
||||
"Auth URL": "Auth URL",
|
||||
"Auth URL - Tooltip": "URL for authentication",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "Base URL",
|
||||
"Base URL - Tooltip": "Base URL of the service",
|
||||
"Bucket": "Bucket",
|
||||
@@ -990,8 +1020,7 @@
|
||||
"Content - Tooltip": "Specific information or data contained in messages, notifications, or documents",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "Disable SSL",
|
||||
"Disable SSL - Tooltip": "Whether to disable SSL protocol when communicating with STMP server",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Domain",
|
||||
"Domain - Tooltip": "Custom domain for object storage",
|
||||
"Edit Provider": "Edit Provider",
|
||||
@@ -1001,6 +1030,7 @@
|
||||
"Email regex - Tooltip": "Only emails matching this regular expression can register or sign in",
|
||||
"Email title": "Email title",
|
||||
"Email title - Tooltip": "Subject of the email",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE (Proof Key for Code Exchange) for enhanced OAuth 2.0 security",
|
||||
"Enable proxy": "Enable proxy",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL",
|
||||
"SP Entity ID": "SP Entity ID",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Scene",
|
||||
"Scene - Tooltip": "Specific business scenario where the function or operation applies, used to adapt logic processing for different scenarios",
|
||||
"Scope": "Scope",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Secret access key",
|
||||
"Secret access key - Tooltip": "Private key paired with the access key, used for signing sensitive operations to enhance access security",
|
||||
"Secret key": "Secret key",
|
||||
@@ -1238,6 +1271,9 @@
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "Admin Email",
|
||||
"Affiliation table": "Affiliation table",
|
||||
"Affiliation table - Tooltip": "Database table name of the work unit",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "Salir de suplantación",
|
||||
"Logout": "Cierre de sesión",
|
||||
"My Account": "Mi cuenta",
|
||||
"Sign Up": "Registrarse"
|
||||
@@ -22,22 +22,22 @@
|
||||
"Add Face ID with Image": "Agregar Face ID con imagen",
|
||||
"Always": "siempre",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Authentication": "Autenticación",
|
||||
"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": "URL de fondo para móvil",
|
||||
"Background URL Mobile - Tooltip": "URL de la imagen de fondo para dispositivos móviles",
|
||||
"Basic": "Basic",
|
||||
"Basic": "Básico",
|
||||
"Big icon": "Icono grande",
|
||||
"Binding providers": "Proveedores de vinculación",
|
||||
"CSS style": "Estilo CSS",
|
||||
"Center": "Centro",
|
||||
"Code resend timeout": "Tiempo de espera para reenviar código",
|
||||
"Code resend timeout - Tooltip": "Período de tiempo (en segundos) que los usuarios deben esperar antes de solicitar otro código de verificación. Establecer en 0 para usar el valor predeterminado global (60 segundos)",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Caducidad de cookie",
|
||||
"Cookie expire - Tooltip": "Tiempo de caducidad de la cookie - Sugerencia",
|
||||
"Copy SAML metadata URL": "Copia la URL de metadatos SAML",
|
||||
"Copy prompt page URL": "Copiar URL de la página del prompt",
|
||||
"Copy signin page URL": "Copiar la URL de la página de inicio de sesión",
|
||||
@@ -47,9 +47,9 @@
|
||||
"Custom CSS - Tooltip": "Estilo CSS de los formularios de registro, inicio de sesión y olvido de contraseña (por ejemplo, agregar bordes y sombras)",
|
||||
"Custom CSS Mobile": "CSS personalizado para móvil",
|
||||
"Custom CSS Mobile - Edit": "CSS personalizado para móvil - Editar",
|
||||
"Custom CSS Mobile - Tooltip": "CSS personalizado para dispositivos móviles",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Custom CSS Mobile - Tooltip": "CSS personalizado para dispositivos móviles - Sugerencia",
|
||||
"Disable SAML attributes": "Desactivar atributos SAML",
|
||||
"Disable SAML attributes - Tooltip": "Desactivar atributos SAML - Sugerencia",
|
||||
"Disable signin": "Desactivar inicio de sesión",
|
||||
"Disable signin - Tooltip": "Desactivar el inicio de sesión para los usuarios",
|
||||
"Dynamic": "Dinámico",
|
||||
@@ -60,16 +60,17 @@
|
||||
"Enable SAML C14N10 - Tooltip": "Usar C14N10 en lugar de C14N11 en SAML",
|
||||
"Enable SAML POST binding": "Habilitar enlace POST de SAML",
|
||||
"Enable SAML POST binding - Tooltip": "El enlace HTTP POST utiliza campos de entrada en un formulario HTML para enviar mensajes SAML. Habilítelo cuando su SP lo utilice.",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "Habilitar firma de aserción SAML",
|
||||
"Enable SAML assertion signature - Tooltip": "Habilitar firma de aserción SAML - Sugerencia",
|
||||
"Enable SAML compression": "Activar la compresión SAML",
|
||||
"Enable SAML compression - Tooltip": "Si comprimir o no los mensajes de respuesta SAML cuando se utiliza Casdoor como proveedor de identidad SAML",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "Habilitar inicio de sesión exclusivo",
|
||||
"Enable exclusive signin - Tooltip": "Cuando el inicio de sesión exclusivo está habilitado, el usuario no puede tener varias sesiones activas",
|
||||
"Enable side panel": "Habilitar panel lateral",
|
||||
"Enable signin session - Tooltip": "Si Casdoor mantiene una sesión después de iniciar sesión en Casdoor desde la aplicación",
|
||||
"Enable signup": "Habilitar registro",
|
||||
"Enable signup - Tooltip": "Ya sea permitir que los usuarios registren una nueva cuenta",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Tiempo de congelación tras inicio fallido",
|
||||
"Failed signin frozen time - Tooltip": "Tiempo durante el cual la cuenta está congelada después de intentos fallidos de inicio de sesión",
|
||||
"Failed signin limit": "Límite de intentos fallidos de inicio",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "Cerró sesión exitosamente",
|
||||
"MFA remember time": "Tiempo de recordatorio MFA",
|
||||
"MFA remember time - Tooltip": "Configura la duración durante la cual una cuenta se recuerda como confiable después de un inicio de sesión MFA exitoso",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "Modo de menú",
|
||||
"Menu mode - Tooltip": "Modo de menú - Sugerencia",
|
||||
"Multiple Choices": "Opciones múltiples",
|
||||
"New Application": "Nueva aplicación",
|
||||
"No verification": "Sin verificación",
|
||||
@@ -111,48 +112,59 @@
|
||||
"Order": "Orden",
|
||||
"Order - Tooltip": "Cuanto menor sea el valor, más alto se clasificará en la página de Aplicaciones",
|
||||
"Org choice mode": "Modo de selección de organización",
|
||||
"Org choice mode - Tooltip": "Modo de elección de organización",
|
||||
"Org choice mode - Tooltip": "Método utilizado para seleccionar la organización para iniciar sesión - Sugerencia",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Por favor, habilita \"Sesión de inicio de sesión\" primero antes de habilitar \"Inicio de sesión automático\"",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "¡Por favor, ingrese su solicitud!",
|
||||
"Please input your organization!": "¡Por favor, ingrese su organización!",
|
||||
"Please select a HTML file": "Por favor, seleccione un archivo HTML",
|
||||
"Pop up": "Ventana emergente",
|
||||
"Providers": "Providers",
|
||||
"Providers": "Proveedores",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "Aleatorio",
|
||||
"Real name": "Nombre real",
|
||||
"Redirect URL": "Redireccionar URL",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redireccionamiento (URL de enlace de publicación del servicio consumidor de afirmaciones)",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redireccionamiento (URL de enlace de publicación del servicio consumidor de afirmaciones) - Sugerencia",
|
||||
"Redirect URLs": "Redireccionar URLs",
|
||||
"Redirect URLs - Tooltip": "Lista de URL de redireccionamiento permitidos, con soporte para coincidencias de expresiones regulares; las URL que no estén en la lista no se redirigirán",
|
||||
"Refresh token expire": "Token de actualización expirado",
|
||||
"Refresh token expire - Tooltip": "Tiempo de caducidad del token de actualización",
|
||||
"Reset to Empty": "Restablecer a vacío",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "Correcto",
|
||||
"Rule": "Regla",
|
||||
"SAML hash algorithm": "Algoritmo hash SAML",
|
||||
"SAML hash algorithm - Tooltip": "Algoritmo hash para la firma SAML",
|
||||
"SAML metadata": "Metadatos de SAML",
|
||||
"SAML metadata - Tooltip": "Los metadatos del protocolo SAML",
|
||||
"SAML metadata - Tooltip": "Los metadatos del protocolo SAML - Sugerencia",
|
||||
"SAML reply URL": "URL de respuesta SAML",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "Seguridad",
|
||||
"Select": "Seleccionar",
|
||||
"Side panel HTML": "Panel lateral HTML",
|
||||
"Side panel HTML - Edit": "Panel lateral HTML - Editar",
|
||||
"Side panel HTML - Tooltip": "Personaliza el código HTML del panel lateral de la página de inicio de sesión",
|
||||
"Side panel HTML - Tooltip": "Personalizar el código HTML del panel lateral de la página de inicio de sesión - Sugerencia",
|
||||
"Sign Up Error": "Error de registro",
|
||||
"Signin": "Iniciar sesión",
|
||||
"Signin (Default True)": "Iniciar sesión (Verdadero por defecto)",
|
||||
"Signin items": "Elementos de inicio",
|
||||
"Signin items - Tooltip": "Elementos de inicio de sesión",
|
||||
"Signin items - Tooltip": "Elementos para que los usuarios completen al iniciar sesión - Sugerencia",
|
||||
"Signin methods": "Métodos de inicio",
|
||||
"Signin methods - Tooltip": "Métodos de inicio - Información adicional",
|
||||
"Signin session": "Sesión de inicio de sesión",
|
||||
"Signup items": "Artículos de registro",
|
||||
"Signup items - Tooltip": "Elementos para que los usuarios los completen al registrar nuevas cuentas",
|
||||
"Signup items - Tooltip": "Elementos para que los usuarios completen al registrar nuevas cuentas - Sugerencia",
|
||||
"Single Choice": "Opción única",
|
||||
"Small icon": "Icono pequeño",
|
||||
"String": "String",
|
||||
"Tags - Tooltip": "Solo los usuarios con la etiqueta que esté listada en las etiquetas de la aplicación pueden iniciar sesión",
|
||||
"Static Value": "Static Value",
|
||||
"String": "Cadena",
|
||||
"Tags - Tooltip": "Solo los usuarios con la etiqueta que esté listada en las etiquetas de la aplicación pueden iniciar sesión - Sugerencia",
|
||||
"The application does not allow to sign up new account": "La aplicación no permite registrarse una cuenta nueva",
|
||||
"Token expire": "Token expirado",
|
||||
"Token expire - Tooltip": "Tiempo de expiración del token de acceso",
|
||||
@@ -162,7 +174,9 @@
|
||||
"Token format - Tooltip": "El formato del token de acceso",
|
||||
"Token signing method": "Método de firma del token",
|
||||
"Token signing method - Tooltip": "Método de firma del token JWT, debe ser el mismo algoritmo que el certificado",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "Personalización de la interfaz",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "Usar correo electrónico como NameID",
|
||||
"Use Email as NameID - Tooltip": "Usar correo electrónico como NameID - Información adicional",
|
||||
"Vertical": "Vertical",
|
||||
@@ -182,7 +196,7 @@
|
||||
"Edit Cert": "Editar Certificado",
|
||||
"Expire in years": "Vencer en años",
|
||||
"Expire in years - Tooltip": "Período de validez del certificado, en años",
|
||||
"New Cert": "ificado",
|
||||
"New Cert": "Nuevo certificado",
|
||||
"Private key": "Clave privada",
|
||||
"Private key - Tooltip": "Clave privada correspondiente al certificado de clave pública",
|
||||
"Scope - Tooltip": "Escenarios de uso del certificado",
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "Ancho"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "Un usuario normal solo puede modificar el permiso enviado por sí mismo",
|
||||
"AI Assistant": "Asistente de IA",
|
||||
"API key": "Clave API",
|
||||
"API key - Tooltip": "Clave API para acceder al servicio",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "Negocios y pagos",
|
||||
"Cancel": "Cancelar",
|
||||
"Captcha": "Captcha",
|
||||
"Cart": "Cart",
|
||||
"Cert": "ificado",
|
||||
"Cart": "Carrito",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "Certificado",
|
||||
"Cert - Tooltip": "El certificado de clave pública que necesita ser verificado por el SDK del cliente correspondiente a esta aplicación",
|
||||
"Certs": "Certificaciones",
|
||||
"Clear": "Clear",
|
||||
"Clear": "Limpiar",
|
||||
"Click to Upload": "Haz clic para cargar",
|
||||
"Client IP": "IP del cliente",
|
||||
"Close": "Cerca",
|
||||
@@ -307,12 +323,12 @@
|
||||
"Delete": "Eliminar",
|
||||
"Description": "Descripción",
|
||||
"Description - Tooltip": "Información detallada de descripción para referencia, Casdoor en sí no la utilizará",
|
||||
"Detail": "详情",
|
||||
"Detail": "Detalle",
|
||||
"Disable": "Deshabilitar",
|
||||
"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",
|
||||
"Down": "Abajo",
|
||||
"Download template": "Download template",
|
||||
"Download template": "Descargar plantilla",
|
||||
"Edit": "Editar",
|
||||
"Email": "Correo electrónico",
|
||||
"Email - Tooltip": "Dirección de correo electrónico válida",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "Habilitado exitosamente",
|
||||
"Enforcers": "Aplicadores",
|
||||
"Failed to add": "No se pudo agregar",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "Error al cancelar",
|
||||
"Failed to connect to server": "No se pudo conectar al servidor",
|
||||
"Failed to copy": "Error al copiar",
|
||||
"Failed to delete": "No se pudo eliminar",
|
||||
"Failed to enable": "Error al habilitar",
|
||||
"Failed to get": "Error al obtener",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "Error al cargar",
|
||||
"Failed to log out": "Error al cerrar sesión",
|
||||
"Failed to remove": "Error al eliminar",
|
||||
"Failed to save": "No se pudo guardar",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "Error al enviar",
|
||||
"Failed to sync": "Error al sincronizar",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "Error al desvincular",
|
||||
"Failed to update": "Error al actualizar",
|
||||
"Failed to upload": "Error al subir",
|
||||
"Failed to verify": "Error al verificar",
|
||||
"False": "Falso",
|
||||
"Favicon": "Favicon",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "URL personalizada para la página \"Olvidé mi contraseña\". Si no se establece, se utilizará la página \"Olvidé mi contraseña\" predeterminada de Casdoor. Cuando se establezca, el enlace \"Olvidé mi contraseña\" en la página de inicio de sesión redireccionará a esta URL",
|
||||
"Forms": "Formularios",
|
||||
"Found some texts still not translated? Please help us translate at": "¿Encontraste algunos textos que aún no están traducidos? Por favor, ayúdanos a traducirlos en",
|
||||
"Generate": "Generate",
|
||||
"Generate": "Generar",
|
||||
"Go to enable": "Ir a habilitar",
|
||||
"Go to writable demo site?": "¿Ir al sitio demo editable?",
|
||||
"Groups": "Grupos",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "Lista blanca de IP",
|
||||
"IP whitelist - Tooltip": "Lista blanca de IP",
|
||||
"Identity": "Identidad",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "Suplantación",
|
||||
"Invitations": "Invitaciones",
|
||||
"Is enabled": "Está habilitado",
|
||||
"Is enabled - Tooltip": "Establecer si se puede usar",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "Nombre",
|
||||
"Name - Tooltip": "ID único basado en cadenas",
|
||||
"Name format": "Formato del nombre",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "No hay productos disponibles",
|
||||
"No sheets found in file": "No se encontraron hojas en el archivo",
|
||||
"No verification method": "No hay método de verificación",
|
||||
"Non-LDAP": "No LDAP",
|
||||
"None": "Ninguno",
|
||||
"OAuth providers": "Proveedores de OAuth",
|
||||
"OFF": "DESACTIVADO",
|
||||
"OK": "Aceptar",
|
||||
"ON": "ACTIVADO",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "Solo se puede requerir 1 método MFA",
|
||||
"Or": "O",
|
||||
"Orders": "Pedidos",
|
||||
"Organization": "Organización",
|
||||
"Organization - Tooltip": "Similar a conceptos como inquilinos o grupos de usuarios, cada usuario y aplicación pertenece a una organización",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "La organización es nula",
|
||||
"Organizations": "Organizaciones",
|
||||
"Password": "Contraseña",
|
||||
"Password - Tooltip": "Asegúrate de que la contraseña sea correcta",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "Número de teléfono",
|
||||
"Phone only": "Solo teléfono",
|
||||
"Phone or Email": "Teléfono o correo electrónico",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "Realizar pedido",
|
||||
"Plain": "Plano",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan de suscripción",
|
||||
"Plans": "Planes",
|
||||
"Plans - Tooltip": "Planes - Información adicional",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "Por favor, completa el captcha correctamente",
|
||||
"Please input your search": "Por favor ingrese su búsqueda",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "Por favor, selecciona al menos 1 usuario primero",
|
||||
"Preview": "Avance",
|
||||
"Preview - Tooltip": "Vista previa de los efectos configurados",
|
||||
"Pricing": "Precios",
|
||||
"Pricing - Tooltip": "Precios - Información adicional",
|
||||
"Pricings": "Precios",
|
||||
"Product Store": "Product Store",
|
||||
"Product Store": "Tienda de productos",
|
||||
"Products": "Productos",
|
||||
"Provider": "Proveedor",
|
||||
"Provider - Tooltip": "Proveedores de pago a configurar, incluyendo PayPal, Alipay, WeChat Pay, etc.",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "El tipo de autenticación de conexión SSH",
|
||||
"Save": "Guardar",
|
||||
"Save & Exit": "Guardar y salir",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Buscar",
|
||||
"Send": "Enviar",
|
||||
"Session ID": "ID de sesión",
|
||||
@@ -493,13 +511,13 @@
|
||||
"Sorry, you do not have permission to access this page or logged in status invalid.": "Lo siento, no tiene permiso para acceder a esta página o su estado de inicio de sesión es inválido.",
|
||||
"State": "Estado",
|
||||
"State - Tooltip": "Estado",
|
||||
"Status": "Status",
|
||||
"Status": "Estado",
|
||||
"Subscriptions": "Suscripciones",
|
||||
"Successfully added": "Éxito al agregar",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "Cancelado con éxito",
|
||||
"Successfully copied": "Copiado exitosamente",
|
||||
"Successfully deleted": "Éxito en la eliminación",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "Ejecutado con éxito",
|
||||
"Successfully removed": "Eliminado exitosamente",
|
||||
"Successfully saved": "Guardado exitosamente",
|
||||
"Successfully sent": "Enviado exitosamente",
|
||||
@@ -514,9 +532,9 @@
|
||||
"Syncers": "Sincronizadores",
|
||||
"System Info": "Información del Sistema",
|
||||
"Tab": "Pestaña",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "Las acciones no pueden estar vacías",
|
||||
"The resources cannot be empty": "Los recursos no pueden estar vacíos",
|
||||
"The users and roles cannot be empty at the same time": "Los usuarios y los roles no pueden estar vacíos al mismo tiempo",
|
||||
"There was a problem signing you in..": "Hubo un problema al iniciar sesión...",
|
||||
"This is a read-only demo site!": "¡Este es un sitio de demostración solo de lectura!",
|
||||
"Tickets": "Tickets",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "Transacciones",
|
||||
"True": "Verdadero",
|
||||
"Type": "Tipo",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "Enlace de URL",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "Nombre de aplicación desconocido",
|
||||
"Unknown authentication type": "Tipo de autenticación desconocido",
|
||||
"Up": "Arriba",
|
||||
"Updated time": "Tiempo actualizado",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"Upload (.xlsx)": "Subir (.xlsx)",
|
||||
"User": "Usuario",
|
||||
"User - Tooltip": "Asegúrate de que el nombre de usuario sea correcto",
|
||||
"User Management": "Gestión de usuarios",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "El usuario ya existe",
|
||||
"User containers": "Piscinas de usuarios",
|
||||
"User type": "Tipo de usuario",
|
||||
"User type - Tooltip": "Etiquetas a las que el usuario pertenece, con una configuración predeterminada en \"usuario-normal\"",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "Usuarios - Información adicional",
|
||||
"Users under all organizations": "Usuarios bajo todas las organizaciones",
|
||||
"Verifications": "Verificaciones",
|
||||
"View": "View",
|
||||
"View": "Ver",
|
||||
"Webhooks": "Webhooks",
|
||||
"You can only select one physical group": "Solo puedes seleccionar un grupo físico",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "Primero debes seleccionar una imagen",
|
||||
"empty": "vacío",
|
||||
"remove": "eliminar",
|
||||
"{total} in total": "{total} en total"
|
||||
@@ -626,7 +645,7 @@
|
||||
"login": {
|
||||
"Auto sign in": "Inicio de sesión automático",
|
||||
"Back button": "Botón atrás",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "Haz clic en el botón de abajo para iniciar sesión con Telegram",
|
||||
"Continue with": "Continúe con",
|
||||
"Email or phone": "Correo electrónico o teléfono",
|
||||
"Face ID": "Face ID",
|
||||
@@ -649,12 +668,12 @@
|
||||
"Please input your Email!": "¡Por favor ingresa tu correo electrónico!",
|
||||
"Please input your LDAP username!": "¡Por favor ingresa tu usuario LDAP!",
|
||||
"Please input your Phone!": "¡Por favor ingresa tu teléfono!",
|
||||
"Please input your RADIUS password!": "Please input your RADIUS password!",
|
||||
"Please input your RADIUS username!": "Please input your RADIUS username!",
|
||||
"Please input your RADIUS password!": "¡Por favor, introduce tu contraseña RADIUS!",
|
||||
"Please input your RADIUS username!": "¡Por favor, introduce tu usuario RADIUS!",
|
||||
"Please input your code!": "¡Por favor ingrese su código!",
|
||||
"Please input your organization name!": "¡Por favor ingresa el nombre de tu organización!",
|
||||
"Please input your password!": "¡Ingrese su contraseña, por favor!",
|
||||
"Please input your push notification receiver!": "Please input your push notification receiver!",
|
||||
"Please input your push notification receiver!": "¡Por favor, introduce el destinatario de notificaciones push!",
|
||||
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Por favor carga la página usando HTTPS, de lo contrario no se puede acceder a la cámara",
|
||||
"Please provide permission to access the camera": "Por favor otorga permiso para acceder a la cámara",
|
||||
"Please select an organization": "Por favor selecciona una organización",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "Seleccionar organización",
|
||||
"Sign In": "Iniciar sesión",
|
||||
"Sign in with Face ID": "Iniciar sesión con Face ID",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "Iniciar sesión con Telegram",
|
||||
"Sign in with WebAuthn": "Iniciar sesión con WebAuthn",
|
||||
"Sign in with {type}": "Inicia sesión con {tipo}",
|
||||
"Signin button": "Botón de inicio",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "Por favor confirma la siguiente información",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "Por favor guarda este código de recuperación. Si tu dispositivo no puede proporcionar un código de autenticación, puedes restablecer la autenticación MFA con este código",
|
||||
"Protect your account with Multi-factor authentication": "Protege tu cuenta con autenticación multifactor",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "Destinatario de notificaciones push",
|
||||
"Recovery code": "Código de recuperación",
|
||||
"Remember this account for {hour} hours": "Recordar esta cuenta por {hour} horas",
|
||||
"Scan the QR code with your Authenticator App": "Escanea el código QR con tu aplicación de autenticación",
|
||||
@@ -708,17 +727,17 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "Para asegurar la seguridad de tu cuenta, es obligatorio habilitar la autenticación multifactor",
|
||||
"Use Authenticator App": "Usar aplicación de autenticación",
|
||||
"Use Email": "Usar correo electrónico",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "Usar notificación push",
|
||||
"Use Radius": "Usar RADIUS",
|
||||
"Use SMS": "Usar SMS",
|
||||
"Use SMS verification code": "Usar código de verificación SMS",
|
||||
"Use a recovery code": "Usar un código de recuperación",
|
||||
"Verify Code": "Verificar código",
|
||||
"Verify Password": "Verificar contraseña",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "Has habilitado autenticación multifactor, por favor haz clic en 'Enviar código' para continuar",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "Has habilitado la autenticación multifactor. Por favor, introduce la contraseña RADIUS",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "Has habilitado autenticación multifactor, por favor ingresa el código TOTP",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "Has habilitado la autenticación multifactor. Por favor, introduce el código de verificación de la notificación push",
|
||||
"Your email is": "Tu correo electrónico es",
|
||||
"Your phone is": "Tu teléfono es",
|
||||
"preferred": "preferido"
|
||||
@@ -732,29 +751,30 @@
|
||||
"New Model": "Nuevo modelo"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "Hora de cancelación",
|
||||
"Edit Order": "Editar pedido",
|
||||
"New Order": "Nuevo pedido",
|
||||
"Order not found": "Pedido no encontrado",
|
||||
"Pay": "Pagar",
|
||||
"Payment failed time": "Hora del fallo de pago",
|
||||
"Payment time": "Hora de pago",
|
||||
"Price": "Precio",
|
||||
"Return to Order List": "Volver a la lista de pedidos",
|
||||
"Timeout time": "Hora de expiración",
|
||||
"View Order": "Ver pedido"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "Elementos de la cuenta",
|
||||
"Account items - Tooltip": "Elementos en la página de configuración personal",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Account menu": "Menú de cuenta",
|
||||
"Account menu - Tooltip": "Menú de cuenta - Tooltip",
|
||||
"Admin navbar items": "Elementos de la barra de navegación del administrador",
|
||||
"Admin navbar items - Tooltip": "Elementos de la barra de navegación del administrador - Tooltip",
|
||||
"All": "All",
|
||||
"Balance credit": "Saldo (créditos)",
|
||||
"Balance credit - Tooltip": "Saldo (créditos) - Tooltip",
|
||||
"Balance currency": "Moneda del saldo",
|
||||
"Balance currency - Tooltip": "Moneda del saldo - Tooltip",
|
||||
"Edit Organization": "Editar organización",
|
||||
"Follow global theme": "Seguir el tema global",
|
||||
"Has privilege consent": "Tiene consentimiento de privilegio",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "Modificar regla",
|
||||
"New Organization": "Nueva organización",
|
||||
"Optional": "Opcional",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "Saldo de la organización",
|
||||
"Org balance - Tooltip": "Saldo de la organización - Tooltip",
|
||||
"Password expire days": "Días de expiración de contraseña",
|
||||
"Password expire days - Tooltip": "Días de expiración de contraseña - Información adicional",
|
||||
"Prompt": "Sugerencia",
|
||||
@@ -778,14 +798,14 @@
|
||||
"Tags": "Etiquetas",
|
||||
"Use Email as username": "Usar correo electrónico como nombre de usuario",
|
||||
"Use Email as username - Tooltip": "Usar correo electrónico como nombre de usuario si el campo de nombre de usuario no es visible al registrarse",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User balance": "Saldo del usuario",
|
||||
"User balance - Tooltip": "Saldo del usuario - Tooltip",
|
||||
"User navbar items": "Elementos de la barra de navegación del usuario",
|
||||
"User navbar items - Tooltip": "Elementos de la barra de navegación del usuario - Tooltip",
|
||||
"User types": "Tipos de usuario",
|
||||
"User types - Tooltip": "Tipos de usuario - Información adicional",
|
||||
"View rule": "Regla de visualización",
|
||||
"Visible": "Visible - 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",
|
||||
"Widget items": "Elementos del widget",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Por favor, revise detenidamente la información de su factura. Una vez emitida la factura, no se puede retirar ni modificar.",
|
||||
"Please pay the order first!": "Por favor, pague el pedido primero",
|
||||
"Processing...": "Procesando...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "Productos - Tooltip",
|
||||
"Recharged successfully": "Recarga exitosa",
|
||||
"Result": "Resultado",
|
||||
"The payment has been canceled": "El pago ha sido cancelado",
|
||||
"The payment has failed": "El pago ha fallado",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "El pago ha expirado",
|
||||
"The payment is still under processing": "El pago aún está en proceso",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "Ver pago",
|
||||
"You can view your order details or return to the order list": "Puedes ver los detalles del pedido o volver a la lista de pedidos",
|
||||
"You have successfully completed the payment": "Has completado el pago exitosamente",
|
||||
"You have successfully recharged": "Has recargado exitosamente",
|
||||
"Your current balance is": "Tu saldo actual es",
|
||||
@@ -867,13 +887,15 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Editar plan",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "Nuevo plan",
|
||||
"Period": "Período",
|
||||
"Period - Tooltip": "Período",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "Nombre del plan",
|
||||
"Price - Tooltip": "Precio",
|
||||
"Related product": "Producto relacionado",
|
||||
"View Plan": "View Plan",
|
||||
"View Plan": "Ver plan",
|
||||
"per month": "por mes",
|
||||
"per year": "por año"
|
||||
},
|
||||
@@ -883,55 +905,62 @@
|
||||
"Free": "Gratis",
|
||||
"Getting started": "Empezar",
|
||||
"New Pricing": "Nuevo precio",
|
||||
"Pricing name": "Pricing name",
|
||||
"Pricing name": "Nombre de precios",
|
||||
"Trial duration": "Duración del período de prueba",
|
||||
"Trial duration - Tooltip": "Duración del período de prueba",
|
||||
"View Pricing": "View Pricing",
|
||||
"View Pricing": "Ver precios",
|
||||
"days trial available!": "días de prueba disponibles",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "El usuario de pago no tiene una suscripción activa o pendiente, por favor selecciona un plan para comprar"
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "Añadir al carrito",
|
||||
"AirWallex": "AirWallex",
|
||||
"Alipay": "Alipay",
|
||||
"Amount": "Amount",
|
||||
"Amount": "Importe",
|
||||
"Buy": "Comprar",
|
||||
"Buy Product": "Comprar producto",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Importe personalizado disponible",
|
||||
"Custom price should be greater than zero": "El precio personalizado debe ser mayor que cero",
|
||||
"Detail - Tooltip": "Detalle del producto",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Disable custom amount": "Desactivar importe personalizado",
|
||||
"Disable custom amount - Tooltip": "Desactivar importe personalizado - Tooltip",
|
||||
"Dummy": "Ficticio",
|
||||
"Edit Product": "Editar Producto",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
"Failed to create order": "Failed to create order",
|
||||
"Enter preset amounts": "Introducir importes predefinidos",
|
||||
"Failed to create order": "Error al crear el pedido",
|
||||
"Image": "Imagen",
|
||||
"Image - Tooltip": "Imagen del producto",
|
||||
"Information": "Information",
|
||||
"Information": "Información",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "Es recarga",
|
||||
"Is recharge - Tooltip": "Indica si el producto actual es para recargar saldo",
|
||||
"Name": "Name",
|
||||
"New Product": "Nuevo producto",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Pedido creado con éxito",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "Pago cancelado",
|
||||
"Payment failed": "Pago fallido",
|
||||
"Payment providers": "Proveedores de pago",
|
||||
"Payment providers - Tooltip": "Proveedores de servicios de pago",
|
||||
"Placing order...": "Haciendo un pedido...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Por favor, añade al menos una opción de recarga cuando el importe personalizado esté desactivado",
|
||||
"Please select a currency": "Por favor, selecciona una moneda",
|
||||
"Please select at least one payment provider": "Por favor, selecciona al menos un proveedor de pago",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Procesando el pago...",
|
||||
"Product list cannot be empty": "La lista de productos no puede estar vacía",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Cantidad",
|
||||
"Quantity - Tooltip": "Cantidad de producto",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge options": "Opciones de recarga",
|
||||
"Recharge options - Tooltip": "Opciones de recarga - Tooltip",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "URL de retorno",
|
||||
"Return URL - Tooltip": "URL para regresar después de una compra exitosa",
|
||||
"SKU": "SKU",
|
||||
"Select amount": "Select amount",
|
||||
"Select amount": "Seleccionar importe",
|
||||
"Sold": "Vendido",
|
||||
"Sold - Tooltip": "Cantidad vendida",
|
||||
"Stripe": "Stripe",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "URL para regresar después de la compra",
|
||||
"Tag - Tooltip": "Etiqueta de producto",
|
||||
"Test buy page..": "Página de compra de prueba.",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "La moneda del producto que estás añadiendo es diferente de la moneda de los artículos del carrito",
|
||||
"There is no payment channel for this product.": "No hay canal de pago para este producto.",
|
||||
"This product is currently not in sale.": "Este producto actualmente no está a la venta.",
|
||||
"This product is currently not purchasable (No options available)": "This product is currently not purchasable (No options available)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"This product is currently not purchasable (No options available)": "Este producto no se puede comprar actualmente (no hay opciones disponibles)",
|
||||
"Total Price": "Precio total",
|
||||
"View Product": "Ver producto",
|
||||
"WeChat Pay": "WeChat Pay"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Clave de autenticación para el servicio",
|
||||
"Auth URL": "URL de autenticación",
|
||||
"Auth URL - Tooltip": "URL para autenticación",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "URL base",
|
||||
"Base URL - Tooltip": "URL base del servicio",
|
||||
"Bucket": "Cubo",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "La segunda clave secreta del cliente",
|
||||
"Content": "Contenido",
|
||||
"Content - Tooltip": "Contenido - Información adicional",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "Desactivar SSL",
|
||||
"Disable SSL - Tooltip": "¿Hay que desactivar el protocolo SSL al comunicarse con el servidor STMP?",
|
||||
"DB test": "Prueba de BD",
|
||||
"DB test - Tooltip": "Prueba de BD - Tooltip",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Dominio",
|
||||
"Domain - Tooltip": "Dominio personalizado para almacenamiento de objetos",
|
||||
"Edit Provider": "Editar proveedor",
|
||||
@@ -1001,10 +1030,11 @@
|
||||
"Email regex - Tooltip": "Expresión regular de correo electrónico - Información adicional",
|
||||
"Email title": "Título del correo electrónico",
|
||||
"Email title - Tooltip": "Título del correo electrónico",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "Habilitar PKCE",
|
||||
"Enable PKCE - Tooltip": "Habilitar PKCE - Tooltip",
|
||||
"Enable proxy": "Habilitar proxy",
|
||||
"Enable proxy - Tooltip": "Habilitar proxy SOCKS5 al enviar correos o SMS",
|
||||
"Endpoint": "Punto final",
|
||||
"Endpoint (Intranet)": "Punto final (intranet)",
|
||||
"Endpoint - Tooltip": "Punto de acceso - Información adicional",
|
||||
@@ -1031,13 +1061,13 @@
|
||||
"Key ID - Tooltip": "ID de clave",
|
||||
"Key text": "Texto de clave",
|
||||
"Key text - Tooltip": "Texto de clave",
|
||||
"LDAP port": "LDAP port",
|
||||
"LDAP port": "Puerto LDAP",
|
||||
"Metadata": "Metadatos",
|
||||
"Metadata - Tooltip": "Metadatos SAML",
|
||||
"Metadata url": "URL de metadatos",
|
||||
"Metadata url - Tooltip": "URL de metadatos - Información adicional",
|
||||
"Method - Tooltip": "Método de inicio de sesión, código QR o inicio de sesión silencioso",
|
||||
"Mobile": "Mobile",
|
||||
"Mobile": "Móvil",
|
||||
"New Provider": "Nuevo proveedor",
|
||||
"Parameter": "Parámetro",
|
||||
"Parameter - Tooltip": "Parámetro - Información adicional",
|
||||
@@ -1055,10 +1085,10 @@
|
||||
"Prompted": "Estimulado",
|
||||
"Provider URL": "URL del proveedor",
|
||||
"Provider URL - Tooltip": "Dirección URL para configurar el proveedor de servicios, este campo sólo se utiliza como referencia y no se utiliza en Casdoor",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "Prueba del proveedor exitosa",
|
||||
"Public key": "Clave pública",
|
||||
"Public key - Tooltip": "Clave pública - Información adicional",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret of RADIUS",
|
||||
"RADIUS Shared Secret - Tooltip": "Secreto compartido de RADIUS",
|
||||
"Region": "Región",
|
||||
"Region - Tooltip": "Región - Información adicional",
|
||||
"Region ID": "ID de región",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "URL de ACS de SP",
|
||||
"SP ACS URL - Tooltip": "URL del ACS de SP",
|
||||
"SP Entity ID": "ID de entidad SP",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Escena",
|
||||
"Scene - Tooltip": "Escena",
|
||||
"Scope": "Alcance",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Clave de acceso secreta",
|
||||
"Secret access key - Tooltip": "Clave de acceso secreta",
|
||||
"Secret key": "Clave secreta",
|
||||
@@ -1111,8 +1144,8 @@
|
||||
"Sub type - Tooltip": "Subtipo",
|
||||
"Subject": "Asunto",
|
||||
"Subject - Tooltip": "Asunto del correo electrónico",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype": "Subtipo",
|
||||
"Subtype - Tooltip": "Subtipo - Tooltip",
|
||||
"Syncer test": "Prueba de sincronizador",
|
||||
"Syncer test - Tooltip": "Prueba de sincronizador",
|
||||
"Team ID": "ID del equipo",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "Prueba de conexión SMTP",
|
||||
"Third-party": "Terceros",
|
||||
"This field is required": "Este campo es obligatorio",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "Dirección del destinatario",
|
||||
"To address - Tooltip": "Dirección de correo del campo \"Para\"",
|
||||
"Token URL": "URL del token",
|
||||
"Token URL - Tooltip": "URL de token",
|
||||
"Use WeChat Media Platform in PC": "Usar plataforma de medios WeChat en PC",
|
||||
@@ -1160,7 +1193,7 @@
|
||||
"File name": "Nombre del archivo",
|
||||
"File size": "Tamaño de archivo",
|
||||
"Format": "Formato",
|
||||
"Parent": "Padre o madre (depending on the gender of the parent)",
|
||||
"Parent": "Padre",
|
||||
"Upload a file...": "Subir un archivo..."
|
||||
},
|
||||
"role": {
|
||||
@@ -1197,7 +1230,7 @@
|
||||
"Please input your last name!": "¡Por favor ingrese su apellido!",
|
||||
"Please input your phone number!": "¡Por favor, ingrese su número de teléfono!",
|
||||
"Please input your real name!": "¡Por favor, ingresa tu nombre real!",
|
||||
"Please input your {label}!": "Please input your {label}!",
|
||||
"Please input your {label}!": "¡Por favor, introduce tu {label}!",
|
||||
"Please select your country code!": "¡Por favor seleccione su código de país!",
|
||||
"Please select your country/region!": "¡Por favor seleccione su país/región!",
|
||||
"Regex": "Expresión regular",
|
||||
@@ -1210,7 +1243,7 @@
|
||||
"Text 4": "Texto 4",
|
||||
"Text 5": "Texto 5",
|
||||
"The input Email doesn't match the signup item regex!": "¡El correo electrónico ingresado no coincide con la expresión regular del elemento de registro!",
|
||||
"The input doesn't match the signup item regex!": "The input doesn't match the signup item regex!",
|
||||
"The input doesn't match the signup item regex!": "¡La entrada no coincide con la expresión regular del elemento de registro!",
|
||||
"The input is not invoice Tax ID!": "¡La entrada no es el ID fiscal de la factura!",
|
||||
"The input is not invoice title!": "¡El entrada no es el título de la factura!",
|
||||
"The input is not valid Phone!": "¡La entrada no es un número de teléfono válido!",
|
||||
@@ -1230,26 +1263,29 @@
|
||||
"New Subscription": "Nueva suscripción",
|
||||
"Start time": "Hora de inicio",
|
||||
"Start time - Tooltip": "Hora de inicio",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Subscription plan": "Plan de suscripción",
|
||||
"Subscription pricing": "Precios de suscripción",
|
||||
"Suspended": "Suspendido",
|
||||
"Upcoming": "Próximo",
|
||||
"View Subscription": "View Subscription"
|
||||
"View Subscription": "Ver suscripción"
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"Admin Email": "Admin Email",
|
||||
"API Token / Password": "Token API / Contraseña",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "Correo del administrador",
|
||||
"Affiliation table": "Tabla de afiliación",
|
||||
"Affiliation table - Tooltip": "Nombre de la tabla de base de datos de la unidad de trabajo",
|
||||
"Avatar base URL": "URL de la base de Avatar",
|
||||
"Avatar base URL - Tooltip": "Prefijo de URL para las imágenes de avatar",
|
||||
"Bind DN": "Bind DN",
|
||||
"Bind DN": "DN de enlace",
|
||||
"Casdoor column": "Columna de Casdoor",
|
||||
"Column name": "Nombre de la columna",
|
||||
"Column type": "Tipo de columna",
|
||||
"Connect successfully": "Conexión exitosa",
|
||||
"Corp ID": "Corp ID",
|
||||
"Corp secret": "Corp secret",
|
||||
"Corp ID": "ID corporativo",
|
||||
"Corp secret": "Secreto corporativo",
|
||||
"Database": "Base de datos",
|
||||
"Database - Tooltip": "El nombre original de la base de datos",
|
||||
"Database type": "Tipo de base de datos",
|
||||
@@ -1263,15 +1299,15 @@
|
||||
"Is read-only": "Es solo lectura",
|
||||
"Is read-only - Tooltip": "Es solo lectura - Información adicional",
|
||||
"New Syncer": "Nuevo Syncer",
|
||||
"Paste your Google Workspace service account JSON key here": "Paste your Google Workspace service account JSON key here",
|
||||
"SCIM Server URL": "SCIM Server URL",
|
||||
"Paste your Google Workspace service account JSON key here": "Pega aquí la clave JSON de la cuenta de servicio de Google Workspace",
|
||||
"SCIM Server URL": "URL del servidor SCIM",
|
||||
"SSH host": "Host SSH",
|
||||
"SSH password": "Contraseña SSH",
|
||||
"SSH port": "Puerto SSH",
|
||||
"SSH user": "Usuario SSH",
|
||||
"SSL mode": "Modo SSL",
|
||||
"SSL mode - Tooltip": "Modo SSL",
|
||||
"Service account key": "Service account key",
|
||||
"Service account key": "Clave de la cuenta de servicio",
|
||||
"Sync interval": "Intervalo de sincronización",
|
||||
"Sync interval - Tooltip": "Unidad en segundos",
|
||||
"Table": "Mesa",
|
||||
@@ -1279,8 +1315,8 @@
|
||||
"Table columns": "Columnas de tabla",
|
||||
"Table columns - Tooltip": "Columnas de la tabla involucradas en la sincronización de datos. Las columnas que no participan en la sincronización no necesitan ser agregadas",
|
||||
"Test Connection": "Probar conexión",
|
||||
"Test DB Connection": "Test DB Connection",
|
||||
"Username (optional)": "Username (optional)"
|
||||
"Test DB Connection": "Probar conexión de BD",
|
||||
"Username (optional)": "Nombre de usuario (opcional)"
|
||||
},
|
||||
"system": {
|
||||
"API Latency": "Retraso API",
|
||||
@@ -1311,16 +1347,16 @@
|
||||
"Theme - Tooltip": "Tema de estilo de la aplicación"
|
||||
},
|
||||
"ticket": {
|
||||
"Closed": "Closed",
|
||||
"Edit Ticket": "Edit Ticket",
|
||||
"In Progress": "In Progress",
|
||||
"Messages": "Messages",
|
||||
"New Ticket": "New Ticket",
|
||||
"Open": "Open",
|
||||
"Please enter a message": "Please enter a message",
|
||||
"Press Ctrl+Enter to send": "Press Ctrl+Enter to send",
|
||||
"Resolved": "Resolved",
|
||||
"Type your message here...": "Type your message here..."
|
||||
"Closed": "Cerrado",
|
||||
"Edit Ticket": "Editar ticket",
|
||||
"In Progress": "En progreso",
|
||||
"Messages": "Mensajes",
|
||||
"New Ticket": "Nuevo ticket",
|
||||
"Open": "Abierto",
|
||||
"Please enter a message": "Por favor, introduce un mensaje",
|
||||
"Press Ctrl+Enter to send": "Pulsa Ctrl+Enter para enviar",
|
||||
"Resolved": "Resuelto",
|
||||
"Type your message here...": "Escribe tu mensaje aquí..."
|
||||
},
|
||||
"token": {
|
||||
"Access token": "Token de acceso",
|
||||
@@ -1342,7 +1378,7 @@
|
||||
"Amount - Tooltip": "Cantidad de productos intercambiados",
|
||||
"Edit Transaction": "Editar transacción",
|
||||
"New Transaction": "Nueva transacción",
|
||||
"Recharge": "Recharge"
|
||||
"Recharge": "Recargar"
|
||||
},
|
||||
"user": {
|
||||
"3rd-party logins": "Inicio de sesión de terceros",
|
||||
@@ -1363,7 +1399,7 @@
|
||||
"Captcha Verify Success": "Verificación de Captcha Exitosa",
|
||||
"City": "Ciudad",
|
||||
"Country code": "Código de país",
|
||||
"Country code - Tooltip": "Country code - Tooltip",
|
||||
"Country code - Tooltip": "Código de país - Tooltip",
|
||||
"Country/Region": "País/Región",
|
||||
"Country/Region - Tooltip": "País o región",
|
||||
"Edit User": "Editar usuario",
|
||||
@@ -1372,7 +1408,7 @@
|
||||
"Email cannot be empty": "El correo electrónico no puede estar vacío",
|
||||
"Email/phone reset successfully": "Restablecimiento de correo electrónico/teléfono exitoso",
|
||||
"Empty input!": "¡Entrada vacía!",
|
||||
"Face IDs": "Face IDs",
|
||||
"Face IDs": "IDs de Face",
|
||||
"Gender": "Género",
|
||||
"Gender - Tooltip": "Género - Información adicional",
|
||||
"Homepage": "Página de inicio del usuario",
|
||||
@@ -1386,10 +1422,10 @@
|
||||
"ID card type": "Tipo de carnet",
|
||||
"ID card type - Tooltip": "Tipo de carnet - Información adicional",
|
||||
"ID card with person": "Carnet con persona",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"ID verification": "Verificación de identidad",
|
||||
"ID verification - Tooltip": "Verificación de identidad - Tooltip",
|
||||
"Identity verification successful": "Verificación de identidad exitosa",
|
||||
"Identity verified": "Identidad verificada",
|
||||
"Input your email": "Introduce tu correo electrónico",
|
||||
"Input your phone number": "Ingrese su número de teléfono",
|
||||
"Is admin": "Es el administrador",
|
||||
@@ -1399,7 +1435,7 @@
|
||||
"Is forbidden": "está prohibido",
|
||||
"Is forbidden - Tooltip": "Los usuarios bloqueados ya no pueden iniciar sesión",
|
||||
"Is online": "Está en línea",
|
||||
"Is verified": "Is verified",
|
||||
"Is verified": "Está verificado",
|
||||
"Karma": "Karma",
|
||||
"Karma - Tooltip": "Karma - Información adicional",
|
||||
"Keys": "Claves",
|
||||
@@ -1424,16 +1460,16 @@
|
||||
"Other": "Otro",
|
||||
"Password set successfully": "Contraseña establecida exitosamente",
|
||||
"Phone cannot be empty": "El teléfono no puede estar vacío",
|
||||
"Please enter your real name": "Please enter your real name",
|
||||
"Please fill in ID card information first": "Please fill in ID card information first",
|
||||
"Please fill in your real name first": "Please fill in your real name first",
|
||||
"Please enter your real name": "Por favor, introduce tu nombre real",
|
||||
"Please fill in ID card information first": "Por favor, completa primero la información del documento de identidad",
|
||||
"Please fill in your real name first": "Por favor, completa primero tu nombre real",
|
||||
"Please select avatar from resources": "Por favor, selecciona un avatar de los recursos disponibles",
|
||||
"Properties": "Propiedades",
|
||||
"Properties - Tooltip": "Propiedades del usuario",
|
||||
"Ranking": "Clasificación",
|
||||
"Ranking - Tooltip": "Clasificación - Información adicional",
|
||||
"Re-enter New": "Volver a ingresar Nueva",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Real name - Tooltip": "Nombre real - Tooltip",
|
||||
"Register source": "Fuente de registro",
|
||||
"Register source - Tooltip": "La fuente desde la cual se registró el usuario",
|
||||
"Register type": "Tipo de registro",
|
||||
@@ -1462,8 +1498,8 @@
|
||||
"User Profile": "Perfil de usuario",
|
||||
"Values": "Valores",
|
||||
"Verification code sent": "Código de verificación enviado",
|
||||
"Verified": "Verified",
|
||||
"Verify Identity": "Verify Identity",
|
||||
"Verified": "Verificado",
|
||||
"Verify Identity": "Verificar identidad",
|
||||
"WebAuthn credentials": "Credenciales de WebAuthn",
|
||||
"Work": "Trabajo",
|
||||
"You have changed the username, please save your change first before modifying the password": "Has cambiado el nombre de usuario, por favor guarda el cambio antes de modificar la contraseña",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "Quitter l'usurpation",
|
||||
"Logout": "Déconnexion",
|
||||
"My Account": "Mon Compte",
|
||||
"Sign Up": "S'inscrire"
|
||||
@@ -22,22 +22,22 @@
|
||||
"Add Face ID with Image": "Ajouter Face ID avec image",
|
||||
"Always": "Toujours",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Authentication": "Authentification",
|
||||
"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": "URL de fond mobile",
|
||||
"Background URL Mobile - Tooltip": "URL de l'image d'arrière-plan pour les appareils mobiles",
|
||||
"Basic": "Basic",
|
||||
"Basic": "Basique",
|
||||
"Big icon": "Grande icône",
|
||||
"Binding providers": "Fournisseurs de liaison",
|
||||
"CSS style": "Style CSS",
|
||||
"Center": "Centré",
|
||||
"Code resend timeout": "Délai de renvoi du code",
|
||||
"Code resend timeout - Tooltip": "Période (en secondes) pendant laquelle les utilisateurs doivent attendre avant de demander un autre code de vérification. Définir à 0 pour utiliser la valeur par défaut globale (60 secondes)",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Expiration du cookie",
|
||||
"Cookie expire - Tooltip": "Durée de validité du cookie - Info-bulle",
|
||||
"Copy SAML metadata URL": "Copiez l'URL de métadonnées SAML",
|
||||
"Copy prompt page URL": "Copier l'URL de la page de l'invite",
|
||||
"Copy signin page URL": "Copier l'URL de la page de connexion",
|
||||
@@ -47,9 +47,9 @@
|
||||
"Custom CSS - Tooltip": "Mise en forme CSS des formulaires d'inscription, de connexion et de récupération de mot de passe (par exemple, en ajoutant des bordures et des ombres)",
|
||||
"Custom CSS Mobile": "CSS personnalisé mobile",
|
||||
"Custom CSS Mobile - Edit": "CSS personnalisé mobile - Modifier",
|
||||
"Custom CSS Mobile - Tooltip": "CSS personnalisé pour les appareils mobiles",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Custom CSS Mobile - Tooltip": "CSS personnalisé pour les appareils mobiles - Info-bulle",
|
||||
"Disable SAML attributes": "Désactiver les attributs SAML",
|
||||
"Disable SAML attributes - Tooltip": "Désactiver les attributs SAML - Info-bulle",
|
||||
"Disable signin": "Désactiver la connexion",
|
||||
"Disable signin - Tooltip": "Désactiver la connexion pour les utilisateurs",
|
||||
"Dynamic": "Dynamique",
|
||||
@@ -60,16 +60,17 @@
|
||||
"Enable SAML C14N10 - Tooltip": "Utiliser C14N10 au lieu de C14N11 dans SAML",
|
||||
"Enable SAML POST binding": "Activer la liaison POST SAML",
|
||||
"Enable SAML POST binding - Tooltip": "La liaison POST HTTP utilise des champs de formulaire HTML pour envoyer des messages SAML, activez-la si votre SP l'utilise",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "Activer la signature d'assertion SAML",
|
||||
"Enable SAML assertion signature - Tooltip": "Activer la signature d'assertion SAML - Info-bulle",
|
||||
"Enable SAML compression": "Activer la compression SAML",
|
||||
"Enable SAML compression - Tooltip": "Compresser ou non les messages de réponse SAML lorsque Casdoor est utilisé en tant que fournisseur d'identité SAML",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "Activer la connexion exclusive",
|
||||
"Enable exclusive signin - Tooltip": "Lorsque la connexion exclusive est activée, l'utilisateur ne peut pas avoir plusieurs sessions actives",
|
||||
"Enable side panel": "Activer le panneau latéral",
|
||||
"Enable signin session - Tooltip": "Conserver une session après la connexion à Casdoor à partir de l'application",
|
||||
"Enable signup": "Activer l'inscription",
|
||||
"Enable signup - Tooltip": "Autoriser la création de nouveaux comptes",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Temps de blocage après échec de connexion",
|
||||
"Failed signin frozen time - Tooltip": "Durée pendant laquelle le compte est gelé après des tentatives de connexion échouées",
|
||||
"Failed signin limit": "Limite d'échecs de connexion",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "Déconnexion réussie",
|
||||
"MFA remember time": "Durée de mémorisation MFA",
|
||||
"MFA remember time - Tooltip": "Configure la durée pendant laquelle un compte est mémorisé comme fiable après une connexion MFA réussie",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "Mode du menu",
|
||||
"Menu mode - Tooltip": "Mode du menu - Info-bulle",
|
||||
"Multiple Choices": "Choix multiples",
|
||||
"New Application": "Nouvelle application",
|
||||
"No verification": "Aucune vérification",
|
||||
@@ -111,48 +112,59 @@
|
||||
"Order": "Ordre",
|
||||
"Order - Tooltip": "Plus la valeur est petite, plus elle est classée haut dans la page Applications",
|
||||
"Org choice mode": "Mode de choix d'organisation",
|
||||
"Org choice mode - Tooltip": "Mode de choix d'organisation",
|
||||
"Org choice mode - Tooltip": "Méthode utilisée pour sélectionner l'organisation pour se connecter - Info-bulle",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Veuillez activer \"Session de connexion\" avant d'activer \"Connexion automatique\"",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "Veuillez saisir votre application !",
|
||||
"Please input your organization!": "Veuillez saisir votre organisation !",
|
||||
"Please select a HTML file": "Veuillez sélectionner un fichier HTML",
|
||||
"Pop up": "Fenêtre contextuelle",
|
||||
"Providers": "Providers",
|
||||
"Providers": "Fournisseurs",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "Aléatoire",
|
||||
"Real name": "Nom réel",
|
||||
"Redirect URL": "URL de redirection",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redirection (Assertion Consumer Service POST Binding URL)",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redirection (Assertion Consumer Service POST Binding URL) - Info-bulle",
|
||||
"Redirect URLs": "URLs de redirection",
|
||||
"Redirect URLs - Tooltip": "Liste des URL de redirection autorisées, les expressions régulières sont supportées ; les URL n'étant pas dans la liste ne seront pas redirigées",
|
||||
"Refresh token expire": "Expiration du jeton de rafraîchissement",
|
||||
"Refresh token expire - Tooltip": "Durée avant expiration du jeton de rafraîchissement",
|
||||
"Reset to Empty": "Réinitialiser à vide",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "Droit",
|
||||
"Rule": "Règle",
|
||||
"SAML hash algorithm": "Algorithme de hachage SAML",
|
||||
"SAML hash algorithm - Tooltip": "Algorithme de hachage pour la signature SAML",
|
||||
"SAML hash algorithm - Tooltip": "Algorithme de hachage pour la signature SAML - Info-bulle",
|
||||
"SAML metadata": "Métadonnées SAML",
|
||||
"SAML metadata - Tooltip": "Les métadonnées du protocole SAML",
|
||||
"SAML metadata - Tooltip": "Métadonnées du protocole SAML - Info-bulle",
|
||||
"SAML reply URL": "URL de réponse SAML",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "Sécurité",
|
||||
"Select": "Sélectionner",
|
||||
"Side panel HTML": "HTML du panneau latéral",
|
||||
"Side panel HTML - Edit": "HTML du panneau latéral - Modifier",
|
||||
"Side panel HTML - Tooltip": "Personnalisez le code HTML du panneau latéral de la page de connexion",
|
||||
"Side panel HTML - Tooltip": "Personnaliser le code HTML du panneau latéral de la page de connexion - Info-bulle",
|
||||
"Sign Up Error": "Erreur d'inscription",
|
||||
"Signin": "Se connecter",
|
||||
"Signin (Default True)": "Connexion (Vrai par défaut)",
|
||||
"Signin items": "Éléments de connexion",
|
||||
"Signin items - Tooltip": "Éléments de connexion",
|
||||
"Signin items - Tooltip": "Éléments de connexion - Info-bulle",
|
||||
"Signin methods": "Méthodes de connexion",
|
||||
"Signin methods - Tooltip": "Méthodes de connexion - Infobulle",
|
||||
"Signin session": "Session de connexion",
|
||||
"Signup items": "Champs d'inscription",
|
||||
"Signup items - Tooltip": "Champs à remplir lors de l'enregistrement de nouveaux comptes",
|
||||
"Signup items - Tooltip": "Éléments à remplir par les utilisateurs lors de la création de nouveaux comptes - Info-bulle",
|
||||
"Single Choice": "Choix unique",
|
||||
"Small icon": "Petite icône",
|
||||
"Static Value": "Static Value",
|
||||
"String": "String",
|
||||
"Tags - Tooltip": "Seuls les utilisateurs avec le tag listé dans les tags de l'application peuvent se connecter",
|
||||
"Tags - Tooltip": "Seuls les utilisateurs avec le tag listé dans les tags de l'application peuvent se connecter - Info-bulle",
|
||||
"The application does not allow to sign up new account": "L'application ne permet pas de créer un nouveau compte",
|
||||
"Token expire": "Expiration du jeton",
|
||||
"Token expire - Tooltip": "Durée avant expiration du jeton d'accès",
|
||||
@@ -162,7 +174,9 @@
|
||||
"Token format - Tooltip": "Le format du jeton d'accès",
|
||||
"Token signing method": "Méthode de signature du jeton",
|
||||
"Token signing method - Tooltip": "Méthode de signature du jeton JWT, doit être le même algorithme que le certificat",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "Personnalisation de l'interface",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "Utiliser l'e-mail comme NameID",
|
||||
"Use Email as NameID - Tooltip": "Utiliser l'e-mail comme NameID - Infobulle",
|
||||
"Vertical": "Vertical",
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "Largeur"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "Un utilisateur normal ne peut modifier que l'autorisation qu'il a lui-même soumise",
|
||||
"AI Assistant": "Assistant IA",
|
||||
"API key": "Clé API",
|
||||
"API key - Tooltip": "Clé API pour accéder au service",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "Entreprise et paiements",
|
||||
"Cancel": "Annuler",
|
||||
"Captcha": "Captcha",
|
||||
"Cart": "Cart",
|
||||
"Cart": "Panier",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "Certificat",
|
||||
"Cert - Tooltip": "La clé publique du certificat qui doit être vérifiée par le kit de développement client correspondant à cette application",
|
||||
"Certs": "Certificats",
|
||||
"Clear": "Clear",
|
||||
"Clear": "Effacer",
|
||||
"Click to Upload": "Cliquer pour télécharger",
|
||||
"Client IP": "IP client",
|
||||
"Close": "Fermer",
|
||||
@@ -307,12 +323,12 @@
|
||||
"Delete": "Supprimer",
|
||||
"Description": "Description",
|
||||
"Description - Tooltip": "Description détaillée pour référence, Casdoor ne l'utilisera pas en soi",
|
||||
"Detail": "详情",
|
||||
"Detail": "Détail",
|
||||
"Disable": "Désactiver",
|
||||
"Display name": "Nom d'affichage",
|
||||
"Display name - Tooltip": "Un nom convivial et facilement lisible affiché publiquement dans l'interface utilisateur",
|
||||
"Down": "Descendre",
|
||||
"Download template": "Download template",
|
||||
"Download template": "Télécharger le modèle",
|
||||
"Edit": "Modifier",
|
||||
"Email": "E-mail",
|
||||
"Email - Tooltip": "Adresse e-mail valide",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "Activé avec succès",
|
||||
"Enforcers": "Agents",
|
||||
"Failed to add": "Échec d'ajout",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "Échec de l'annulation",
|
||||
"Failed to connect to server": "Échec de la connexion au serveur",
|
||||
"Failed to copy": "Échec de la copie",
|
||||
"Failed to delete": "Échec de la suppression",
|
||||
"Failed to enable": "Échec de l'activation",
|
||||
"Failed to get": "Échec de la récupération",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "Échec du chargement",
|
||||
"Failed to log out": "Échec de la déconnexion",
|
||||
"Failed to remove": "Échec de la suppression",
|
||||
"Failed to save": "Échec de sauvegarde",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "Échec de l'envoi",
|
||||
"Failed to sync": "Échec de la synchronisation",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "Échec de la dissociation",
|
||||
"Failed to update": "Échec de la mise à jour",
|
||||
"Failed to upload": "Échec du téléchargement",
|
||||
"Failed to verify": "Échec de la vérification",
|
||||
"False": "Faux",
|
||||
"Favicon": "Favicon",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "URL personnalisée pour la page \"Mot de passe oublié\". Si elle n'est pas définie, la page par défaut \"Mot de passe oublié\" de Casdoor sera utilisée. Lorsqu'elle est définie, le lien \"Mot de passe oublié\" sur la page de connexion sera redirigé vers cette URL",
|
||||
"Forms": "Formulaires",
|
||||
"Found some texts still not translated? Please help us translate at": "Trouvé des textes encore non traduits ? Veuillez nous aider à les traduire sur",
|
||||
"Generate": "Generate",
|
||||
"Generate": "Générer",
|
||||
"Go to enable": "Aller activer",
|
||||
"Go to writable demo site?": "Allez sur le site de démonstration modifiable ?",
|
||||
"Groups": "Groupes",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "Liste blanche IP",
|
||||
"IP whitelist - Tooltip": "Liste blanche IP",
|
||||
"Identity": "Identité",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "Usurpation",
|
||||
"Invitations": "Invitations",
|
||||
"Is enabled": "Est activé",
|
||||
"Is enabled - Tooltip": "Définir s'il peut être utilisé",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "Nom",
|
||||
"Name - Tooltip": "Identifiant unique à base de chaîne",
|
||||
"Name format": "Format du nom",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "Aucun produit disponible",
|
||||
"No sheets found in file": "Aucune feuille trouvée dans le fichier",
|
||||
"No verification method": "Aucune méthode de vérification",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "Aucun",
|
||||
"OAuth providers": "Fournisseurs OAuth",
|
||||
"OFF": "DÉSACTIVÉ",
|
||||
"OK": "OK",
|
||||
"ON": "ACTIVÉ",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "Une seule méthode MFA peut être requise",
|
||||
"Or": "Ou",
|
||||
"Orders": "Commandes",
|
||||
"Organization": "Organisation",
|
||||
"Organization - Tooltip": "Similaire à des concepts tels que les locataires (tenants) ou les groupes de compte, chaque compte et application appartient à une organisation",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "L'organisation est nulle",
|
||||
"Organizations": "Organisations",
|
||||
"Password": "Mot de passe",
|
||||
"Password - Tooltip": "Assurez-vous que le mot de passe soit correct",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "Numéro de téléphone",
|
||||
"Phone only": "Téléphone uniquement",
|
||||
"Phone or Email": "Téléphone ou e-mail",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "Passer la commande",
|
||||
"Plain": "Simple",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan d'abonnement",
|
||||
"Plans": "Offres",
|
||||
"Plans - Tooltip": "Plans - Infobulle",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "Veuillez compléter correctement le captcha",
|
||||
"Please input your search": "Veuillez saisir votre recherche",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "Veuillez d'abord sélectionner au moins 1 utilisateur",
|
||||
"Preview": "Aperçu",
|
||||
"Preview - Tooltip": "Prévisualisation des effets configurés",
|
||||
"Pricing": "Tarification",
|
||||
"Pricing - Tooltip": "Tarification - Infobulle",
|
||||
"Pricings": "Tarifs",
|
||||
"Product Store": "Product Store",
|
||||
"Product Store": "Boutique de produits",
|
||||
"Products": "Produits",
|
||||
"Provider": "Fournisseur",
|
||||
"Provider - Tooltip": "Les fournisseurs de paiement à configurer, tels que PayPal, Alipay, WeChat Pay, etc.",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "Type d'authentification de connexion SSH",
|
||||
"Save": "Enregistrer",
|
||||
"Save & Exit": "Enregistrer et quitter",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Rechercher",
|
||||
"Send": "Envoyer",
|
||||
"Session ID": "Identifiant de session",
|
||||
@@ -493,13 +511,13 @@
|
||||
"Sorry, you do not have permission to access this page or logged in status invalid.": "Désolé, vous n'avez pas la permission d'accéder à cette page ou votre statut de connexion est invalide.",
|
||||
"State": "État",
|
||||
"State - Tooltip": "État",
|
||||
"Status": "Status",
|
||||
"Status": "Statut",
|
||||
"Subscriptions": "Abonnements",
|
||||
"Successfully added": "Ajouté avec succès",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "Annulé avec succès",
|
||||
"Successfully copied": "Copié avec succès",
|
||||
"Successfully deleted": "Supprimé avec succès",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "Exécuté avec succès",
|
||||
"Successfully removed": "Supprimé avec succès",
|
||||
"Successfully saved": "Enregistré avec succès",
|
||||
"Successfully sent": "Envoyé avec succès",
|
||||
@@ -514,9 +532,9 @@
|
||||
"Syncers": "Synchroniseurs",
|
||||
"System Info": "Informations système",
|
||||
"Tab": "Onglet",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "Les actions ne peuvent pas être vides",
|
||||
"The resources cannot be empty": "Les ressources ne peuvent pas être vides",
|
||||
"The users and roles cannot be empty at the same time": "Les utilisateurs et les rôles ne peuvent pas être vides en même temps",
|
||||
"There was a problem signing you in..": "Un problème est survenu lors de votre connexion..",
|
||||
"This is a read-only demo site!": "Ceci est un site de démonstration en lecture seule !",
|
||||
"Tickets": "Tickets",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "Transactions",
|
||||
"True": "Vrai",
|
||||
"Type": "Type",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "Lien de l'URL",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "Nom d'application inconnu",
|
||||
"Unknown authentication type": "Type d'authentification inconnu",
|
||||
"Up": "Monter",
|
||||
"Updated time": "Heure de mise à jour",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"Upload (.xlsx)": "Télécharger (.xlsx)",
|
||||
"User": "Compte",
|
||||
"User - Tooltip": "Assurez-vous que l'identifiant est correct",
|
||||
"User Management": "Gestion des utilisateurs",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "L'utilisateur existe déjà",
|
||||
"User containers": "Groupe de comptes",
|
||||
"User type": "Type de compte",
|
||||
"User type - Tooltip": "Étiquettes associées au compte, avec une valeur par défaut \"normal-user\"",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "Utilisateurs - Infobulle",
|
||||
"Users under all organizations": "Comptes sous toutes les organisations",
|
||||
"Verifications": "Vérifications",
|
||||
"View": "View",
|
||||
"View": "Voir",
|
||||
"Webhooks": "Webhooks",
|
||||
"You can only select one physical group": "Vous ne pouvez sélectionner qu'un seul groupe physique",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "Vous devez d'abord sélectionner une image",
|
||||
"empty": "vide",
|
||||
"remove": "supprimer",
|
||||
"{total} in total": "{total} au total"
|
||||
@@ -626,7 +645,7 @@
|
||||
"login": {
|
||||
"Auto sign in": "Connexion automatique",
|
||||
"Back button": "Bouton retour",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "Cliquez sur le bouton ci-dessous pour vous connecter avec Telegram",
|
||||
"Continue with": "Continuer avec",
|
||||
"Email or phone": "Email ou téléphone",
|
||||
"Face ID": "Face ID",
|
||||
@@ -649,12 +668,12 @@
|
||||
"Please input your Email!": "Veuillez entrer votre e-mail !",
|
||||
"Please input your LDAP username!": "Veuillez entrer votre nom d'utilisateur LDAP !",
|
||||
"Please input your Phone!": "Veuillez entrer votre téléphone !",
|
||||
"Please input your RADIUS password!": "Please input your RADIUS password!",
|
||||
"Please input your RADIUS username!": "Please input your RADIUS username!",
|
||||
"Please input your RADIUS password!": "Veuillez saisir votre mot de passe RADIUS !",
|
||||
"Please input your RADIUS username!": "Veuillez saisir votre identifiant RADIUS !",
|
||||
"Please input your code!": "Veuillez saisir votre code !",
|
||||
"Please input your organization name!": "Veuillez entrer le nom de votre organisation !",
|
||||
"Please input your password!": "Veuillez saisir votre mot de passe !",
|
||||
"Please input your push notification receiver!": "Please input your push notification receiver!",
|
||||
"Please input your push notification receiver!": "Veuillez saisir le destinataire de la notification push !",
|
||||
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Veuillez charger la page web en HTTPS, sinon l'appareil photo ne peut pas être accessible",
|
||||
"Please provide permission to access the camera": "Veuillez autoriser l'accès à l'appareil photo",
|
||||
"Please select an organization": "Veuillez sélectionner une organisation",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "Sélectionner l'organisation",
|
||||
"Sign In": "Se connecter",
|
||||
"Sign in with Face ID": "Se connecter avec Face ID",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "Se connecter avec Telegram",
|
||||
"Sign in with WebAuthn": "Connectez-vous avec WebAuthn",
|
||||
"Sign in with {type}": "Connectez-vous avec {type}",
|
||||
"Signin button": "Bouton de connexion",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "Veuillez confirmer les informations ci-dessous",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "Veuillez enregistrer ce code de récupération. Si votre appareil ne peut pas fournir de code d'authentification, vous pouvez réinitialiser l'authentification MFA avec ce code",
|
||||
"Protect your account with Multi-factor authentication": "Protégez votre compte avec l'authentification multi-facteur",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "Destinataire de la notification push",
|
||||
"Recovery code": "Code de récupération",
|
||||
"Remember this account for {hour} hours": "Se souvenir de ce compte pendant {hour} heures",
|
||||
"Scan the QR code with your Authenticator App": "Scannez le code QR avec votre application d'authentification",
|
||||
@@ -708,17 +727,17 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "Pour assurer la sécurité de votre compte, l'authentification multi-facteur est requise",
|
||||
"Use Authenticator App": "Utiliser l'application d'authentification",
|
||||
"Use Email": "Utiliser l'e-mail",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "Utiliser la notification push",
|
||||
"Use Radius": "Utiliser RADIUS",
|
||||
"Use SMS": "Utiliser SMS",
|
||||
"Use SMS verification code": "Utiliser le code de vérification SMS",
|
||||
"Use a recovery code": "Utiliser un code de récupération",
|
||||
"Verify Code": "Vérifier le code",
|
||||
"Verify Password": "Vérifier le mot de passe",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "Vous avez activé l'authentification multi-facteur, veuillez cliquer sur 'Envoyer le code' pour continuer",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "Vous avez activé l'authentification multi-facteur. Veuillez saisir le mot de passe RADIUS",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "Vous avez activé l'authentification multi-facteur, veuillez entrer le code TOTP",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "Vous avez activé l'authentification multi-facteur. Veuillez saisir le code de vérification de la notification push",
|
||||
"Your email is": "Votre e-mail est",
|
||||
"Your phone is": "Votre téléphone est",
|
||||
"preferred": "préféré"
|
||||
@@ -732,29 +751,30 @@
|
||||
"New Model": "Nouveau modèle"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "Heure d'annulation",
|
||||
"Edit Order": "Modifier la commande",
|
||||
"New Order": "Nouvelle commande",
|
||||
"Order not found": "Commande introuvable",
|
||||
"Pay": "Payer",
|
||||
"Payment failed time": "Heure de l'échec de paiement",
|
||||
"Payment time": "Heure du paiement",
|
||||
"Price": "Prix",
|
||||
"Return to Order List": "Retourner à la liste des commandes",
|
||||
"Timeout time": "Heure d'expiration",
|
||||
"View Order": "Voir la commande"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "Champs du compte",
|
||||
"Account items - Tooltip": "Champs de la page des paramètres personnels",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Account menu": "Menu du compte",
|
||||
"Account menu - Tooltip": "Menu du compte - Infobulle",
|
||||
"Admin navbar items": "Éléments de la barre de navigation admin",
|
||||
"Admin navbar items - Tooltip": "Éléments de la barre de navigation admin - Infobulle",
|
||||
"All": "All",
|
||||
"Balance credit": "Solde (crédits)",
|
||||
"Balance credit - Tooltip": "Solde (crédits) - Infobulle",
|
||||
"Balance currency": "Devise du solde",
|
||||
"Balance currency - Tooltip": "Devise du solde - Infobulle",
|
||||
"Edit Organization": "Modifier l'organisation",
|
||||
"Follow global theme": "Suivre le thème global",
|
||||
"Has privilege consent": "A le consentement des privilèges",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "Règle de modification",
|
||||
"New Organization": "Nouvelle organisation",
|
||||
"Optional": "Optionnel",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "Solde de l'organisation",
|
||||
"Org balance - Tooltip": "Solde de l'organisation - Infobulle",
|
||||
"Password expire days": "Jours d'expiration du mot de passe",
|
||||
"Password expire days - Tooltip": "Jours d'expiration du mot de passe - Infobulle",
|
||||
"Prompt": "Invite",
|
||||
@@ -776,15 +796,15 @@
|
||||
"Soft deletion": "Suppression douce",
|
||||
"Soft deletion - Tooltip": "Lorsque c'est activée, la suppression de compte ne les retirera pas complètement de la base de données. Au lieu de cela, ils seront marqués comme supprimés",
|
||||
"Tags": "Étiquettes",
|
||||
"Use Email as username": "Utiliser l'e-mail comme nom d'utilisateur",
|
||||
"Use Email as username - Tooltip": "Utiliser l'e-mail comme nom d'utilisateur si le champ nom d'utilisateur n'est pas visible à l'inscription",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User types": "Types d'utilisateurs",
|
||||
"User types - Tooltip": "Types d'utilisateurs - Infobulle",
|
||||
"View rule": "Règle de visibilité",
|
||||
"Use Email as username": "Utiliser l'e-mail comme identifiant",
|
||||
"Use Email as username - Tooltip": "Utiliser l'e-mail comme identifiant si le champ identifiant est masqué lors de l'inscription",
|
||||
"User balance": "Solde de l'utilisateur",
|
||||
"User balance - Tooltip": "Solde de l'utilisateur - Infobulle",
|
||||
"User navbar items": "Éléments de la barre de navigation utilisateur",
|
||||
"User navbar items - Tooltip": "Éléments de la barre de navigation utilisateur - Infobulle",
|
||||
"User types": "Types de compte",
|
||||
"User types - Tooltip": "Types d'utilisateur - Infobulle",
|
||||
"View rule": "Règle d'affichage",
|
||||
"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",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Veuillez vérifier attentivement les informations de votre facture. Une fois émise, la facture ne peut pas être retirée ou modifiée.",
|
||||
"Please pay the order first!": "Veuillez d'abord payer la commande !",
|
||||
"Processing...": "Traitement...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "Produits - Infobulle",
|
||||
"Recharged successfully": "Rechargé avec succès",
|
||||
"Result": "Résultat",
|
||||
"The payment has been canceled": "Le paiement a été annulé",
|
||||
"The payment has failed": "Le paiement a échoué",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "Le paiement a expiré",
|
||||
"The payment is still under processing": "Le paiement est encore en cours de traitement",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "Voir le paiement",
|
||||
"You can view your order details or return to the order list": "Vous pouvez consulter les détails de la commande ou retourner à la liste des commandes",
|
||||
"You have successfully completed the payment": "Vous avez effectué le paiement avec succès",
|
||||
"You have successfully recharged": "Vous avez rechargé avec succès",
|
||||
"Your current balance is": "Votre solde actuel est",
|
||||
@@ -843,7 +863,7 @@
|
||||
},
|
||||
"permission": {
|
||||
"Actions": "Actions",
|
||||
"Actions - Tooltip": "Actions autorisées",
|
||||
"Actions - Tooltip": "Actions autorisées - Infobulle",
|
||||
"Allow": "Permettre",
|
||||
"Approve time": "Date d'approbation",
|
||||
"Approve time - Tooltip": "La date d'approbation pour cette permission",
|
||||
@@ -859,7 +879,7 @@
|
||||
"Read": "Lire",
|
||||
"Resource type": "Type de ressource",
|
||||
"Resource type - Tooltip": "Type de ressource",
|
||||
"Resources - Tooltip": "Ressources autorisées",
|
||||
"Resources - Tooltip": "Ressources autorisées - Infobulle",
|
||||
"Submitter": "Soumetteur",
|
||||
"Submitter - Tooltip": "La personne demandant cette permission",
|
||||
"TreeNode": "Nœud d'arbre",
|
||||
@@ -867,13 +887,15 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Modifier le plan",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "Nouveau plan",
|
||||
"Period": "Période",
|
||||
"Period - Tooltip": "Période",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "Nom du plan",
|
||||
"Price - Tooltip": "Prix",
|
||||
"Related product": "Produit associé",
|
||||
"View Plan": "View Plan",
|
||||
"View Plan": "Voir le plan",
|
||||
"per month": "par mois",
|
||||
"per year": "par an"
|
||||
},
|
||||
@@ -883,55 +905,62 @@
|
||||
"Free": "Gratuit",
|
||||
"Getting started": "Commencer",
|
||||
"New Pricing": "Nouvelle tarification",
|
||||
"Pricing name": "Pricing name",
|
||||
"Pricing name": "Nom de la tarification",
|
||||
"Trial duration": "Durée de l'essai",
|
||||
"Trial duration - Tooltip": "Durée de la période d'essai",
|
||||
"View Pricing": "View Pricing",
|
||||
"View Pricing": "Voir la tarification",
|
||||
"days trial available!": "jours d'essai disponibles !",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "L'utilisateur payant n'a pas d'abonnement actif ou en attente, veuillez sélectionner un plan à acheter"
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "Ajouter au panier",
|
||||
"AirWallex": "AirWallex",
|
||||
"Alipay": "Alipay",
|
||||
"Amount": "Amount",
|
||||
"Amount": "Montant",
|
||||
"Buy": "Acheter",
|
||||
"Buy Product": "Acheter un produit",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Detail - Tooltip": "Détail du produit",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Montant personnalisé disponible",
|
||||
"Custom price should be greater than zero": "Le prix personnalisé doit être supérieur à zéro",
|
||||
"Detail - Tooltip": "Détail du produit - Infobulle",
|
||||
"Disable custom amount": "Désactiver le montant personnalisé",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Dummy": "Factice",
|
||||
"Edit Product": "Modifier le produit",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
"Failed to create order": "Failed to create order",
|
||||
"Enter preset amounts": "Saisir des montants prédéfinis",
|
||||
"Failed to create order": "Échec de la création de la commande",
|
||||
"Image": "Image",
|
||||
"Image - Tooltip": "Image du produit",
|
||||
"Information": "Information",
|
||||
"Information": "Informations",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "Est un rechargement",
|
||||
"Is recharge - Tooltip": "Indique si le produit actuel permet de recharger le solde",
|
||||
"Name": "Name",
|
||||
"New Product": "Nouveau produit",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Commande créée avec succès",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "Paiement annulé",
|
||||
"Payment failed": "Paiement échoué",
|
||||
"Payment providers": "Fournisseurs de paiement",
|
||||
"Payment providers - Tooltip": "Fournisseurs de services de paiement",
|
||||
"Placing order...": "Passer une commande...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Veuillez ajouter au moins une option de recharge lorsque le montant personnalisé est désactivé",
|
||||
"Please select a currency": "Veuillez sélectionner une devise",
|
||||
"Please select at least one payment provider": "Veuillez sélectionner au moins un fournisseur de paiement",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Traitement du paiement...",
|
||||
"Product list cannot be empty": "La liste des produits ne peut pas être vide",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Quantité",
|
||||
"Quantity - Tooltip": "Quantité de produit",
|
||||
"Recharge options": "Recharge options",
|
||||
"Quantity - Tooltip": "Quantité du produit",
|
||||
"Recharge options": "Options de recharge",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "URL de retour",
|
||||
"Return URL - Tooltip": "URL de retour après l'achat réussi",
|
||||
"SKU": "SKU",
|
||||
"Select amount": "Select amount",
|
||||
"Select amount": "Sélectionner un montant",
|
||||
"Sold": "Vendu",
|
||||
"Sold - Tooltip": "Quantité vendue",
|
||||
"Stripe": "Stripe",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "URL de retour après achat",
|
||||
"Tag - Tooltip": "Étiquette de produit",
|
||||
"Test buy page..": "Page d'achat de test.",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "La devise du produit que vous ajoutez est différente de celle des articles du panier",
|
||||
"There is no payment channel for this product.": "Il n'y a aucun canal de paiement pour ce produit.",
|
||||
"This product is currently not in sale.": "Ce produit n'est actuellement pas en vente.",
|
||||
"This product is currently not purchasable (No options available)": "This product is currently not purchasable (No options available)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"This product is currently not purchasable (No options available)": "Ce produit n'est actuellement pas achetable (aucune option disponible)",
|
||||
"Total Price": "Prix total",
|
||||
"View Product": "Voir le produit",
|
||||
"WeChat Pay": "WeChat Pay"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Clé d'authentification - Infobulle",
|
||||
"Auth URL": "URL d'authentification",
|
||||
"Auth URL - Tooltip": "URL d'authentification",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "URL de base",
|
||||
"Base URL - Tooltip": "URL de base - Infobulle",
|
||||
"Bucket": "seau",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "La deuxième clé secrète du client",
|
||||
"Content": "Contenu",
|
||||
"Content - Tooltip": "Contenu - Infobulle",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "Désactiver SSL",
|
||||
"Disable SSL - Tooltip": "Désactiver le protocole SSL lors de la communication avec le serveur STMP",
|
||||
"DB test": "Test BD",
|
||||
"DB test - Tooltip": "Test BD - Infobulle",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Domaine",
|
||||
"Domain - Tooltip": "Domaine personnalisé pour le stockage d'objets",
|
||||
"Edit Provider": "Modifier le fournisseur",
|
||||
@@ -1001,10 +1030,11 @@
|
||||
"Email regex - Tooltip": "Regex e-mail - Infobulle",
|
||||
"Email title": "Titre de l'email",
|
||||
"Email title - Tooltip": "Titre de l'email",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "Activer PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Enable proxy": "Activer le proxy",
|
||||
"Enable proxy - Tooltip": "Activer un proxy SOCKS5 lors de l'envoi d'e-mails ou de SMS",
|
||||
"Endpoint": "Point de terminaison",
|
||||
"Endpoint (Intranet)": "Endpoint (intranet)",
|
||||
"Endpoint - Tooltip": "Point de terminaison - Infobulle",
|
||||
@@ -1031,7 +1061,7 @@
|
||||
"Key ID - Tooltip": "ID de clé",
|
||||
"Key text": "Texte de clé",
|
||||
"Key text - Tooltip": "Texte de clé",
|
||||
"LDAP port": "LDAP port",
|
||||
"LDAP port": "Port LDAP",
|
||||
"Metadata": "Métadonnées",
|
||||
"Metadata - Tooltip": "Métadonnées SAML",
|
||||
"Metadata url": "URL des métadonnées",
|
||||
@@ -1055,10 +1085,10 @@
|
||||
"Prompted": "Incité",
|
||||
"Provider URL": "URL du fournisseur",
|
||||
"Provider URL - Tooltip": "URL pour configurer le fournisseur de services, ce champ est uniquement utilisé à titre de référence et n'est pas utilisé dans Casdoor",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "Test du fournisseur réussi",
|
||||
"Public key": "Clé publique",
|
||||
"Public key - Tooltip": "Clé publique - Infobulle",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret of RADIUS",
|
||||
"RADIUS Shared Secret - Tooltip": "Secret partagé RADIUS",
|
||||
"Region": "Région",
|
||||
"Region - Tooltip": "Région - Infobulle",
|
||||
"Region ID": "Identifiant de région",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "URL du SP ACS",
|
||||
"SP ACS URL - Tooltip": "URL de l'ACS du fournisseur de service",
|
||||
"SP Entity ID": "Identifiant d'entité SP",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Scène",
|
||||
"Scene - Tooltip": "Scène",
|
||||
"Scope": "Portée",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Clé d'accès secrète",
|
||||
"Secret access key - Tooltip": "Clé d'accès secrète",
|
||||
"Secret key": "Clé secrète",
|
||||
@@ -1111,8 +1144,8 @@
|
||||
"Sub type - Tooltip": "Sous-type",
|
||||
"Subject": "Sujet",
|
||||
"Subject - Tooltip": "Sujet de l'e-mail",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype": "Sous-type",
|
||||
"Subtype - Tooltip": "Sous-type - Infobulle",
|
||||
"Syncer test": "Test du synchroniseur",
|
||||
"Syncer test - Tooltip": "Test du synchroniseur",
|
||||
"Team ID": "ID de l'équipe",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "Test de connexion SMTP",
|
||||
"Third-party": "Tierce partie",
|
||||
"This field is required": "Ce champ est requis",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "Adresse du destinataire",
|
||||
"To address - Tooltip": "Adresse e-mail du champ « À »",
|
||||
"Token URL": "URL de jeton",
|
||||
"Token URL - Tooltip": "URL de jeton",
|
||||
"Use WeChat Media Platform in PC": "Utiliser la plateforme WeChat Media sur PC",
|
||||
@@ -1197,7 +1230,7 @@
|
||||
"Please input your last name!": "Veuillez saisir votre nom de famille !",
|
||||
"Please input your phone number!": "Veuillez saisir votre numéro de téléphone !",
|
||||
"Please input your real name!": "Veuillez saisir votre nom complet !",
|
||||
"Please input your {label}!": "Please input your {label}!",
|
||||
"Please input your {label}!": "Veuillez saisir votre {label} !",
|
||||
"Please select your country code!": "Sélectionnez votre code de pays, s'il vous plaît !",
|
||||
"Please select your country/region!": "Veuillez sélectionner votre pays/région !",
|
||||
"Regex": "Expression régulière",
|
||||
@@ -1210,7 +1243,7 @@
|
||||
"Text 4": "Texte 4",
|
||||
"Text 5": "Texte 5",
|
||||
"The input Email doesn't match the signup item regex!": "L'e-mail saisi ne correspond pas au regex de l'élément d'inscription !",
|
||||
"The input doesn't match the signup item regex!": "The input doesn't match the signup item regex!",
|
||||
"The input doesn't match the signup item regex!": "L'entrée ne correspond pas au regex de l'élément d'inscription !",
|
||||
"The input is not invoice Tax ID!": "L'entrée n'est pas l'identifiant fiscal de la facture !",
|
||||
"The input is not invoice title!": "L'entrée n'est pas un nom ou une dénomination sociale !",
|
||||
"The input is not valid Phone!": "L'entrée n'est pas un numéro de téléphone valide !",
|
||||
@@ -1230,15 +1263,18 @@
|
||||
"New Subscription": "Nouvel abonnement",
|
||||
"Start time": "Heure de début",
|
||||
"Start time - Tooltip": "Heure de début",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Subscription plan": "Plan d'abonnement",
|
||||
"Subscription pricing": "Tarification d'abonnement",
|
||||
"Suspended": "Suspendu",
|
||||
"Upcoming": "À venir",
|
||||
"View Subscription": "View Subscription"
|
||||
"View Subscription": "Voir l'abonnement"
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"Admin Email": "Admin Email",
|
||||
"API Token / Password": "Jeton API / Mot de passe",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "E-mail admin",
|
||||
"Affiliation table": "Table d'affiliation",
|
||||
"Affiliation table - Tooltip": "Nom de la table de la base de données de l'unité de travail",
|
||||
"Avatar base URL": "URL de base de l'avatar",
|
||||
@@ -1248,8 +1284,8 @@
|
||||
"Column name": "Nom de la colonne",
|
||||
"Column type": "Type de colonne",
|
||||
"Connect successfully": "Connexion réussie",
|
||||
"Corp ID": "Corp ID",
|
||||
"Corp secret": "Corp secret",
|
||||
"Corp ID": "ID entreprise",
|
||||
"Corp secret": "Secret entreprise",
|
||||
"Database": "Base de données",
|
||||
"Database - Tooltip": "Le nom original de la base de données",
|
||||
"Database type": "Type de base de données",
|
||||
@@ -1263,15 +1299,15 @@
|
||||
"Is read-only": "Est en lecture seule",
|
||||
"Is read-only - Tooltip": "Est en lecture seule - Infobulle",
|
||||
"New Syncer": "Nouveau synchroniseur",
|
||||
"Paste your Google Workspace service account JSON key here": "Paste your Google Workspace service account JSON key here",
|
||||
"SCIM Server URL": "SCIM Server URL",
|
||||
"Paste your Google Workspace service account JSON key here": "Collez ici la clé JSON du compte de service Google Workspace",
|
||||
"SCIM Server URL": "URL du serveur SCIM",
|
||||
"SSH host": "Hôte SSH",
|
||||
"SSH password": "Mot de passe SSH",
|
||||
"SSH port": "Port SSH",
|
||||
"SSH user": "Utilisateur SSH",
|
||||
"SSL mode": "Mode SSL",
|
||||
"SSL mode - Tooltip": "Mode SSL",
|
||||
"Service account key": "Service account key",
|
||||
"Service account key": "Clé du compte de service",
|
||||
"Sync interval": "Intervalle de synchronisation",
|
||||
"Sync interval - Tooltip": "Unité en secondes",
|
||||
"Table": "Tableau",
|
||||
@@ -1279,8 +1315,8 @@
|
||||
"Table columns": "Colonnes de table",
|
||||
"Table columns - Tooltip": "Colonnes du tableau impliquées dans la synchronisation des données. Les colonnes qui ne participent pas à la synchronisation n'ont pas besoin d'être ajoutées",
|
||||
"Test Connection": "Tester la connexion",
|
||||
"Test DB Connection": "Test DB Connection",
|
||||
"Username (optional)": "Username (optional)"
|
||||
"Test DB Connection": "Tester la connexion BD",
|
||||
"Username (optional)": "Nom d'utilisateur (optionnel)"
|
||||
},
|
||||
"system": {
|
||||
"API Latency": "Retard API",
|
||||
@@ -1311,16 +1347,16 @@
|
||||
"Theme - Tooltip": "Thème de style de l'application"
|
||||
},
|
||||
"ticket": {
|
||||
"Closed": "Closed",
|
||||
"Edit Ticket": "Edit Ticket",
|
||||
"In Progress": "In Progress",
|
||||
"Closed": "Fermé",
|
||||
"Edit Ticket": "Modifier le ticket",
|
||||
"In Progress": "En cours",
|
||||
"Messages": "Messages",
|
||||
"New Ticket": "New Ticket",
|
||||
"Open": "Open",
|
||||
"Please enter a message": "Please enter a message",
|
||||
"Press Ctrl+Enter to send": "Press Ctrl+Enter to send",
|
||||
"Resolved": "Resolved",
|
||||
"Type your message here...": "Type your message here..."
|
||||
"New Ticket": "Nouveau ticket",
|
||||
"Open": "Ouvert",
|
||||
"Please enter a message": "Veuillez saisir un message",
|
||||
"Press Ctrl+Enter to send": "Appuyez sur Ctrl+Entrée pour envoyer",
|
||||
"Resolved": "Résolu",
|
||||
"Type your message here...": "Saisissez votre message ici..."
|
||||
},
|
||||
"token": {
|
||||
"Access token": "Token d'accès",
|
||||
@@ -1342,7 +1378,7 @@
|
||||
"Amount - Tooltip": "Le montant des produits échangés",
|
||||
"Edit Transaction": "Modifier la transaction",
|
||||
"New Transaction": "Nouvelle transaction",
|
||||
"Recharge": "Recharge"
|
||||
"Recharge": "Recharger"
|
||||
},
|
||||
"user": {
|
||||
"3rd-party logins": "Services de connexions tiers",
|
||||
@@ -1372,7 +1408,7 @@
|
||||
"Email cannot be empty": "Le champ e-mail doit être rempli",
|
||||
"Email/phone reset successfully": "E-mail ou téléphone réinitialisé avec succès",
|
||||
"Empty input!": "Champ vide !",
|
||||
"Face IDs": "Face IDs",
|
||||
"Face IDs": "Identifiants Face",
|
||||
"Gender": "Genre",
|
||||
"Gender - Tooltip": "Genre - Infobulle",
|
||||
"Homepage": "Site web",
|
||||
@@ -1386,10 +1422,10 @@
|
||||
"ID card type": "Type de carte d'identité",
|
||||
"ID card type - Tooltip": "Type de carte d'identité - Infobulle",
|
||||
"ID card with person": "Carte d'identité avec la personne",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"ID verification": "Vérification d'identité",
|
||||
"ID verification - Tooltip": "Vérification d'identité - Infobulle",
|
||||
"Identity verification successful": "Vérification d'identité réussie",
|
||||
"Identity verified": "Identité vérifiée",
|
||||
"Input your email": "Saisissez votre adresse e-mail",
|
||||
"Input your phone number": "Saisissez votre numéro de téléphone",
|
||||
"Is admin": "Est administrateur ou administratrice",
|
||||
@@ -1399,7 +1435,7 @@
|
||||
"Is forbidden": "Est interdit",
|
||||
"Is forbidden - Tooltip": "Les comptes interdits ne peuvent plus se connecter",
|
||||
"Is online": "En ligne",
|
||||
"Is verified": "Is verified",
|
||||
"Is verified": "Est vérifié",
|
||||
"Karma": "Karma",
|
||||
"Karma - Tooltip": "Karma - Infobulle",
|
||||
"Keys": "Clés",
|
||||
@@ -1424,16 +1460,16 @@
|
||||
"Other": "Autre",
|
||||
"Password set successfully": "Mot de passe changé avec succès",
|
||||
"Phone cannot be empty": "Le numéro de téléphone ne peut pas être vide",
|
||||
"Please enter your real name": "Please enter your real name",
|
||||
"Please fill in ID card information first": "Please fill in ID card information first",
|
||||
"Please fill in your real name first": "Please fill in your real name first",
|
||||
"Please enter your real name": "Veuillez saisir votre nom complet",
|
||||
"Please fill in ID card information first": "Veuillez d'abord remplir les informations de la pièce d'identité",
|
||||
"Please fill in your real name first": "Veuillez d'abord saisir votre nom complet",
|
||||
"Please select avatar from resources": "Sélectionner un avatar à partir des ressources",
|
||||
"Properties": "Propriétés",
|
||||
"Properties - Tooltip": "Propriétés du compte",
|
||||
"Ranking": "Classement",
|
||||
"Ranking - Tooltip": "Classement - Infobulle",
|
||||
"Re-enter New": "Confirmer le mot de passe",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Real name - Tooltip": "Nom complet - Infobulle",
|
||||
"Register source": "Source d'enregistrement",
|
||||
"Register source - Tooltip": "La source à partir de laquelle l'utilisateur a été enregistré",
|
||||
"Register type": "Type d'enregistrement",
|
||||
@@ -1462,8 +1498,8 @@
|
||||
"User Profile": "Profil utilisateur",
|
||||
"Values": "Valeurs",
|
||||
"Verification code sent": "Code de vérification envoyé",
|
||||
"Verified": "Verified",
|
||||
"Verify Identity": "Verify Identity",
|
||||
"Verified": "Vérifié",
|
||||
"Verify Identity": "Vérifier l'identité",
|
||||
"WebAuthn credentials": "Identifiants WebAuthn",
|
||||
"Work": "Travail",
|
||||
"You have changed the username, please save your change first before modifying the password": "Vous avez changé le nom d'utilisateur, veuillez d'abord enregistrer votre modification avant de modifier le mot de passe",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "なりすましを終了",
|
||||
"Logout": "ログアウト",
|
||||
"My Account": "マイアカウント",
|
||||
"Sign Up": "新規登録"
|
||||
@@ -21,23 +21,23 @@
|
||||
"Add Face ID": "顔IDを追加",
|
||||
"Add Face ID with Image": "画像で顔IDを追加",
|
||||
"Always": "常に",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Array": "配列",
|
||||
"Authentication": "認証",
|
||||
"Auto signin": "自動サインイン",
|
||||
"Auto signin - Tooltip": "Casdoorにログインセッションが存在する場合、アプリケーション側のログインに自動的に使用されます",
|
||||
"Background URL": "背景URL",
|
||||
"Background URL - Tooltip": "ログインページで使用される背景画像のURL",
|
||||
"Background URL Mobile": "モバイル背景URL",
|
||||
"Background URL Mobile - Tooltip": "モバイルデバイス用の背景画像URL",
|
||||
"Basic": "Basic",
|
||||
"Basic": "基本",
|
||||
"Big icon": "大きいアイコン",
|
||||
"Binding providers": "バインディングプロバイダー",
|
||||
"CSS style": "CSSスタイル",
|
||||
"Center": "センター",
|
||||
"Code resend timeout": "コード再送信タイムアウト",
|
||||
"Code resend timeout - Tooltip": "ユーザーが別の確認コードを要求する前に待機する必要がある期間(秒単位)。グローバルデフォルト(60秒)を使用するには0に設定します",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Cookieの有効期限",
|
||||
"Cookie expire - Tooltip": "Cookieの有効期限 - ヒント",
|
||||
"Copy SAML metadata URL": "SAMLメタデータのURLをコピーしてください",
|
||||
"Copy prompt page URL": "プロンプトページのURLをコピーしてください",
|
||||
"Copy signin page URL": "サインインページのURLをコピーしてください",
|
||||
@@ -47,9 +47,9 @@
|
||||
"Custom CSS - Tooltip": "サインアップ、サインイン、パスワード忘れのフォームのCSSスタイリング(例:境界線や影の追加)",
|
||||
"Custom CSS Mobile": "カスタムCSS(モバイル)",
|
||||
"Custom CSS Mobile - Edit": "カスタムCSS(モバイル)- 編集",
|
||||
"Custom CSS Mobile - Tooltip": "モバイルデバイス用のカスタムCSS",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Custom CSS Mobile - Tooltip": "モバイルデバイス用のカスタムCSS - ヒント",
|
||||
"Disable SAML attributes": "SAML属性を無効にする",
|
||||
"Disable SAML attributes - Tooltip": "SAML属性を無効にする - ヒント",
|
||||
"Disable signin": "サインインを無効化",
|
||||
"Disable signin - Tooltip": "ユーザーのサインインを無効化する",
|
||||
"Dynamic": "動的",
|
||||
@@ -60,16 +60,17 @@
|
||||
"Enable SAML C14N10 - Tooltip": "SAMLでC14N11の代わりにC14N10を使用する",
|
||||
"Enable SAML POST binding": "SAML POSTバインディングを有効にする",
|
||||
"Enable SAML POST binding - Tooltip": "HTTP POSTバインディングはHTMLフォームの入力フィールドを使用してSAMLメッセージを送信します。SPがこれを使用する場合は有効にしてください。",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "SAMLアサーション署名を有効にする",
|
||||
"Enable SAML assertion signature - Tooltip": "SAMLアサーション署名を有効にする - ヒント",
|
||||
"Enable SAML compression": "SAMLの圧縮を有効にする",
|
||||
"Enable SAML compression - Tooltip": "CasdoorをSAML IdPとして使用する場合、SAMLレスポンスメッセージを圧縮するかどうか。圧縮する: 圧縮するかどうか。圧縮しない: 圧縮しないかどうか",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "排他的サインインを有効にする",
|
||||
"Enable exclusive signin - Tooltip": "排他的サインインが有効な場合、ユーザーは複数のアクティブセッションを持てません",
|
||||
"Enable side panel": "サイドパネルを有効にする",
|
||||
"Enable signin session - Tooltip": "アプリケーションから Casdoor にログイン後、Casdoor がセッションを維持しているかどうか",
|
||||
"Enable signup": "サインアップを有効にする",
|
||||
"Enable signup - Tooltip": "新しいアカウントの登録をユーザーに許可するかどうか",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "サインイン失敗時の凍結時間",
|
||||
"Failed signin frozen time - Tooltip": "サインイン失敗後にアカウントが凍結される時間",
|
||||
"Failed signin limit": "サインイン失敗回数制限",
|
||||
@@ -89,7 +90,7 @@
|
||||
"Header HTML": "ヘッダーHTML",
|
||||
"Header HTML - Edit": "ヘッダーHTML - 編集",
|
||||
"Header HTML - Tooltip": "アプリケーションエントリーページのheadタグをカスタマイズします",
|
||||
"Horizontal": "Horizontal",
|
||||
"Horizontal": "水平",
|
||||
"Incremental": "増分",
|
||||
"Inline": "インライン",
|
||||
"Input": "入力",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "正常にログアウトしました",
|
||||
"MFA remember time": "MFA記憶時間",
|
||||
"MFA remember time - Tooltip": "MFAログインに成功した後、アカウントが信頼できるものとして記憶される期間を設定します",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "メニューモード",
|
||||
"Menu mode - Tooltip": "メニューモード - ヒント",
|
||||
"Multiple Choices": "複数選択",
|
||||
"New Application": "新しいアプリケーション",
|
||||
"No verification": "検証なし",
|
||||
@@ -111,39 +112,49 @@
|
||||
"Order": "順序",
|
||||
"Order - Tooltip": "値が小さいほど、アプリページで上位にランク付けされます",
|
||||
"Org choice mode": "組織選択モード",
|
||||
"Org choice mode - Tooltip": "組織選択モード",
|
||||
"Org choice mode - Tooltip": "ログインする組織を選択する方法 - ヒント",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "\"自動サインイン\"を有効にする前に、まず\"サインインセッション\"を有効にしてください",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "あなたの申請を入力してください!",
|
||||
"Please input your organization!": "あなたの組織を入力してください!",
|
||||
"Please select a HTML file": "HTMLファイルを選択してください",
|
||||
"Pop up": "ポップアップ",
|
||||
"Providers": "Providers",
|
||||
"Providers": "プロバイダー",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "ランダム",
|
||||
"Real name": "本名",
|
||||
"Redirect URL": "リダイレクトURL",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "リダイレクトURL(アサーションコンシューマサービスPOSTバインディングURL)",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "リダイレクトURL(アサーションコンシューマーサービスPOSTバインディングURL) - ヒント",
|
||||
"Redirect URLs": "リダイレクトURL",
|
||||
"Redirect URLs - Tooltip": "許可されたリダイレクトURLリストは、正規表現マッチングをサポートしています。リストに含まれていないURLはリダイレクトできません",
|
||||
"Refresh token expire": "リフレッシュトークンの有効期限が切れました",
|
||||
"Refresh token expire - Tooltip": "リフレッシュトークンの有効期限時間",
|
||||
"Reset to Empty": "空にリセット",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "右",
|
||||
"Rule": "ルール",
|
||||
"SAML hash algorithm": "SAMLハッシュアルゴリズム",
|
||||
"SAML hash algorithm - Tooltip": "SAML署名のハッシュアルゴリズム",
|
||||
"SAML metadata": "SAMLメタデータ",
|
||||
"SAML metadata - Tooltip": "SAMLプロトコルのメタデータ",
|
||||
"SAML metadata - Tooltip": "SAMLプロトコルのメタデータ - ヒント",
|
||||
"SAML reply URL": "SAMLリプライURL",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "セキュリティ",
|
||||
"Select": "選択",
|
||||
"Side panel HTML": "サイドパネルのHTML",
|
||||
"Side panel HTML - Edit": "サイドパネルのHTML - 編集",
|
||||
"Side panel HTML - Tooltip": "ログインページのサイドパネルに対するHTMLコードをカスタマイズしてください",
|
||||
"Side panel HTML - Tooltip": "ログインページのサイドパネルのHTMLコードをカスタマイズします - ヒント",
|
||||
"Sign Up Error": "サインアップエラー",
|
||||
"Signin": "サインイン",
|
||||
"Signin (Default True)": "サインイン(デフォルトは有効)",
|
||||
"Signin items": "サインイン項目",
|
||||
"Signin items - Tooltip": "サインイン項目",
|
||||
"Signin items - Tooltip": "ユーザーがサインインするときに記入するアイテム - ヒント",
|
||||
"Signin methods": "サインイン方法",
|
||||
"Signin methods - Tooltip": "サインイン方法 - ツールチップ",
|
||||
"Signin session": "サインインセッション",
|
||||
@@ -151,7 +162,8 @@
|
||||
"Signup items - Tooltip": "新しいアカウントを登録する際にユーザーが入力するアイテム",
|
||||
"Single Choice": "単一選択",
|
||||
"Small icon": "小さいアイコン",
|
||||
"String": "String",
|
||||
"Static Value": "Static Value",
|
||||
"String": "文字列",
|
||||
"Tags - Tooltip": "アプリケーションタグに含まれるタグを持つユーザーのみログイン可能です",
|
||||
"The application does not allow to sign up new account": "アプリケーションでは新しいアカウントの登録ができません",
|
||||
"Token expire": "トークンの有効期限が切れました",
|
||||
@@ -162,10 +174,12 @@
|
||||
"Token format - Tooltip": "アクセストークンのフォーマット",
|
||||
"Token signing method": "トークン署名方法",
|
||||
"Token signing method - Tooltip": "JWTトークンの署名方法。証明書と同じアルゴリズムである必要があります。",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "UIのカスタマイズ",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "メールアドレスをNameIDとして使用",
|
||||
"Use Email as NameID - Tooltip": "メールアドレスをNameIDとして使用 - ツールチップ",
|
||||
"Vertical": "Vertical",
|
||||
"Vertical": "垂直",
|
||||
"You are unexpected to see this prompt page": "このプロンプトページを見ることは予期せぬことである"
|
||||
},
|
||||
"cert": {
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "幅"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "通常ユーザーは自分が提出した権限のみ変更できます",
|
||||
"AI Assistant": "AIアシスタント",
|
||||
"API key": "APIキー",
|
||||
"API key - Tooltip": "サービスにアクセスするためのAPIキー",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "ビジネスと支払い",
|
||||
"Cancel": "キャンセルします",
|
||||
"Captcha": "キャプチャ",
|
||||
"Cart": "Cart",
|
||||
"Cart": "カート",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "証明書",
|
||||
"Cert - Tooltip": "このアプリケーションに対応するクライアントSDKによって検証する必要がある公開鍵証明書",
|
||||
"Certs": "証明書",
|
||||
"Clear": "Clear",
|
||||
"Clear": "クリア",
|
||||
"Click to Upload": "アップロードするにはクリックしてください",
|
||||
"Client IP": "クライアントIP",
|
||||
"Close": "閉じる",
|
||||
@@ -307,12 +323,12 @@
|
||||
"Delete": "削除",
|
||||
"Description": "説明",
|
||||
"Description - Tooltip": "参照用の詳細な説明情報です。Casdoor自体はそれを使用しません",
|
||||
"Detail": "详情",
|
||||
"Detail": "詳細",
|
||||
"Disable": "無効",
|
||||
"Display name": "表示名",
|
||||
"Display name - Tooltip": "UIで公開されている使いやすく読みやすい名前",
|
||||
"Down": "ダウン",
|
||||
"Download template": "Download template",
|
||||
"Download template": "テンプレートをダウンロード",
|
||||
"Edit": "編集",
|
||||
"Email": "電子メール",
|
||||
"Email - Tooltip": "有効な電子メールアドレス",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "正常に有効化されました",
|
||||
"Enforcers": "エンフォーサー",
|
||||
"Failed to add": "追加できませんでした",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "キャンセルに失敗しました",
|
||||
"Failed to connect to server": "サーバーに接続できませんでした",
|
||||
"Failed to copy": "コピーに失敗しました",
|
||||
"Failed to delete": "削除に失敗しました",
|
||||
"Failed to enable": "有効化に失敗しました",
|
||||
"Failed to get": "取得に失敗しました",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "読み込みに失敗しました",
|
||||
"Failed to log out": "ログアウトに失敗しました",
|
||||
"Failed to remove": "削除に失敗しました",
|
||||
"Failed to save": "保存に失敗しました",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "送信に失敗しました",
|
||||
"Failed to sync": "同期に失敗しました",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "リンク解除に失敗しました",
|
||||
"Failed to update": "更新に失敗しました",
|
||||
"Failed to upload": "アップロードに失敗しました",
|
||||
"Failed to verify": "検証に失敗しました",
|
||||
"False": "偽",
|
||||
"Favicon": "ファビコン",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "「パスワードをお忘れの場合」ページのカスタムURL。未設定の場合、デフォルトのCasdoor「パスワードをお忘れの場合」ページが使用されます。設定された場合、ログインページの「パスワードをお忘れの場合」リンクはこのURLにリダイレクトされます",
|
||||
"Forms": "フォーム",
|
||||
"Found some texts still not translated? Please help us translate at": "まだ翻訳されていない文章が見つかりましたか?是非とも翻訳のお手伝いをお願いします",
|
||||
"Generate": "Generate",
|
||||
"Generate": "生成",
|
||||
"Go to enable": "有効にする",
|
||||
"Go to writable demo site?": "書き込み可能なデモサイトに移動しますか?",
|
||||
"Groups": "グループ",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "IPホワイトリスト",
|
||||
"IP whitelist - Tooltip": "IPホワイトリスト",
|
||||
"Identity": "ID",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "なりすまし",
|
||||
"Invitations": "招待",
|
||||
"Is enabled": "可能になっています",
|
||||
"Is enabled - Tooltip": "使用可能かどうかを設定してください",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "名前",
|
||||
"Name - Tooltip": "ユニークで文字列ベースのID",
|
||||
"Name format": "名前フォーマット",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "利用可能な商品がありません",
|
||||
"No sheets found in file": "ファイル内にシートが見つかりません",
|
||||
"No verification method": "検証方法がありません",
|
||||
"Non-LDAP": "非LDAP",
|
||||
"None": "なし",
|
||||
"OAuth providers": "OAuthプロバイダー",
|
||||
"OFF": "オフ",
|
||||
"OK": "OK",
|
||||
"ON": "オン",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "必須にできるMFA方法は1つだけです",
|
||||
"Or": "または",
|
||||
"Orders": "注文",
|
||||
"Organization": "組織",
|
||||
"Organization - Tooltip": "テナントまたはユーザープールのような概念に似て、各ユーザーとアプリケーションは組織に属しています",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "組織が空です",
|
||||
"Organizations": "組織",
|
||||
"Password": "パスワード",
|
||||
"Password - Tooltip": "パスワードが正しいことを確認してください",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "電話番号",
|
||||
"Phone only": "電話のみ",
|
||||
"Phone or Email": "電話またはメール",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "注文する",
|
||||
"Plain": "プレーン",
|
||||
"Plan": "プラン",
|
||||
"Plan - Tooltip": "サブスクリプションプラン",
|
||||
"Plans": "プラン",
|
||||
"Plans - Tooltip": "プラン - ツールチップ",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "キャプチャを正しく入力してください",
|
||||
"Please input your search": "検索内容を入力してください",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "まず少なくとも1人のユーザーを選択してください",
|
||||
"Preview": "プレビュー",
|
||||
"Preview - Tooltip": "構成されたエフェクトをプレビューする",
|
||||
"Pricing": "価格設定",
|
||||
"Pricing - Tooltip": "価格設定 - ツールチップ",
|
||||
"Pricings": "価格設定",
|
||||
"Product Store": "Product Store",
|
||||
"Product Store": "商品ストア",
|
||||
"Products": "製品",
|
||||
"Provider": "プロバイダー",
|
||||
"Provider - Tooltip": "支払いプロバイダーを設定する必要があります。これには、PayPal、Alipay、WeChat Payなどが含まれます。",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "SSH接続の認証タイプ",
|
||||
"Save": "保存",
|
||||
"Save & Exit": "保存して終了",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "検索",
|
||||
"Send": "送信",
|
||||
"Session ID": "セッションID",
|
||||
@@ -493,13 +511,13 @@
|
||||
"Sorry, you do not have permission to access this page or logged in status invalid.": "申し訳ありませんが、このページにアクセスする権限がありません、またはログイン状態が無効です。",
|
||||
"State": "州",
|
||||
"State - Tooltip": "状態",
|
||||
"Status": "Status",
|
||||
"Status": "状態",
|
||||
"Subscriptions": "サブスクリプション",
|
||||
"Successfully added": "正常に追加されました",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "正常にキャンセルされました",
|
||||
"Successfully copied": "正常にコピーされました",
|
||||
"Successfully deleted": "正常に削除されました",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "正常に実行されました",
|
||||
"Successfully removed": "正常に削除されました",
|
||||
"Successfully saved": "成功的に保存されました",
|
||||
"Successfully sent": "正常に送信されました",
|
||||
@@ -514,12 +532,12 @@
|
||||
"Syncers": "同期ツール",
|
||||
"System Info": "システム情報",
|
||||
"Tab": "タブ",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "アクションを空にできません",
|
||||
"The resources cannot be empty": "リソースを空にできません",
|
||||
"The users and roles cannot be empty at the same time": "ユーザーとロールを同時に空にすることはできません",
|
||||
"There was a problem signing you in..": "サインインに問題が発生しました...",
|
||||
"This is a read-only demo site!": "これは読み取り専用のデモサイトです!",
|
||||
"Tickets": "Tickets",
|
||||
"Tickets": "チケット",
|
||||
"Timestamp": "タイムスタンプ",
|
||||
"Title": "タイトル",
|
||||
"Title - Tooltip": "タイトル",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "取引",
|
||||
"True": "真",
|
||||
"Type": "タイプ",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "URLリンク",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "不明なアプリケーション名",
|
||||
"Unknown authentication type": "不明な認証タイプ",
|
||||
"Up": "アップ",
|
||||
"Updated time": "更新日時",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"Upload (.xlsx)": "アップロード (.xlsx)",
|
||||
"User": "ユーザー",
|
||||
"User - Tooltip": "ユーザー名が正しいことを確認してください",
|
||||
"User Management": "ユーザー管理",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "ユーザーは既に存在します",
|
||||
"User containers": "ユーザープール",
|
||||
"User type": "ユーザータイプ",
|
||||
"User type - Tooltip": "ユーザーが属するタグは、デフォルトでは「通常ユーザー」となります",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "ユーザー - ツールチップ",
|
||||
"Users under all organizations": "すべての組織のユーザー",
|
||||
"Verifications": "検証",
|
||||
"View": "View",
|
||||
"View": "表示",
|
||||
"Webhooks": "Webhook",
|
||||
"You can only select one physical group": "物理グループは1つしか選択できません",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "まず画像を選択してください",
|
||||
"empty": "空",
|
||||
"remove": "削除",
|
||||
"{total} in total": "総計{total}"
|
||||
@@ -626,7 +645,7 @@
|
||||
"login": {
|
||||
"Auto sign in": "自動サインイン",
|
||||
"Back button": "戻るボタン",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "下のボタンをクリックしてTelegramでサインインしてください",
|
||||
"Continue with": "続ける",
|
||||
"Email or phone": "メールまたは電話",
|
||||
"Face ID": "Face ID",
|
||||
@@ -649,12 +668,12 @@
|
||||
"Please input your Email!": "メールアドレスを入力してください!",
|
||||
"Please input your LDAP username!": "LDAPユーザー名を入力してください!",
|
||||
"Please input your Phone!": "電話番号を入力してください!",
|
||||
"Please input your RADIUS password!": "Please input your RADIUS password!",
|
||||
"Please input your RADIUS username!": "Please input your RADIUS username!",
|
||||
"Please input your RADIUS password!": "RADIUSパスワードを入力してください!",
|
||||
"Please input your RADIUS username!": "RADIUSユーザー名を入力してください!",
|
||||
"Please input your code!": "あなたのコードを入力してください!",
|
||||
"Please input your organization name!": "組織名を入力してください!",
|
||||
"Please input your password!": "パスワードを入力してください!",
|
||||
"Please input your push notification receiver!": "Please input your push notification receiver!",
|
||||
"Please input your push notification receiver!": "プッシュ通知の受信者を入力してください!",
|
||||
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "HTTPSでページを読み込んでください。そうでない場合、カメラにアクセスできません",
|
||||
"Please provide permission to access the camera": "カメラへのアクセス許可を与えてください",
|
||||
"Please select an organization": "組織を選択してください",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "組織を選択",
|
||||
"Sign In": "サインイン",
|
||||
"Sign in with Face ID": "顔IDでサインイン",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "Telegramでサインイン",
|
||||
"Sign in with WebAuthn": "WebAuthnでサインインしてください",
|
||||
"Sign in with {type}": "{type}でサインインしてください",
|
||||
"Signin button": "サインインボタン",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "以下の情報を確認してください",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "このリカバリーコードを保存してください。デバイスが認証コードを提供できない場合、このリカバリーコードでMFA認証をリセットできます",
|
||||
"Protect your account with Multi-factor authentication": "多要素認証でアカウントを保護する",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "プッシュ通知受信者",
|
||||
"Recovery code": "リカバリーコード",
|
||||
"Remember this account for {hour} hours": "{hour}時間このアカウントを記憶する",
|
||||
"Scan the QR code with your Authenticator App": "認証アプリでQRコードをスキャンしてください",
|
||||
@@ -708,17 +727,17 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "アカウントのセキュリティを確保するため、多要素認証の有効化が必要です",
|
||||
"Use Authenticator App": "認証アプリを使用",
|
||||
"Use Email": "メールを使用",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "プッシュ通知を使用",
|
||||
"Use Radius": "RADIUSを使用",
|
||||
"Use SMS": "SMSを使用",
|
||||
"Use SMS verification code": "SMS検証コードを使用",
|
||||
"Use a recovery code": "リカバリーコードを使用",
|
||||
"Verify Code": "検証コード",
|
||||
"Verify Password": "パスワードを検証",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "多要素認証が有効になっています。「コードを送信」をクリックして続行してください",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "多要素認証が有効になっています。RADIUSパスワードを入力してください",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "多要素認証が有効になっています。TOTPコードを入力してください",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "多要素認証が有効になっています。プッシュ通知の確認コードを入力してください",
|
||||
"Your email is": "あなたのメールは",
|
||||
"Your phone is": "あなたの電話は",
|
||||
"preferred": "優先"
|
||||
@@ -732,29 +751,30 @@
|
||||
"New Model": "新しいモデル"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "キャンセル時刻",
|
||||
"Edit Order": "注文を編集",
|
||||
"New Order": "新しい注文",
|
||||
"Order not found": "注文が見つかりません",
|
||||
"Pay": "支払う",
|
||||
"Payment failed time": "支払い失敗時刻",
|
||||
"Payment time": "支払い時刻",
|
||||
"Price": "価格",
|
||||
"Return to Order List": "注文一覧に戻る",
|
||||
"Timeout time": "タイムアウト時刻",
|
||||
"View Order": "注文を表示"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "アカウントアイテム",
|
||||
"Account items - Tooltip": "個人設定ページのアイテム",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Account menu": "アカウントメニュー",
|
||||
"Account menu - Tooltip": "アカウントメニュー - ツールチップ",
|
||||
"Admin navbar items": "管理者ナビバー項目",
|
||||
"Admin navbar items - Tooltip": "管理者ナビバー項目 - ツールチップ",
|
||||
"All": "All",
|
||||
"Balance credit": "残高クレジット",
|
||||
"Balance credit - Tooltip": "残高クレジット - ツールチップ",
|
||||
"Balance currency": "残高通貨",
|
||||
"Balance currency - Tooltip": "残高通貨 - ツールチップ",
|
||||
"Edit Organization": "組織の編集",
|
||||
"Follow global theme": "グローバルテーマに従ってください",
|
||||
"Has privilege consent": "権限同意あり",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "ルールを変更する",
|
||||
"New Organization": "新しい組織",
|
||||
"Optional": "オプション",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "組織残高",
|
||||
"Org balance - Tooltip": "組織残高 - ツールチップ",
|
||||
"Password expire days": "パスワード有効期限(日)",
|
||||
"Password expire days - Tooltip": "パスワード有効期限(日) - ツールチップ",
|
||||
"Prompt": "プロンプト",
|
||||
@@ -778,10 +798,10 @@
|
||||
"Tags": "タグ",
|
||||
"Use Email as username": "メールアドレスをユーザー名として使用",
|
||||
"Use Email as username - Tooltip": "ユーザー名フィールドがサインアップ時に表示されない場合、メールアドレスをユーザー名として使用します",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User balance": "ユーザー残高",
|
||||
"User balance - Tooltip": "ユーザー残高 - ツールチップ",
|
||||
"User navbar items": "ユーザーナビバー項目",
|
||||
"User navbar items - Tooltip": "ユーザーナビバー項目 - ツールチップ",
|
||||
"User types": "ユーザータイプ",
|
||||
"User types - Tooltip": "ユーザータイプ - ツールチップ",
|
||||
"View rule": "ビュールール",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "請求書情報を慎重に確認してください。一度請求書が発行されると、取り下げまたは変更することはできません。",
|
||||
"Please pay the order first!": "最初に注文をお支払いください!",
|
||||
"Processing...": "処理中... ",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "商品 - ツールチップ",
|
||||
"Recharged successfully": "正常にチャージされました",
|
||||
"Result": "結果",
|
||||
"The payment has been canceled": "支払いがキャンセルされました",
|
||||
"The payment has failed": "支払いに失敗しました",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "支払いがタイムアウトしました",
|
||||
"The payment is still under processing": "支払いはまだ処理中です",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "支払いを表示",
|
||||
"You can view your order details or return to the order list": "注文詳細を表示するか、注文一覧に戻ることができます",
|
||||
"You have successfully completed the payment": "あなたは支払いを正常に完了しました",
|
||||
"You have successfully recharged": "正常にチャージされました",
|
||||
"Your current balance is": "現在の残高は",
|
||||
@@ -867,13 +887,15 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "プランを編集",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "新しいプラン",
|
||||
"Period": "期間",
|
||||
"Period - Tooltip": "期間",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "プラン名",
|
||||
"Price - Tooltip": "価格",
|
||||
"Related product": "関連製品",
|
||||
"View Plan": "View Plan",
|
||||
"View Plan": "プランを表示",
|
||||
"per month": "月毎",
|
||||
"per year": "年あたり"
|
||||
},
|
||||
@@ -883,55 +905,62 @@
|
||||
"Free": "無料",
|
||||
"Getting started": "はじめる",
|
||||
"New Pricing": "新しい価格設定",
|
||||
"Pricing name": "Pricing name",
|
||||
"Pricing name": "価格設定名",
|
||||
"Trial duration": "トライアル期間の長さ",
|
||||
"Trial duration - Tooltip": "トライアル期間の長さ",
|
||||
"View Pricing": "View Pricing",
|
||||
"View Pricing": "価格設定を表示",
|
||||
"days trial available!": "日間のトライアルが利用可能です!",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "有料ユーザーにアクティブまたは保留中のサブスクリプションがありません。購入するプランを選択してください"
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "カートに追加",
|
||||
"AirWallex": "エアウォレックス",
|
||||
"Alipay": "アリペイ",
|
||||
"Amount": "Amount",
|
||||
"Amount": "金額",
|
||||
"Buy": "購入",
|
||||
"Buy Product": "製品を購入する",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "任意金額を利用可能",
|
||||
"Custom price should be greater than zero": "カスタム価格は0より大きくする必要があります",
|
||||
"Detail - Tooltip": "製品の詳細",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Disable custom amount": "任意金額を無効にする",
|
||||
"Disable custom amount - Tooltip": "任意金額を無効にする - ツールチップ",
|
||||
"Dummy": "ダミー",
|
||||
"Edit Product": "製品を編集",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
"Failed to create order": "Failed to create order",
|
||||
"Enter preset amounts": "プリセット金額を入力",
|
||||
"Failed to create order": "注文の作成に失敗しました",
|
||||
"Image": "画像",
|
||||
"Image - Tooltip": "製品のイメージ",
|
||||
"Information": "Information",
|
||||
"Information": "情報",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "チャージ用か",
|
||||
"Is recharge - Tooltip": "現在の製品が残高をチャージするためかどうか",
|
||||
"Name": "Name",
|
||||
"New Product": "新製品",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "注文が正常に作成されました",
|
||||
"PayPal": "ペイパル",
|
||||
"Payment cancelled": "支払いキャンセル",
|
||||
"Payment failed": "支払い失敗",
|
||||
"Payment providers": "支払いプロバイダー",
|
||||
"Payment providers - Tooltip": "支払いサービスの提供者",
|
||||
"Placing order...": "注文をする...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please add at least one recharge option when custom amount is disabled": "任意金額が無効な場合は、少なくとも1つのチャージオプションを追加してください",
|
||||
"Please select a currency": "通貨を選択してください",
|
||||
"Please select at least one payment provider": "少なくとも1つの支払いプロバイダーを選択してください",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "支払い処理中...",
|
||||
"Product list cannot be empty": "商品リストを空にできません",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "量",
|
||||
"Quantity - Tooltip": "製品の量",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge options": "チャージオプション",
|
||||
"Recharge options - Tooltip": "チャージオプション - ツールチップ",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "戻りURL",
|
||||
"Return URL - Tooltip": "成功した購入後に戻るURL",
|
||||
"SKU": "SKU",
|
||||
"Select amount": "Select amount",
|
||||
"Select amount": "金額を選択",
|
||||
"Sold": "売れました",
|
||||
"Sold - Tooltip": "販売数量",
|
||||
"Stripe": "ストライプ",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "購入後に戻るURL",
|
||||
"Tag - Tooltip": "製品のタグ",
|
||||
"Test buy page..": "テスト購入ページ。",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "追加しようとしている商品の通貨がカート内の商品の通貨と異なります",
|
||||
"There is no payment channel for this product.": "この製品には支払いチャネルがありません。",
|
||||
"This product is currently not in sale.": "この製品は現在販売されていません。",
|
||||
"This product is currently not purchasable (No options available)": "This product is currently not purchasable (No options available)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"This product is currently not purchasable (No options available)": "この商品は現在購入できません(利用可能なオプションがありません)",
|
||||
"Total Price": "合計金額",
|
||||
"View Product": "商品を表示",
|
||||
"WeChat Pay": "微信支付"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "認証キー - ツールチップ",
|
||||
"Auth URL": "認証URL",
|
||||
"Auth URL - Tooltip": "認証URL",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "ベースURL",
|
||||
"Base URL - Tooltip": "ベースURL - ツールチップ",
|
||||
"Bucket": "バケツ",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "第二クライアント秘密鍵",
|
||||
"Content": "コンテンツ",
|
||||
"Content - Tooltip": "コンテンツ - ツールチップ",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "SSLを無効にする",
|
||||
"Disable SSL - Tooltip": "SMTPサーバーと通信する場合にSSLプロトコルを無効にするかどうか",
|
||||
"DB test": "DBテスト",
|
||||
"DB test - Tooltip": "DBテスト - ツールチップ",
|
||||
"Disable": "Disable",
|
||||
"Domain": "ドメイン",
|
||||
"Domain - Tooltip": "オブジェクトストレージのカスタムドメイン",
|
||||
"Edit Provider": "編集プロバイダー",
|
||||
@@ -1001,10 +1030,11 @@
|
||||
"Email regex - Tooltip": "メール正規表現 - ツールチップ",
|
||||
"Email title": "電子メールのタイトル",
|
||||
"Email title - Tooltip": "メールのタイトル",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "PKCEを有効にする",
|
||||
"Enable PKCE - Tooltip": "PKCEを有効にする - ツールチップ",
|
||||
"Enable proxy": "プロキシを有効にする",
|
||||
"Enable proxy - Tooltip": "メールまたはSMS送信時にsocks5プロキシを有効にする",
|
||||
"Endpoint": "エンドポイント",
|
||||
"Endpoint (Intranet)": "エンドポイント(イントラネット)",
|
||||
"Endpoint - Tooltip": "エンドポイント - ツールチップ",
|
||||
@@ -1031,13 +1061,13 @@
|
||||
"Key ID - Tooltip": "キーID",
|
||||
"Key text": "キーテキスト",
|
||||
"Key text - Tooltip": "キーテキスト",
|
||||
"LDAP port": "LDAP port",
|
||||
"LDAP port": "LDAPポート",
|
||||
"Metadata": "メタデータ",
|
||||
"Metadata - Tooltip": "SAMLのメタデータ",
|
||||
"Metadata url": "メタデータURL",
|
||||
"Metadata url - Tooltip": "メタデータURL - ツールチップ",
|
||||
"Method - Tooltip": "ログイン方法、QRコードまたはサイレントログイン",
|
||||
"Mobile": "Mobile",
|
||||
"Mobile": "モバイル",
|
||||
"New Provider": "新しい提供者",
|
||||
"Parameter": "パラメータ",
|
||||
"Parameter - Tooltip": "パラメータ - ツールチップ",
|
||||
@@ -1055,10 +1085,10 @@
|
||||
"Prompted": "促された",
|
||||
"Provider URL": "プロバイダーURL",
|
||||
"Provider URL - Tooltip": "サービスプロバイダーの設定用URL。このフィールドは参照用にのみ使用され、Casdoorでは使用されません",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "プロバイダーのテストに成功しました",
|
||||
"Public key": "公開鍵",
|
||||
"Public key - Tooltip": "公開鍵 - ツールチップ",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret of RADIUS",
|
||||
"RADIUS Shared Secret - Tooltip": "RADIUSの共有シークレット",
|
||||
"Region": "リージョン",
|
||||
"Region - Tooltip": "リージョン - ツールチップ",
|
||||
"Region ID": "地域ID",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - ツールチップ",
|
||||
"SP Entity ID": "SPエンティティID",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "シーン",
|
||||
"Scene - Tooltip": "シーン",
|
||||
"Scope": "範囲",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "秘密のアクセスキー",
|
||||
"Secret access key - Tooltip": "秘密のアクセスキー",
|
||||
"Secret key": "秘密鍵",
|
||||
@@ -1111,8 +1144,8 @@
|
||||
"Sub type - Tooltip": "サブタイプ",
|
||||
"Subject": "件名",
|
||||
"Subject - Tooltip": "メールの件名",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype": "サブタイプ",
|
||||
"Subtype - Tooltip": "サブタイプ - ツールチップ",
|
||||
"Syncer test": "同期テスト",
|
||||
"Syncer test - Tooltip": "同期テスト",
|
||||
"Team ID": "チームID",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "SMTP接続をテストする",
|
||||
"Third-party": "サードパーティ",
|
||||
"This field is required": "このフィールドは必須です",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "宛先アドレス",
|
||||
"To address - Tooltip": "「宛先」のメールアドレス",
|
||||
"Token URL": "トークンのURL",
|
||||
"Token URL - Tooltip": "トークンURL",
|
||||
"Use WeChat Media Platform in PC": "PCでWeChat Media Platformを使用",
|
||||
@@ -1146,7 +1179,7 @@
|
||||
"UserInfo URL - Tooltip": "ユーザー情報URL",
|
||||
"Wallets": "ウォレット",
|
||||
"Wallets - Tooltip": "ウォレット - ツールチップ",
|
||||
"Web": "Web",
|
||||
"Web": "ウェブ",
|
||||
"admin (Shared)": "管理者(共有)"
|
||||
},
|
||||
"record": {
|
||||
@@ -1197,7 +1230,7 @@
|
||||
"Please input your last name!": "あなたの姓を入力してください!",
|
||||
"Please input your phone number!": "あなたの電話番号を入力してください!",
|
||||
"Please input your real name!": "正しい名前を入力してください!",
|
||||
"Please input your {label}!": "Please input your {label}!",
|
||||
"Please input your {label}!": "{label}を入力してください!",
|
||||
"Please select your country code!": "あなたの国コードを選択してください!",
|
||||
"Please select your country/region!": "あなたの国/地域を選択してください!",
|
||||
"Regex": "正規表現",
|
||||
@@ -1210,7 +1243,7 @@
|
||||
"Text 4": "テキスト4",
|
||||
"Text 5": "テキスト5",
|
||||
"The input Email doesn't match the signup item regex!": "入力されたメールアドレスがサインアップ項目の正規表現と一致しません!",
|
||||
"The input doesn't match the signup item regex!": "The input doesn't match the signup item regex!",
|
||||
"The input doesn't match the signup item regex!": "入力内容がサインアップ項目の正規表現と一致しません!",
|
||||
"The input is not invoice Tax ID!": "入力されたものは請求書の税番号ではありません!",
|
||||
"The input is not invoice title!": "インプットは請求書タイトルではありません!",
|
||||
"The input is not valid Phone!": "この入力は有効な電話番号ではありません!",
|
||||
@@ -1230,26 +1263,29 @@
|
||||
"New Subscription": "新しいサブスクリプション",
|
||||
"Start time": "開始時刻",
|
||||
"Start time - Tooltip": "開始時刻",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Subscription plan": "サブスクリプションプラン",
|
||||
"Subscription pricing": "サブスクリプション価格設定",
|
||||
"Suspended": "一時停止",
|
||||
"Upcoming": "近日",
|
||||
"View Subscription": "View Subscription"
|
||||
"View Subscription": "サブスクリプションを表示"
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"Admin Email": "Admin Email",
|
||||
"API Token / Password": "APIトークン / パスワード",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "管理者メール",
|
||||
"Affiliation table": "所属テーブル",
|
||||
"Affiliation table - Tooltip": "作業単位のデータベーステーブル名",
|
||||
"Avatar base URL": "アバターベースURL",
|
||||
"Avatar base URL - Tooltip": "アバター画像のURLプレフィックス",
|
||||
"Bind DN": "Bind DN",
|
||||
"Bind DN": "バインドDN",
|
||||
"Casdoor column": "カスドアカラム",
|
||||
"Column name": "列名",
|
||||
"Column type": "コラムタイプ",
|
||||
"Connect successfully": "接続成功",
|
||||
"Corp ID": "Corp ID",
|
||||
"Corp secret": "Corp secret",
|
||||
"Corp ID": "企業ID",
|
||||
"Corp secret": "企業シークレット",
|
||||
"Database": "データベース",
|
||||
"Database - Tooltip": "元のデータベース名",
|
||||
"Database type": "データベースのタイプ",
|
||||
@@ -1263,15 +1299,15 @@
|
||||
"Is read-only": "読み取り専用か",
|
||||
"Is read-only - Tooltip": "読み取り専用か - ツールチップ",
|
||||
"New Syncer": "新しいシンクロナイザー",
|
||||
"Paste your Google Workspace service account JSON key here": "Paste your Google Workspace service account JSON key here",
|
||||
"SCIM Server URL": "SCIM Server URL",
|
||||
"Paste your Google Workspace service account JSON key here": "ここにGoogle WorkspaceサービスアカウントのJSONキーを貼り付けてください",
|
||||
"SCIM Server URL": "SCIMサーバーURL",
|
||||
"SSH host": "SSHホスト",
|
||||
"SSH password": "SSHパスワード",
|
||||
"SSH port": "SSHポート",
|
||||
"SSH user": "SSHユーザー",
|
||||
"SSL mode": "SSLモード",
|
||||
"SSL mode - Tooltip": "SSLモード",
|
||||
"Service account key": "Service account key",
|
||||
"Service account key": "サービスアカウントキー",
|
||||
"Sync interval": "同期の間隔",
|
||||
"Sync interval - Tooltip": "単位は秒です",
|
||||
"Table": "テーブル",
|
||||
@@ -1279,8 +1315,8 @@
|
||||
"Table columns": "テーブルの列",
|
||||
"Table columns - Tooltip": "データ同期に関与するテーブル列。同期に関与しない列は追加する必要がありません",
|
||||
"Test Connection": "接続をテスト",
|
||||
"Test DB Connection": "Test DB Connection",
|
||||
"Username (optional)": "Username (optional)"
|
||||
"Test DB Connection": "DB接続をテスト",
|
||||
"Username (optional)": "ユーザー名(任意)"
|
||||
},
|
||||
"system": {
|
||||
"API Latency": "API遅延",
|
||||
@@ -1311,16 +1347,16 @@
|
||||
"Theme - Tooltip": "アプリケーションのスタイルテーマ"
|
||||
},
|
||||
"ticket": {
|
||||
"Closed": "Closed",
|
||||
"Edit Ticket": "Edit Ticket",
|
||||
"In Progress": "In Progress",
|
||||
"Messages": "Messages",
|
||||
"New Ticket": "New Ticket",
|
||||
"Open": "Open",
|
||||
"Please enter a message": "Please enter a message",
|
||||
"Press Ctrl+Enter to send": "Press Ctrl+Enter to send",
|
||||
"Resolved": "Resolved",
|
||||
"Type your message here...": "Type your message here..."
|
||||
"Closed": "クローズ",
|
||||
"Edit Ticket": "チケットを編集",
|
||||
"In Progress": "進行中",
|
||||
"Messages": "メッセージ",
|
||||
"New Ticket": "新しいチケット",
|
||||
"Open": "オープン",
|
||||
"Please enter a message": "メッセージを入力してください",
|
||||
"Press Ctrl+Enter to send": "Ctrl+Enterで送信",
|
||||
"Resolved": "解決済み",
|
||||
"Type your message here...": "ここにメッセージを入力..."
|
||||
},
|
||||
"token": {
|
||||
"Access token": "アクセストークン",
|
||||
@@ -1342,7 +1378,7 @@
|
||||
"Amount - Tooltip": "取引製品の金額",
|
||||
"Edit Transaction": "取引を編集",
|
||||
"New Transaction": "新しい取引",
|
||||
"Recharge": "Recharge"
|
||||
"Recharge": "チャージ"
|
||||
},
|
||||
"user": {
|
||||
"3rd-party logins": "サードパーティログイン",
|
||||
@@ -1363,7 +1399,7 @@
|
||||
"Captcha Verify Success": "キャプチャを確認しました。成功しました",
|
||||
"City": "都市",
|
||||
"Country code": "国番号",
|
||||
"Country code - Tooltip": "Country code - Tooltip",
|
||||
"Country code - Tooltip": "国コード - ツールチップ",
|
||||
"Country/Region": "国/地域",
|
||||
"Country/Region - Tooltip": "国または地域",
|
||||
"Edit User": "ユーザーの編集",
|
||||
@@ -1386,10 +1422,10 @@
|
||||
"ID card type": "身分証タイプ",
|
||||
"ID card type - Tooltip": "身分証タイプ - ツールチップ",
|
||||
"ID card with person": "本人と身分証",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"ID verification": "本人確認",
|
||||
"ID verification - Tooltip": "本人確認 - ツールチップ",
|
||||
"Identity verification successful": "本人確認に成功しました",
|
||||
"Identity verified": "本人確認済み",
|
||||
"Input your email": "あなたのメールアドレスを入力してください",
|
||||
"Input your phone number": "電話番号を入力してください",
|
||||
"Is admin": "管理者ですか?",
|
||||
@@ -1399,7 +1435,7 @@
|
||||
"Is forbidden": "禁止されています",
|
||||
"Is forbidden - Tooltip": "禁止されたユーザーはこれ以上ログインできません",
|
||||
"Is online": "オンラインか",
|
||||
"Is verified": "Is verified",
|
||||
"Is verified": "確認済み",
|
||||
"Karma": "カルマ",
|
||||
"Karma - Tooltip": "カルマ - ツールチップ",
|
||||
"Keys": "鍵",
|
||||
@@ -1424,19 +1460,19 @@
|
||||
"Other": "その他",
|
||||
"Password set successfully": "パスワードの設定に成功しました",
|
||||
"Phone cannot be empty": "電話は空白にできません",
|
||||
"Please enter your real name": "Please enter your real name",
|
||||
"Please fill in ID card information first": "Please fill in ID card information first",
|
||||
"Please fill in your real name first": "Please fill in your real name first",
|
||||
"Please enter your real name": "実名を入力してください",
|
||||
"Please fill in ID card information first": "先に身分証情報を入力してください",
|
||||
"Please fill in your real name first": "先に実名を入力してください",
|
||||
"Please select avatar from resources": "リソースからアバターを選択してください",
|
||||
"Properties": "特性",
|
||||
"Properties - Tooltip": "ユーザーのプロパティー",
|
||||
"Ranking": "ランキング",
|
||||
"Ranking - Tooltip": "ランキング - ツールチップ",
|
||||
"Re-enter New": "新しく入り直す",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Real name - Tooltip": "実名 - ツールチップ",
|
||||
"Register source": "登録元",
|
||||
"Register source - Tooltip": "ユーザーが登録されたソース",
|
||||
"Register type": "登録タイプ",
|
||||
"Register type": "登録方法",
|
||||
"Register type - Tooltip": "ユーザーを登録するために使用される方法",
|
||||
"Reset Email...": "リセットメール...",
|
||||
"Reset Phone...": "リセットします...",
|
||||
@@ -1462,8 +1498,8 @@
|
||||
"User Profile": "ユーザープロフィール",
|
||||
"Values": "価値観",
|
||||
"Verification code sent": "確認コードを送信しました",
|
||||
"Verified": "Verified",
|
||||
"Verify Identity": "Verify Identity",
|
||||
"Verified": "確認済み",
|
||||
"Verify Identity": "本人確認",
|
||||
"WebAuthn credentials": "WebAuthnの資格情報",
|
||||
"Work": "職場",
|
||||
"You have changed the username, please save your change first before modifying the password": "ユーザー名を変更しました。パスワードを変更する前に、変更を保存してください",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "Sair da impersonação",
|
||||
"Logout": "Sair",
|
||||
"My Account": "Minha Conta",
|
||||
"Sign Up": "Cadastrar-se"
|
||||
@@ -22,22 +22,22 @@
|
||||
"Add Face ID with Image": "Adicionar Face ID com imagem",
|
||||
"Always": "Sempre",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Authentication": "Autenticação",
|
||||
"Auto signin": "Login automático",
|
||||
"Auto signin - Tooltip": "Quando uma sessão logada existe no Casdoor, ela é automaticamente usada para o login no lado da aplicação",
|
||||
"Background URL": "URL de Fundo",
|
||||
"Background URL - Tooltip": "URL da imagem de fundo usada na página de login",
|
||||
"Background URL Mobile": "URL de fundo para dispositivos móveis",
|
||||
"Background URL Mobile - Tooltip": "URL da imagem de fundo para dispositivos móveis",
|
||||
"Basic": "Basic",
|
||||
"Basic": "Básico",
|
||||
"Big icon": "Ícone grande",
|
||||
"Binding providers": "Provedores de vinculação",
|
||||
"CSS style": "Estilo CSS",
|
||||
"Center": "Centro",
|
||||
"Code resend timeout": "Tempo limite de reenvio de código",
|
||||
"Code resend timeout - Tooltip": "Período de tempo (em segundos) que os usuários devem esperar antes de solicitar outro código de verificação. Defina como 0 para usar o padrão global (60 segundos)",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Expiração do cookie",
|
||||
"Cookie expire - Tooltip": "Tempo de expiração do cookie - Dica",
|
||||
"Copy SAML metadata URL": "Copiar URL de metadados SAML",
|
||||
"Copy prompt page URL": "Copiar URL da página de prompt",
|
||||
"Copy signin page URL": "Copiar URL da página de login",
|
||||
@@ -47,9 +47,9 @@
|
||||
"Custom CSS - Tooltip": "Estilização CSS dos formulários de registro, login e recuperação de senha (por exemplo, adicionando bordas e sombras)",
|
||||
"Custom CSS Mobile": "CSS personalizado para dispositivos móveis",
|
||||
"Custom CSS Mobile - Edit": "Editar CSS personalizado para dispositivos móveis",
|
||||
"Custom CSS Mobile - Tooltip": "CSS personalizado para dispositivos móveis",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Custom CSS Mobile - Tooltip": "CSS personalizado para dispositivos móveis - Dica",
|
||||
"Disable SAML attributes": "Desativar atributos SAML",
|
||||
"Disable SAML attributes - Tooltip": "Se deve desativar atributos SAML - Dica",
|
||||
"Disable signin": "Desativar login",
|
||||
"Disable signin - Tooltip": "Desativar login para usuários",
|
||||
"Dynamic": "Dinâmico",
|
||||
@@ -60,16 +60,17 @@
|
||||
"Enable SAML C14N10 - Tooltip": "Use C14N10 em vez de C14N11 no SAML",
|
||||
"Enable SAML POST binding": "Ativar vinculação SAML POST",
|
||||
"Enable SAML POST binding - Tooltip": "A vinculação por POST HTTP usa campos de formulário HTML para enviar mensagens SAML. Ative quando seu SP a utilizar.",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "Ativar assinatura da asserção SAML",
|
||||
"Enable SAML assertion signature - Tooltip": "Se deve assinar a asserção SAML - Dica",
|
||||
"Enable SAML compression": "Ativar compressão SAML",
|
||||
"Enable SAML compression - Tooltip": "Se deve comprimir as mensagens de resposta SAML quando o Casdoor é usado como provedor de identidade SAML",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "Ativar login exclusivo",
|
||||
"Enable exclusive signin - Tooltip": "Quando o login exclusivo está ativado, o usuário não pode ter várias sessões ativas",
|
||||
"Enable side panel": "Ativar painel lateral",
|
||||
"Enable signin session - Tooltip": "Se o Casdoor mantém uma sessão depois de fazer login no Casdoor a partir da aplicação",
|
||||
"Enable signup": "Ativar registro",
|
||||
"Enable signup - Tooltip": "Se permite que os usuários registrem uma nova conta",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Tempo de bloqueio após falha de login",
|
||||
"Failed signin frozen time - Tooltip": "Tempo em que a conta fica congelada após tentativas de login falhadas",
|
||||
"Failed signin limit": "Limite de tentativas de login falhadas",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "Logout realizado com sucesso",
|
||||
"MFA remember time": "Tempo de lembrar MFA",
|
||||
"MFA remember time - Tooltip": "Configura a duração pela qual uma conta é lembrada como confiável após um login MFA bem-sucedido",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "Modo do menu",
|
||||
"Menu mode - Tooltip": "Modo do menu - Dica",
|
||||
"Multiple Choices": "Múltipla escolha",
|
||||
"New Application": "Nova Aplicação",
|
||||
"No verification": "Sem verificação",
|
||||
@@ -111,48 +112,59 @@
|
||||
"Order": "Ordem",
|
||||
"Order - Tooltip": "Quanto menor o valor, maior a classificação na página de Aplicativos",
|
||||
"Org choice mode": "Modo de escolha da organização",
|
||||
"Org choice mode - Tooltip": "Modo de escolha de organização",
|
||||
"Org choice mode - Tooltip": "Método usado para selecionar a organização para fazer login - Dica",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Por favor, habilite a \"Sessão de login\" primeiro antes de habilitar o \"Login automático\"",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "Por favor, insira o nome da sua aplicação!",
|
||||
"Please input your organization!": "Por favor, insira o nome da sua organização!",
|
||||
"Please select a HTML file": "Por favor, selecione um arquivo HTML",
|
||||
"Pop up": "Abrir em pop-up",
|
||||
"Providers": "Providers",
|
||||
"Providers": "Provedores",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "Aleatório",
|
||||
"Real name": "Nome real",
|
||||
"Redirect URL": "URL de redirecionamento",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redirecionamento (URL de ligação de postagem de serviço do consumidor de afirmação)",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redirecionamento (URL de ligação de postagem de serviço do consumidor de afirmação) - Dica",
|
||||
"Redirect URLs": "URLs de redirecionamento",
|
||||
"Redirect URLs - Tooltip": "Lista de URLs de redirecionamento permitidos, com suporte à correspondência por expressões regulares; URLs que não estão na lista falharão ao redirecionar",
|
||||
"Refresh token expire": "Expiração do token de atualização",
|
||||
"Refresh token expire - Tooltip": "Tempo de expiração do token de atualização",
|
||||
"Reset to Empty": "Redefinir para vazio",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "Direita",
|
||||
"Rule": "Regra",
|
||||
"SAML hash algorithm": "Algoritmo de hash SAML",
|
||||
"SAML hash algorithm - Tooltip": "Algoritmo de hash para assinatura SAML",
|
||||
"SAML metadata": "Metadados do SAML",
|
||||
"SAML metadata - Tooltip": "Os metadados do protocolo SAML",
|
||||
"SAML metadata - Tooltip": "Os metadados do protocolo SAML - Dica",
|
||||
"SAML reply URL": "URL de resposta do SAML",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "Segurança",
|
||||
"Select": "Selecionar",
|
||||
"Side panel HTML": "HTML do painel lateral",
|
||||
"Side panel HTML - Edit": "Editar HTML do painel lateral",
|
||||
"Side panel HTML - Tooltip": "Personalize o código HTML para o painel lateral da página de login",
|
||||
"Side panel HTML - Tooltip": "Personalize o código HTML do painel lateral da página de login - Dica",
|
||||
"Sign Up Error": "Erro ao Registrar",
|
||||
"Signin": "Entrar",
|
||||
"Signin (Default True)": "Login (Padrão: Verdadeiro)",
|
||||
"Signin items": "Itens de login",
|
||||
"Signin items - Tooltip": "Itens de login",
|
||||
"Signin items - Tooltip": "Itens de login - Dica",
|
||||
"Signin methods": "Métodos de login",
|
||||
"Signin methods - Tooltip": "Dica: métodos de login",
|
||||
"Signin methods - Tooltip": "Dica: métodos de login - Dica",
|
||||
"Signin session": "Sessão de login",
|
||||
"Signup items": "Itens de registro",
|
||||
"Signup items - Tooltip": "Itens para os usuários preencherem ao registrar novas contas",
|
||||
"Signup items - Tooltip": "Itens para os usuários preencherem ao fazer login - Dica",
|
||||
"Single Choice": "Escolha única",
|
||||
"Small icon": "Ícone pequeno",
|
||||
"Static Value": "Static Value",
|
||||
"String": "String",
|
||||
"Tags - Tooltip": "Apenas usuários com a tag listada nas tags da aplicação podem fazer login",
|
||||
"Tags - Tooltip": "Apenas usuários com a tag listada nas tags da aplicação podem fazer login - Dica",
|
||||
"The application does not allow to sign up new account": "A aplicação não permite o registro de novas contas",
|
||||
"Token expire": "Expiração do Token",
|
||||
"Token expire - Tooltip": "Tempo de expiração do token de acesso",
|
||||
@@ -162,7 +174,9 @@
|
||||
"Token format - Tooltip": "O formato do token de acesso",
|
||||
"Token signing method": "Método de assinatura do token",
|
||||
"Token signing method - Tooltip": "Método de assinatura do token JWT. Deve ser o mesmo algoritmo do certificado.",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "Personalização da interface",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "Usar e-mail como NameID",
|
||||
"Use Email as NameID - Tooltip": "Dica: usar e-mail como NameID",
|
||||
"Vertical": "Vertical",
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "Largura"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "Um usuário comum só pode modificar a permissão enviada por ele mesmo",
|
||||
"AI Assistant": "Assistente de IA",
|
||||
"API key": "Chave da API",
|
||||
"API key - Tooltip": "Chave da API para acessar o serviço",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "Negócios e Pagamentos",
|
||||
"Cancel": "Cancelar",
|
||||
"Captcha": "Captcha",
|
||||
"Cart": "Cart",
|
||||
"Cart": "Carrinho",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "Certificado",
|
||||
"Cert - Tooltip": "O certificado da chave pública que precisa ser verificado pelo SDK do cliente correspondente a esta aplicação",
|
||||
"Certs": "Certificados",
|
||||
"Clear": "Clear",
|
||||
"Clear": "Limpar",
|
||||
"Click to Upload": "Clique para Enviar",
|
||||
"Client IP": "IP do cliente",
|
||||
"Close": "Fechar",
|
||||
@@ -307,12 +323,12 @@
|
||||
"Delete": "Excluir",
|
||||
"Description": "Descrição",
|
||||
"Description - Tooltip": "Informações de descrição detalhadas para referência, o Casdoor em si não irá utilizá-las",
|
||||
"Detail": "详情",
|
||||
"Detail": "Detalhes",
|
||||
"Disable": "Desabilitar",
|
||||
"Display name": "Nome de exibição",
|
||||
"Display name - Tooltip": "Um nome amigável e facilmente legível exibido publicamente na interface do usuário",
|
||||
"Down": "Descer",
|
||||
"Download template": "Download template",
|
||||
"Download template": "Baixar modelo",
|
||||
"Edit": "Editar",
|
||||
"Email": "E-mail",
|
||||
"Email - Tooltip": "Endereço de e-mail válido",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "Ativado com sucesso",
|
||||
"Enforcers": "Aplicadores",
|
||||
"Failed to add": "Falha ao adicionar",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "Falha ao cancelar",
|
||||
"Failed to connect to server": "Falha ao conectar ao servidor",
|
||||
"Failed to copy": "Falha ao copiar",
|
||||
"Failed to delete": "Falha ao excluir",
|
||||
"Failed to enable": "Falha ao ativar",
|
||||
"Failed to get": "Falha ao obter",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "Falha ao carregar",
|
||||
"Failed to log out": "Falha ao sair",
|
||||
"Failed to remove": "Falha ao remover",
|
||||
"Failed to save": "Falha ao salvar",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "Falha ao enviar",
|
||||
"Failed to sync": "Falha ao sincronizar",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "Falha ao desvincular",
|
||||
"Failed to update": "Falha ao atualizar",
|
||||
"Failed to upload": "Falha ao enviar",
|
||||
"Failed to verify": "Falha ao verificar",
|
||||
"False": "Falso",
|
||||
"Favicon": "Ícone do site",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "URL personalizada para a página de \"Esqueci a senha\". Se não definido, será usada a página padrão de \"Esqueci a senha\" do Casdoor. Quando definido, o link de \"Esqueci a senha\" na página de login será redirecionado para esta URL",
|
||||
"Forms": "Formulários",
|
||||
"Found some texts still not translated? Please help us translate at": "Encontrou algum texto ainda não traduzido? Ajude-nos a traduzir em",
|
||||
"Generate": "Generate",
|
||||
"Generate": "Gerar",
|
||||
"Go to enable": "Ir para ativar",
|
||||
"Go to writable demo site?": "Acessar o site de demonstração gravável?",
|
||||
"Groups": "Grupos",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "Lista de IPs permitidos",
|
||||
"IP whitelist - Tooltip": "Lista branca de IP",
|
||||
"Identity": "Identidade",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "Impersonação",
|
||||
"Invitations": "Convites",
|
||||
"Is enabled": "Está habilitado",
|
||||
"Is enabled - Tooltip": "Define se está habilitado",
|
||||
@@ -381,7 +397,7 @@
|
||||
"Last name - Tooltip": "O sobrenome do usuário",
|
||||
"Later": "Depois",
|
||||
"Logging & Auditing": "Registro e Auditoria",
|
||||
"Login page": "Login page",
|
||||
"Login page": "Página de login",
|
||||
"Logo": "Logotipo",
|
||||
"Logo - Tooltip": "Ícones que o aplicativo apresenta para o mundo externo",
|
||||
"Logo dark": "Logo escuro",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "Nome",
|
||||
"Name - Tooltip": "ID único em formato de string",
|
||||
"Name format": "Formato do nome",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "Nenhum produto disponível",
|
||||
"No sheets found in file": "Nenhuma planilha encontrada no arquivo",
|
||||
"No verification method": "Nenhum método de verificação",
|
||||
"Non-LDAP": "Não-LDAP",
|
||||
"None": "Nenhum",
|
||||
"OAuth providers": "Provedores OAuth",
|
||||
"OFF": "DESLIGADO",
|
||||
"OK": "OK",
|
||||
"ON": "LIGADO",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "Apenas 1 método de MFA pode ser exigido",
|
||||
"Or": "Ou",
|
||||
"Orders": "Pedidos",
|
||||
"Organization": "Organização",
|
||||
"Organization - Tooltip": "Semelhante a conceitos como inquilinos ou grupos de usuários, cada usuário e aplicativo pertence a uma organização",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "A organização está vazia",
|
||||
"Organizations": "Organizações",
|
||||
"Password": "Senha",
|
||||
"Password - Tooltip": "Certifique-se de que a senha está correta",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "Número de telefone",
|
||||
"Phone only": "Apenas telefone",
|
||||
"Phone or Email": "Telefone ou e-mail",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "Fazer pedido",
|
||||
"Plain": "Simples",
|
||||
"Plan": "Plano",
|
||||
"Plan - Tooltip": "Plano de assinatura",
|
||||
"Plans": "Kế hoạch",
|
||||
"Plans": "Planos",
|
||||
"Plans - Tooltip": "Dica: planos",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "Por favor, conclua o captcha corretamente",
|
||||
"Please input your search": "Por favor, insira sua busca",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "Por favor, selecione pelo menos 1 usuário primeiro",
|
||||
"Preview": "Visualizar",
|
||||
"Preview - Tooltip": "Visualizar os efeitos configurados",
|
||||
"Pricing": "Preços",
|
||||
"Pricing - Tooltip": "Dica: preços",
|
||||
"Pricings": "Bảng giá",
|
||||
"Product Store": "Product Store",
|
||||
"Pricings": "Tabelas de preços",
|
||||
"Product Store": "Loja de produtos",
|
||||
"Products": "Produtos",
|
||||
"Provider": "Provedor",
|
||||
"Provider - Tooltip": "Provedores de pagamento a serem configurados, incluindo PayPal, Alipay, WeChat Pay, etc.",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "Tipo de autenticação para conexão SSH",
|
||||
"Save": "Salvar",
|
||||
"Save & Exit": "Salvar e Sair",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Buscar",
|
||||
"Send": "Enviar",
|
||||
"Session ID": "ID da sessão",
|
||||
@@ -494,12 +512,12 @@
|
||||
"State": "Estado",
|
||||
"State - Tooltip": "Estado",
|
||||
"Status": "Status",
|
||||
"Subscriptions": "Đăng ký",
|
||||
"Subscriptions": "Assinaturas",
|
||||
"Successfully added": "Adicionado com sucesso",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "Cancelado com sucesso",
|
||||
"Successfully copied": "Copiado com sucesso",
|
||||
"Successfully deleted": "Excluído com sucesso",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "Executado com sucesso",
|
||||
"Successfully removed": "Removido com sucesso",
|
||||
"Successfully saved": "Salvo com sucesso",
|
||||
"Successfully sent": "Enviado com sucesso",
|
||||
@@ -514,12 +532,12 @@
|
||||
"Syncers": "Sincronizadores",
|
||||
"System Info": "Informações do Sistema",
|
||||
"Tab": "Aba",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "As ações não podem estar vazias",
|
||||
"The resources cannot be empty": "Os recursos não podem estar vazios",
|
||||
"The users and roles cannot be empty at the same time": "Os usuários e as funções não podem estar vazios ao mesmo tempo",
|
||||
"There was a problem signing you in..": "Ocorreu um problema ao fazer login...",
|
||||
"This is a read-only demo site!": "Este é um site de demonstração apenas para leitura!",
|
||||
"Tickets": "Tickets",
|
||||
"Tickets": "Chamados",
|
||||
"Timestamp": "Carimbo de data/hora",
|
||||
"Title": "Título",
|
||||
"Title - Tooltip": "Título",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "Transações",
|
||||
"True": "Verdadeiro",
|
||||
"Type": "Tipo",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "Link da URL",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "Nome de aplicação desconhecido",
|
||||
"Unknown authentication type": "Tipo de autenticação desconhecido",
|
||||
"Up": "Acima",
|
||||
"Updated time": "Hora da atualização",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"Upload (.xlsx)": "Enviar (.xlsx)",
|
||||
"User": "Usuário",
|
||||
"User - Tooltip": "Certifique-se de que o nome de usuário esteja correto",
|
||||
"User Management": "Gerenciamento de usuários",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "O usuário já existe",
|
||||
"User containers": "Pools de Usuários",
|
||||
"User type": "Tipo de Usuário",
|
||||
"User type - Tooltip": "Tags às quais o usuário pertence, com valor padrão de \"usuário-normal\"",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "Dica: usuários",
|
||||
"Users under all organizations": "Usuários em todas as organizações",
|
||||
"Verifications": "Verificações",
|
||||
"View": "View",
|
||||
"View": "Ver",
|
||||
"Webhooks": "Webhooks",
|
||||
"You can only select one physical group": "Você só pode selecionar um grupo físico",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "Você deve selecionar uma imagem primeiro",
|
||||
"empty": "vazio",
|
||||
"remove": "remover",
|
||||
"{total} in total": "{total} no total"
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "Por favor, confirme as informações abaixo",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "Por favor, salve este código de recuperação. Se seu dispositivo não puder fornecer um código de autenticação, você poderá redefinir a autenticação MFA com este código",
|
||||
"Protect your account with Multi-factor authentication": "Proteja sua conta com autenticação multifator",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "Destinatário de notificação push",
|
||||
"Recovery code": "Código de recuperação",
|
||||
"Remember this account for {hour} hours": "Lembrar desta conta por {hour} horas",
|
||||
"Scan the QR code with your Authenticator App": "Escaneie o código QR com seu aplicativo autenticador",
|
||||
@@ -708,17 +727,17 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "Para garantir a segurança da sua conta, é obrigatório ativar a autenticação multifator",
|
||||
"Use Authenticator App": "Usar aplicativo autenticador",
|
||||
"Use Email": "Usar e-mail",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "Usar notificação push",
|
||||
"Use Radius": "Usar RADIUS",
|
||||
"Use SMS": "Usar SMS",
|
||||
"Use SMS verification code": "Usar código de verificação por SMS",
|
||||
"Use a recovery code": "Usar código de recuperação",
|
||||
"Verify Code": "Verificar código",
|
||||
"Verify Password": "Verificar senha",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "Você ativou a autenticação multifator. Por favor, clique em 'Enviar código' para continuar",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "Você ativou a autenticação multifator. Por favor, insira a senha do RADIUS",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "Você ativou a autenticação multifator. Por favor, insira o código TOTP",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "Você ativou a autenticação multifator. Por favor, insira o código de verificação da notificação push",
|
||||
"Your email is": "Seu e-mail é",
|
||||
"Your phone is": "Seu telefone é",
|
||||
"preferred": "preferido"
|
||||
@@ -732,29 +751,30 @@
|
||||
"New Model": "Novo Modelo"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "Hora do cancelamento",
|
||||
"Edit Order": "Editar Pedido",
|
||||
"New Order": "Novo Pedido",
|
||||
"Order not found": "Pedido não encontrado",
|
||||
"Pay": "Pagar",
|
||||
"Payment failed time": "Hora da falha no pagamento",
|
||||
"Payment time": "Hora do pagamento",
|
||||
"Price": "Preço",
|
||||
"Return to Order List": "Voltar para a lista de pedidos",
|
||||
"Timeout time": "Tempo limite",
|
||||
"View Order": "Ver Pedido"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "Itens da Conta",
|
||||
"Account items - Tooltip": "Itens na página de Configurações Pessoais",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Account menu": "Menu da conta",
|
||||
"Account menu - Tooltip": "Dica: menu da conta",
|
||||
"Admin navbar items": "Itens da barra de navegação do administrador",
|
||||
"Admin navbar items - Tooltip": "Dica: itens da barra de navegação do administrador",
|
||||
"All": "All",
|
||||
"Balance credit": "Saldo de créditos",
|
||||
"Balance credit - Tooltip": "Dica: saldo de créditos",
|
||||
"Balance currency": "Moeda do saldo",
|
||||
"Balance currency - Tooltip": "Dica: moeda do saldo",
|
||||
"Edit Organization": "Editar Organização",
|
||||
"Follow global theme": "Seguir tema global",
|
||||
"Has privilege consent": "Tem consentimento de privilégio",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "Modificar regra",
|
||||
"New Organization": "Nova Organização",
|
||||
"Optional": "Opcional",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "Saldo da organização",
|
||||
"Org balance - Tooltip": "Dica: saldo da organização",
|
||||
"Password expire days": "Dias para expiração da senha",
|
||||
"Password expire days - Tooltip": "Dica: dias para expiração da senha",
|
||||
"Prompt": "Prompt",
|
||||
@@ -778,10 +798,10 @@
|
||||
"Tags": "Etiquetas",
|
||||
"Use Email as username": "Usar e-mail como nome de usuário",
|
||||
"Use Email as username - Tooltip": "Usar e-mail como nome de usuário se o campo de nome de usuário não estiver visível no cadastro",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User balance": "Saldo do usuário",
|
||||
"User balance - Tooltip": "Dica: saldo do usuário",
|
||||
"User navbar items": "Itens da barra de navegação do usuário",
|
||||
"User navbar items - Tooltip": "Dica: itens da barra de navegação do usuário",
|
||||
"User types": "Tipos de usuário",
|
||||
"User types - Tooltip": "Dica: tipos de usuário",
|
||||
"View rule": "Ver regra",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Por favor, verifique cuidadosamente as informações da sua fatura. Uma vez emitida, a fatura não pode ser cancelada ou modificada.",
|
||||
"Please pay the order first!": "Por favor, faça o pagamento do pedido primeiro!",
|
||||
"Processing...": "Processando...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "Dica: produtos",
|
||||
"Recharged successfully": "Recarregado com sucesso",
|
||||
"Result": "Resultado",
|
||||
"The payment has been canceled": "O pagamento foi cancelado",
|
||||
"The payment has failed": "O pagamento falhou",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "O pagamento expirou",
|
||||
"The payment is still under processing": "O pagamento ainda está sendo processado",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "Ver Pagamento",
|
||||
"You can view your order details or return to the order list": "Você pode ver os detalhes do seu pedido ou voltar para a lista de pedidos",
|
||||
"You have successfully completed the payment": "Você concluiu o pagamento com sucesso",
|
||||
"You have successfully recharged": "Você recarregou com sucesso",
|
||||
"Your current balance is": "Seu saldo atual é",
|
||||
@@ -867,71 +887,80 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Editar Plano",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "Novo Plano",
|
||||
"Period": "Período",
|
||||
"Period - Tooltip": "Período",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "Nome do plano",
|
||||
"Price - Tooltip": "Preço",
|
||||
"Related product": "Produto relacionado",
|
||||
"View Plan": "View Plan",
|
||||
"per month": "mỗi tháng",
|
||||
"View Plan": "Ver Plano",
|
||||
"per month": "por mês",
|
||||
"per year": "por ano"
|
||||
},
|
||||
"pricing": {
|
||||
"Copy pricing page URL": "Sao chép URL trang bảng giá",
|
||||
"Copy pricing page URL": "Copiar URL da página de preços",
|
||||
"Edit Pricing": "Editar Preço",
|
||||
"Free": "Miễn phí",
|
||||
"Getting started": "Bắt đầu",
|
||||
"Free": "Gratuito",
|
||||
"Getting started": "Começar",
|
||||
"New Pricing": "Novo Preço",
|
||||
"Pricing name": "Pricing name",
|
||||
"Trial duration": "Thời gian thử nghiệm",
|
||||
"Trial duration - Tooltip": "Thời gian thử nghiệm",
|
||||
"View Pricing": "View Pricing",
|
||||
"days trial available!": "ngày dùng thử có sẵn!",
|
||||
"Pricing name": "Nome do preço",
|
||||
"Trial duration": "Duração do teste",
|
||||
"Trial duration - Tooltip": "Dica: duração do teste",
|
||||
"View Pricing": "Ver Preço",
|
||||
"days trial available!": "dias de teste disponíveis!",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "usuário pago não tem assinatura ativa ou pendente, por favor selecione um plano para comprar"
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "Adicionar ao carrinho",
|
||||
"AirWallex": "AirWallex",
|
||||
"Alipay": "Alipay",
|
||||
"Amount": "Amount",
|
||||
"Amount": "Valor",
|
||||
"Buy": "Comprar",
|
||||
"Buy Product": "Comprar Produto",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Valor personalizado disponível",
|
||||
"Custom price should be greater than zero": "O preço personalizado deve ser maior que zero",
|
||||
"Detail - Tooltip": "Detalhes do produto",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Dummy": "Dummy",
|
||||
"Disable custom amount": "Desativar valor personalizado",
|
||||
"Disable custom amount - Tooltip": "Dica: desativar valor personalizado",
|
||||
"Dummy": "Fictício",
|
||||
"Edit Product": "Editar Produto",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
"Failed to create order": "Failed to create order",
|
||||
"Enter preset amounts": "Inserir valores predefinidos",
|
||||
"Failed to create order": "Falha ao criar pedido",
|
||||
"Image": "Imagem",
|
||||
"Image - Tooltip": "Imagem do produto",
|
||||
"Information": "Information",
|
||||
"Information": "Informações",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "É recarga",
|
||||
"Is recharge - Tooltip": "Se o produto atual é para recarregar saldo",
|
||||
"Name": "Name",
|
||||
"New Product": "Novo Produto",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Pedido criado com sucesso",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "Pagamento cancelado",
|
||||
"Payment failed": "Pagamento falhou",
|
||||
"Payment providers": "Provedores de Pagamento",
|
||||
"Payment providers - Tooltip": "Fornecedores de serviços de pagamento",
|
||||
"Placing order...": "Processando pedido...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Por favor, adicione pelo menos uma opção de recarga quando o valor personalizado estiver desativado",
|
||||
"Please select a currency": "Por favor, selecione uma moeda",
|
||||
"Please select at least one payment provider": "Por favor, selecione pelo menos um provedor de pagamento",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Processando pagamento...",
|
||||
"Product list cannot be empty": "A lista de produtos não pode estar vazia",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Quantidade",
|
||||
"Quantity - Tooltip": "Quantidade do produto",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge options": "Opções de recarga",
|
||||
"Recharge options - Tooltip": "Dica: opções de recarga",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "URL de Retorno",
|
||||
"Return URL - Tooltip": "URL para retornar após a compra bem-sucedida",
|
||||
"SKU": "SKU",
|
||||
"Select amount": "Select amount",
|
||||
"Select amount": "Selecionar valor",
|
||||
"Sold": "Vendido",
|
||||
"Sold - Tooltip": "Quantidade vendida",
|
||||
"Stripe": "Stripe",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "URL para retornar após compra",
|
||||
"Tag - Tooltip": "Tag do produto",
|
||||
"Test buy page..": "Página de teste de compra...",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "A moeda do produto que você está adicionando é diferente da moeda dos itens no carrinho",
|
||||
"There is no payment channel for this product.": "Não há canal de pagamento disponível para este produto.",
|
||||
"This product is currently not in sale.": "Este produto não está disponível para venda no momento.",
|
||||
"This product is currently not purchasable (No options available)": "This product is currently not purchasable (No options available)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"This product is currently not purchasable (No options available)": "Este produto não pode ser comprado no momento (nenhuma opção disponível)",
|
||||
"Total Price": "Preço total",
|
||||
"View Product": "Ver Produto",
|
||||
"WeChat Pay": "WeChat Pay"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Dica: chave de autenticação",
|
||||
"Auth URL": "URL de autenticação",
|
||||
"Auth URL - Tooltip": "URL de autenticação",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "URL base",
|
||||
"Base URL - Tooltip": "Dica: URL base",
|
||||
"Bucket": "Bucket",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "A segunda chave secreta do cliente",
|
||||
"Content": "Conteúdo",
|
||||
"Content - Tooltip": "Dica: conteúdo",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "Desabilitar SSL",
|
||||
"Disable SSL - Tooltip": "Se deve desabilitar o protocolo SSL ao comunicar com o servidor SMTP",
|
||||
"DB test": "Teste do banco de dados",
|
||||
"DB test - Tooltip": "Dica: teste do banco de dados",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Domínio",
|
||||
"Domain - Tooltip": "Domínio personalizado para armazenamento de objetos",
|
||||
"Edit Provider": "Editar Provedor",
|
||||
@@ -1001,10 +1030,11 @@
|
||||
"Email regex - Tooltip": "Dica: regex de e-mail",
|
||||
"Email title": "Título do e-mail",
|
||||
"Email title - Tooltip": "Título do e-mail",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "Ativar PKCE",
|
||||
"Enable PKCE - Tooltip": "Dica: ativar PKCE",
|
||||
"Enable proxy": "Ativar proxy",
|
||||
"Enable proxy - Tooltip": "Ativar proxy socks5 ao enviar e-mail ou SMS",
|
||||
"Endpoint": "Endpoint",
|
||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||
"Endpoint - Tooltip": "Dica: endpoint",
|
||||
@@ -1031,13 +1061,13 @@
|
||||
"Key ID - Tooltip": "ID da chave",
|
||||
"Key text": "Texto da chave",
|
||||
"Key text - Tooltip": "Texto da chave",
|
||||
"LDAP port": "LDAP port",
|
||||
"LDAP port": "Porta LDAP",
|
||||
"Metadata": "Metadados",
|
||||
"Metadata - Tooltip": "Metadados SAML",
|
||||
"Metadata url": "URL de metadados",
|
||||
"Metadata url - Tooltip": "Dica: URL de metadados",
|
||||
"Method - Tooltip": "Método de login, código QR ou login silencioso",
|
||||
"Mobile": "Mobile",
|
||||
"Mobile": "Dispositivo móvel",
|
||||
"New Provider": "Novo Provedor",
|
||||
"Parameter": "Parâmetro",
|
||||
"Parameter - Tooltip": "Dica: parâmetro",
|
||||
@@ -1055,10 +1085,10 @@
|
||||
"Prompted": "Solicitado",
|
||||
"Provider URL": "URL do Provedor",
|
||||
"Provider URL - Tooltip": "URL para configurar o provedor de serviço, este campo é apenas usado para referência e não é usado no Casdoor",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "Teste do provedor bem-sucedido",
|
||||
"Public key": "Chave pública",
|
||||
"Public key - Tooltip": "Dica: chave pública",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret of RADIUS",
|
||||
"RADIUS Shared Secret - Tooltip": "Segredo compartilhado do RADIUS",
|
||||
"Region": "Região",
|
||||
"Region - Tooltip": "Dica: região",
|
||||
"Region ID": "ID da Região",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "URL SP ACS",
|
||||
"SP ACS URL - Tooltip": "URL SP ACS",
|
||||
"SP Entity ID": "ID da Entidade SP",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Cenário",
|
||||
"Scene - Tooltip": "Cenário",
|
||||
"Scope": "Escopo",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Chave de acesso secreta",
|
||||
"Secret access key - Tooltip": "Chave de acesso secreta",
|
||||
"Secret key": "Chave secreta",
|
||||
@@ -1091,7 +1124,7 @@
|
||||
"Service ID identifier": "Identificador do ID do serviço",
|
||||
"Service ID identifier - Tooltip": "Identificador do ID do serviço",
|
||||
"Service account JSON": "JSON da conta de serviço",
|
||||
"Service account JSON - Tooltip": "Service account JSON - Tooltip",
|
||||
"Service account JSON - Tooltip": "Dica: JSON da conta de serviço",
|
||||
"Sign Name": "Nome do Sinal",
|
||||
"Sign Name - Tooltip": "Nome da assinatura a ser usada",
|
||||
"Sign request": "Solicitação de assinatura",
|
||||
@@ -1111,12 +1144,12 @@
|
||||
"Sub type - Tooltip": "Subtipo",
|
||||
"Subject": "Assunto",
|
||||
"Subject - Tooltip": "Assunto do e-mail",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype": "Subtipo",
|
||||
"Subtype - Tooltip": "Dica: subtipo",
|
||||
"Syncer test": "Teste de sincronizador",
|
||||
"Syncer test - Tooltip": "Testar se a conexão com o sincronizador está funcionando",
|
||||
"Team ID": "ID da equipe",
|
||||
"Team ID - Tooltip": "Team ID - Tooltip",
|
||||
"Team ID - Tooltip": "Dica: ID da equipe",
|
||||
"Template code": "Código do modelo",
|
||||
"Template code - Tooltip": "Código do modelo",
|
||||
"Tenant ID": "ID Tenant",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "Testar Conexão SMTP",
|
||||
"Third-party": "Terceiro",
|
||||
"This field is required": "Este campo é obrigatório",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "Endereço do destinatário",
|
||||
"To address - Tooltip": "Endereço de e-mail do campo \"Para\"",
|
||||
"Token URL": "URL do Token",
|
||||
"Token URL - Tooltip": "URL do Token",
|
||||
"Use WeChat Media Platform in PC": "Usar plataforma de mídia WeChat no PC",
|
||||
@@ -1139,7 +1172,7 @@
|
||||
"Use id as name": "Usar ID como nome",
|
||||
"Use id as name - Tooltip": "Usar ID como nome do usuário",
|
||||
"User flow": "Fluxo do usuário",
|
||||
"User flow - Tooltip": "User flow - Tooltip",
|
||||
"User flow - Tooltip": "Fluxo do usuário - Dica",
|
||||
"User mapping": "Mapeamento de usuário",
|
||||
"User mapping - Tooltip": "Dica: mapeamento de usuário",
|
||||
"UserInfo URL": "URL do UserInfo",
|
||||
@@ -1169,7 +1202,7 @@
|
||||
"Sub domains": "Subdomínios",
|
||||
"Sub domains - Tooltip": "Domínios incluídos na função atual",
|
||||
"Sub groups": "Subgrupos",
|
||||
"Sub groups - Tooltip": "Sub groups - Tooltip",
|
||||
"Sub groups - Tooltip": "Subgrupos - Dica",
|
||||
"Sub roles": "Subfunções",
|
||||
"Sub roles - Tooltip": "Funções incluídas na função atual",
|
||||
"Sub users": "Subusuários",
|
||||
@@ -1224,32 +1257,35 @@
|
||||
"Active": "Ativa",
|
||||
"Edit Subscription": "Editar Assinatura",
|
||||
"End time": "Hora de término",
|
||||
"End time - Tooltip": "End time - Tooltip",
|
||||
"End time - Tooltip": "Dica: hora de término",
|
||||
"Error": "Erro",
|
||||
"Expired": "Expirada",
|
||||
"New Subscription": "Nova Assinatura",
|
||||
"Start time": "Hora de início",
|
||||
"Start time - Tooltip": "Start time - Tooltip",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Start time - Tooltip": "Dica: hora de início",
|
||||
"Subscription plan": "Plano de assinatura",
|
||||
"Subscription pricing": "Preço da assinatura",
|
||||
"Suspended": "Suspensa",
|
||||
"Upcoming": "Próxima",
|
||||
"View Subscription": "View Subscription"
|
||||
"View Subscription": "Ver Assinatura"
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"Admin Email": "Admin Email",
|
||||
"API Token / Password": "Token de API / Senha",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "E-mail do administrador",
|
||||
"Affiliation table": "Tabela de Afiliação",
|
||||
"Affiliation table - Tooltip": "Nome da tabela no banco de dados da unidade de trabalho",
|
||||
"Avatar base URL": "URL base do Avatar",
|
||||
"Avatar base URL - Tooltip": "Prefixo URL para as imagens de avatar",
|
||||
"Bind DN": "Bind DN",
|
||||
"Bind DN": "DN de vinculação",
|
||||
"Casdoor column": "Coluna Casdoor",
|
||||
"Column name": "Nome da coluna",
|
||||
"Column type": "Tipo de coluna",
|
||||
"Connect successfully": "Conectado com sucesso",
|
||||
"Corp ID": "Corp ID",
|
||||
"Corp secret": "Corp secret",
|
||||
"Corp ID": "ID da corporação",
|
||||
"Corp secret": "Segredo da corporação",
|
||||
"Database": "Banco de dados",
|
||||
"Database - Tooltip": "Nome original do banco de dados",
|
||||
"Database type": "Tipo de banco de dados",
|
||||
@@ -1263,15 +1299,15 @@
|
||||
"Is read-only": "É somente leitura",
|
||||
"Is read-only - Tooltip": "Dica: é somente leitura",
|
||||
"New Syncer": "Novo Syncer",
|
||||
"Paste your Google Workspace service account JSON key here": "Paste your Google Workspace service account JSON key here",
|
||||
"Paste your Google Workspace service account JSON key here": "Cole aqui a chave JSON da conta de serviço do Google Workspace",
|
||||
"SCIM Server URL": "SCIM Server URL",
|
||||
"SSH host": "Host SSH",
|
||||
"SSH password": "Senha SSH",
|
||||
"SSH port": "Porta SSH",
|
||||
"SSH user": "Usuário SSH",
|
||||
"SSL mode": "Modo SSL",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Service account key": "Service account key",
|
||||
"SSL mode - Tooltip": "Dica: modo SSL",
|
||||
"Service account key": "Chave da conta de serviço",
|
||||
"Sync interval": "Intervalo de sincronização",
|
||||
"Sync interval - Tooltip": "Unidade em segundos",
|
||||
"Table": "Tabela",
|
||||
@@ -1279,8 +1315,8 @@
|
||||
"Table columns": "Colunas da tabela",
|
||||
"Table columns - Tooltip": "Colunas da tabela envolvidas na sincronização de dados. Colunas que não participam da sincronização não precisam ser adicionadas",
|
||||
"Test Connection": "Testar conexão",
|
||||
"Test DB Connection": "Test DB Connection",
|
||||
"Username (optional)": "Username (optional)"
|
||||
"Test DB Connection": "Testar conexão com o banco de dados",
|
||||
"Username (optional)": "Nome de usuário (opcional)"
|
||||
},
|
||||
"system": {
|
||||
"API Latency": "Latência da API",
|
||||
@@ -1299,7 +1335,7 @@
|
||||
"Version": "Versão"
|
||||
},
|
||||
"theme": {
|
||||
"Blossom": "Blossom",
|
||||
"Blossom": "Florescer",
|
||||
"Border radius": "Raio da borda",
|
||||
"Compact": "Compacto",
|
||||
"Customize theme": "Personalizar tema",
|
||||
@@ -1311,16 +1347,16 @@
|
||||
"Theme - Tooltip": "Tema de estilo do aplicativo"
|
||||
},
|
||||
"ticket": {
|
||||
"Closed": "Closed",
|
||||
"Edit Ticket": "Edit Ticket",
|
||||
"In Progress": "In Progress",
|
||||
"Messages": "Messages",
|
||||
"New Ticket": "New Ticket",
|
||||
"Open": "Open",
|
||||
"Please enter a message": "Please enter a message",
|
||||
"Press Ctrl+Enter to send": "Press Ctrl+Enter to send",
|
||||
"Resolved": "Resolved",
|
||||
"Type your message here...": "Type your message here..."
|
||||
"Closed": "Fechado",
|
||||
"Edit Ticket": "Editar chamado",
|
||||
"In Progress": "Em andamento",
|
||||
"Messages": "Mensagens",
|
||||
"New Ticket": "Novo chamado",
|
||||
"Open": "Aberto",
|
||||
"Please enter a message": "Por favor, digite uma mensagem",
|
||||
"Press Ctrl+Enter to send": "Pressione Ctrl+Enter para enviar",
|
||||
"Resolved": "Resolvido",
|
||||
"Type your message here...": "Digite sua mensagem aqui..."
|
||||
},
|
||||
"token": {
|
||||
"Access token": "Token de acesso",
|
||||
@@ -1342,7 +1378,7 @@
|
||||
"Amount - Tooltip": "Dica: valor do produto negociado",
|
||||
"Edit Transaction": "Editar Transação",
|
||||
"New Transaction": "Nova Transação",
|
||||
"Recharge": "Recharge"
|
||||
"Recharge": "Recarga"
|
||||
},
|
||||
"user": {
|
||||
"3rd-party logins": "Logins de terceiros",
|
||||
@@ -1363,7 +1399,7 @@
|
||||
"Captcha Verify Success": "Verificação de captcha bem-sucedida",
|
||||
"City": "Cidade",
|
||||
"Country code": "Código do país",
|
||||
"Country code - Tooltip": "Country code - Tooltip",
|
||||
"Country code - Tooltip": "Dica: código do país",
|
||||
"Country/Region": "País/Região",
|
||||
"Country/Region - Tooltip": "País ou região",
|
||||
"Edit User": "Editar Usuário",
|
||||
@@ -1372,7 +1408,7 @@
|
||||
"Email cannot be empty": "O e-mail não pode ficar em branco",
|
||||
"Email/phone reset successfully": "Redefinição de e-mail/telefone com sucesso",
|
||||
"Empty input!": "Entrada vazia!",
|
||||
"Face IDs": "Face IDs",
|
||||
"Face IDs": "IDs faciais",
|
||||
"Gender": "Gênero",
|
||||
"Gender - Tooltip": "Dica: gênero",
|
||||
"Homepage": "Página inicial",
|
||||
@@ -1386,10 +1422,10 @@
|
||||
"ID card type": "Tipo de cartão de identidade",
|
||||
"ID card type - Tooltip": "Dica: tipo de cartão de identidade",
|
||||
"ID card with person": "Cartão de identidade com pessoa",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"ID verification": "Verificação de ID",
|
||||
"ID verification - Tooltip": "Dica: verificação de ID",
|
||||
"Identity verification successful": "Verificação de identidade bem-sucedida",
|
||||
"Identity verified": "Identidade verificada",
|
||||
"Input your email": "Digite seu e-mail",
|
||||
"Input your phone number": "Digite seu número de telefone",
|
||||
"Is admin": "É administrador",
|
||||
@@ -1399,7 +1435,7 @@
|
||||
"Is forbidden": "Está proibido",
|
||||
"Is forbidden - Tooltip": "Usuários proibidos não podem fazer login novamente",
|
||||
"Is online": "Está online",
|
||||
"Is verified": "Is verified",
|
||||
"Is verified": "Está verificado",
|
||||
"Karma": "Karma",
|
||||
"Karma - Tooltip": "Dica: karma",
|
||||
"Keys": "Chaves",
|
||||
@@ -1424,19 +1460,19 @@
|
||||
"Other": "Outro",
|
||||
"Password set successfully": "Senha definida com sucesso",
|
||||
"Phone cannot be empty": "O telefone não pode ficar vazio",
|
||||
"Please enter your real name": "Please enter your real name",
|
||||
"Please fill in ID card information first": "Please fill in ID card information first",
|
||||
"Please fill in your real name first": "Please fill in your real name first",
|
||||
"Please enter your real name": "Por favor, insira seu nome real",
|
||||
"Please fill in ID card information first": "Por favor, preencha primeiro as informações do documento de identidade",
|
||||
"Please fill in your real name first": "Por favor, preencha primeiro seu nome real",
|
||||
"Please select avatar from resources": "Selecione um avatar dos recursos",
|
||||
"Properties": "Propriedades",
|
||||
"Properties - Tooltip": "Propriedades do usuário",
|
||||
"Ranking": "Classificação",
|
||||
"Ranking - Tooltip": "Dica: classificação",
|
||||
"Re-enter New": "Digite Novamente",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Register source": "Register source",
|
||||
"Real name - Tooltip": "Dica: nome real",
|
||||
"Register source": "Origem do registro",
|
||||
"Register source - Tooltip": "A fonte da qual o usuário foi registrado",
|
||||
"Register type": "Register type",
|
||||
"Register type": "Tipo de registro",
|
||||
"Register type - Tooltip": "O método usado para registrar o usuário",
|
||||
"Reset Email...": "Redefinir E-mail...",
|
||||
"Reset Phone...": "Redefinir Telefone...",
|
||||
@@ -1462,8 +1498,8 @@
|
||||
"User Profile": "Perfil do usuário",
|
||||
"Values": "Valores",
|
||||
"Verification code sent": "Código de verificação enviado",
|
||||
"Verified": "Verified",
|
||||
"Verify Identity": "Verify Identity",
|
||||
"Verified": "Verificado",
|
||||
"Verify Identity": "Verificar identidade",
|
||||
"WebAuthn credentials": "Credenciais WebAuthn",
|
||||
"Work": "Trabalho",
|
||||
"You have changed the username, please save your change first before modifying the password": "Você alterou o nome de usuário. Salve a alteração antes de modificar a senha",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "Kimliğe bürünmeyi sonlandır",
|
||||
"Logout": "Oturumu kapat",
|
||||
"My Account": "Hesabım",
|
||||
"Sign Up": "Üye Ol"
|
||||
@@ -21,23 +21,23 @@
|
||||
"Add Face ID": "Face ID Ekle",
|
||||
"Add Face ID with Image": "Görüntü ile Face ID Ekle",
|
||||
"Always": "Her zaman",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Array": "Dizi",
|
||||
"Authentication": "Kimlik Doğrulama",
|
||||
"Auto signin": "Beni hatırla",
|
||||
"Auto signin - Tooltip": "Varolan oturum ile giriş yap",
|
||||
"Background URL": "Arkaplan Resim URL",
|
||||
"Background URL - Tooltip": "Login sayfası için arkaplan resmi url'i",
|
||||
"Background URL Mobile": "Arka Plan URL'si (Mobil)",
|
||||
"Background URL Mobile - Tooltip": "Mobil cihazlar için arka plan resmi URL'si",
|
||||
"Basic": "Basic",
|
||||
"Basic": "Temel",
|
||||
"Big icon": "Büyük simge",
|
||||
"Binding providers": "Bağlama sağlayıcıları",
|
||||
"CSS style": "CSS stili",
|
||||
"Center": "Ortala",
|
||||
"Code resend timeout": "Kod yeniden gönderme zaman aşımı",
|
||||
"Code resend timeout - Tooltip": "Kullanıcıların başka bir doğrulama kodu talep etmeden önce beklemesi gereken süre (saniye cinsinden). Genel varsayılanı (60 saniye) kullanmak için 0 olarak ayarlayın",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Çerez süresi",
|
||||
"Cookie expire - Tooltip": "Çerezin sona erme süresi - İpucu",
|
||||
"Copy SAML metadata URL": "SAML Metadata URL'ini kopyala",
|
||||
"Copy prompt page URL": "Prompt Page URL 'ini kopyala",
|
||||
"Copy signin page URL": "Giriş sayfası URL 'ini kopyala",
|
||||
@@ -47,9 +47,9 @@
|
||||
"Custom CSS - Tooltip": "Kayıt, giriş ve parola unutma formlarının CSS stilleri (örneğin, sınırlar ve gölgeler ekleme)",
|
||||
"Custom CSS Mobile": "Özel CSS (Mobil)",
|
||||
"Custom CSS Mobile - Edit": "Özel CSS (Mobil) - Düzenle",
|
||||
"Custom CSS Mobile - Tooltip": "Mobil cihazlar için özel CSS",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Custom CSS Mobile - Tooltip": "Mobil cihazlar için özel CSS - İpucu",
|
||||
"Disable SAML attributes": "SAML özniteliklerini devre dışı bırak",
|
||||
"Disable SAML attributes - Tooltip": "SAML özniteliklerinin devre dışı bırakılıp bırakılmayacağı - İpucu",
|
||||
"Disable signin": "Oturum açmayı devre dışı bırak",
|
||||
"Disable signin - Tooltip": "Kullanıcılar için oturum açmayı devre dışı bırak",
|
||||
"Dynamic": "Dinamik",
|
||||
@@ -60,16 +60,17 @@
|
||||
"Enable SAML C14N10 - Tooltip": "SAML'de C14N11 yerine C14N10 kullan",
|
||||
"Enable SAML POST binding": "SAML POST bağlamasını etkinleştir",
|
||||
"Enable SAML POST binding - Tooltip": "HTTP POST bağlaması, HTML formundaki input alanları aracılığıyla SAML mesajları gönderir. SP'niz bunu kullanıyorsa etkinleştirin.",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "SAML asserton imzasını etkinleştir",
|
||||
"Enable SAML assertion signature - Tooltip": "SAML assertonunu imzalamayı etkinleştir - İpucu",
|
||||
"Enable SAML compression": "SAML sıkıştırmasını Etkinleştir",
|
||||
"Enable SAML compression - Tooltip": "Casdoor SAML idp olarak kullanıldığında SAML yanıt mesajlarını sıkıştırıp sıkıştırmayacağı",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "Özel oturum açmayı etkinleştir",
|
||||
"Enable exclusive signin - Tooltip": "Özel oturum açma etkinse kullanıcı birden fazla etkin oturuma sahip olamaz",
|
||||
"Enable side panel": "Yan paneli Etkinleştir",
|
||||
"Enable signin session - Tooltip": "Uygulamadan Casdoor'a giriş yaptıktan sonra Casdoor'un bir oturum sürdürüp sürdürmeyeceği",
|
||||
"Enable signup": "Kayıtı Etkinleştir",
|
||||
"Enable signup - Tooltip": "Kullanıcıların yeni bir hesap kaydetmesine izin verilip verilmeyeceği",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Başarısız giriş dondurma süresi",
|
||||
"Failed signin frozen time - Tooltip": "Başarısız giriş denemelerinden sonra hesabın dondurulduğu süre",
|
||||
"Failed signin limit": "Başarısız giriş limiti",
|
||||
@@ -89,7 +90,7 @@
|
||||
"Header HTML": "Üst bilgi HTML",
|
||||
"Header HTML - Edit": "Üst bilgi HTML - Düzenle",
|
||||
"Header HTML - Tooltip": "Uygulamanızın giriş sayfasının head etiketini özelleştirin",
|
||||
"Horizontal": "Horizontal",
|
||||
"Horizontal": "Yatay",
|
||||
"Incremental": "Artımlı",
|
||||
"Inline": "Satır içi",
|
||||
"Input": "Girdi",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "Başarıyla çıkış yapıldı",
|
||||
"MFA remember time": "MFA hatırlama süresi",
|
||||
"MFA remember time - Tooltip": "Başarılı bir MFA girişinden sonra bir hesabın güvenilir olarak hatırlanacağı süreyi yapılandırır",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "Menü modu",
|
||||
"Menu mode - Tooltip": "Menü modu - İpucu",
|
||||
"Multiple Choices": "Çoklu Seçim",
|
||||
"New Application": "Yeni Uygulama",
|
||||
"No verification": "Doğrulama yok",
|
||||
@@ -111,48 +112,59 @@
|
||||
"Order": "Sıra",
|
||||
"Order - Tooltip": "Değer ne kadar küçükse, Uygulamalar sayfasında o kadar yüksek sıralanır",
|
||||
"Org choice mode": "Organizasyon seçim modu",
|
||||
"Org choice mode - Tooltip": "Organizasyon seçim modu",
|
||||
"Org choice mode - Tooltip": "Giriş yapmak için organizasyon seçme yöntemi - İpucu",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Lütfen \"Oturum açma oturumu\"nu etkinleştirmeden önce \"Otomatik oturum açma\"yı etkinleştirin",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "Lütfen uygulamanızı girin!",
|
||||
"Please input your organization!": "Lütfen organizasyonunuzu girin!",
|
||||
"Please select a HTML file": "Lütfen bir HTML dosyası seçin",
|
||||
"Pop up": "Açılır pencere",
|
||||
"Providers": "Providers",
|
||||
"Providers": "Sağlayıcılar",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "Rastgele",
|
||||
"Real name": "Gerçek ad",
|
||||
"Redirect URL": "Yönlendirme URL'si",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Yönlendirme URL'si (İddia Tüketici Hizmeti POST Bağlama URL'si)",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Yönlendirme URL'si (İddia Tüketici Hizmeti POST Bağlama URL'si) - İpucu",
|
||||
"Redirect URLs": "Yönlendirme URL'leri",
|
||||
"Redirect URLs - Tooltip": "Kabul edilen yönlendirme URL listesi, düzenli ifadeleri (regexp) kullanabilirsiniz. Eğer url bu lşistede yoksa hata sayfasına yönlendirilirsiniz",
|
||||
"Refresh token expire": "Yenileme jetonu sona erer",
|
||||
"Refresh token expire - Tooltip": "Yenileme jetonunun son kullanma süresi",
|
||||
"Reset to Empty": "Boşalt",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "Sağ",
|
||||
"Rule": "Kural",
|
||||
"SAML hash algorithm": "SAML karma algoritması",
|
||||
"SAML hash algorithm - Tooltip": "SAML imzası için karma algoritması",
|
||||
"SAML metadata": "SAML元数据",
|
||||
"SAML metadata - Tooltip": "SAML protokolünün元数据",
|
||||
"SAML metadata": "SAML meta verileri",
|
||||
"SAML metadata - Tooltip": "SAML protokolünün meta verileri - İpucu",
|
||||
"SAML reply URL": "SAML yanıt URL'si",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "Güvenlik",
|
||||
"Select": "Seç",
|
||||
"Side panel HTML": "Yan panel HTML",
|
||||
"Side panel HTML - Edit": "Yan panel HTML - Düzenle",
|
||||
"Side panel HTML - Tooltip": "Giriş sayfasının yan paneli için HTML kodunu özelleştirin",
|
||||
"Side panel HTML - Tooltip": "Giriş sayfasının yan paneli için HTML kodunu özelleştirin - İpucu",
|
||||
"Sign Up Error": "Kayıt Hatası",
|
||||
"Signin": "Oturum aç",
|
||||
"Signin (Default True)": "Oturum aç (Varsayılan True)",
|
||||
"Signin items": "Oturum açma öğeleri",
|
||||
"Signin items - Tooltip": "Oturum açma öğeleri",
|
||||
"Signin items - Tooltip": "Kullanıcıların giriş sırasında doldurması gereken öğeler - İpucu",
|
||||
"Signin methods": "Oturum açma yöntemleri",
|
||||
"Signin methods - Tooltip": "Oturum açma yöntemleri - Araç ipucu",
|
||||
"Signin session": "Giriş oturumu",
|
||||
"Signup items": "Kayıt öğeleri",
|
||||
"Signup items - Tooltip": "Kullanıcıların yeni hesaplar kaydederken doldurması gereken öğeler",
|
||||
"Signup items - Tooltip": "Kullanıcıların yeni hesaplar kaydederken doldurması gereken öğeler - İpucu",
|
||||
"Single Choice": "Tek Seçim",
|
||||
"Small icon": "Küçük simge",
|
||||
"String": "String",
|
||||
"Tags - Tooltip": "Yalnızca uygulama etiketlerinde listelenen etikete sahip kullanıcılar giriş yapabilir",
|
||||
"Static Value": "Static Value",
|
||||
"String": "Dize",
|
||||
"Tags - Tooltip": "Yalnızca uygulama etiketlerinde listelenen etikete sahip kullanıcılar giriş yapabilir - İpucu",
|
||||
"The application does not allow to sign up new account": "Uygulama yeni hesap kaydetmeyi izin vermemektedir",
|
||||
"Token expire": "Jeton sona erer",
|
||||
"Token expire - Tooltip": "Erişim jetonunun son kullanma süresi",
|
||||
@@ -162,10 +174,12 @@
|
||||
"Token format - Tooltip": "Erişim jetonunun formatı",
|
||||
"Token signing method": "Token imzalama yöntemi",
|
||||
"Token signing method - Tooltip": "JWT token'ın imzalama yöntemi, sertifika ile aynı algoritma olmalıdır",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "Arayüz Özelleştirme",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "NameID olarak E-posta kullan",
|
||||
"Use Email as NameID - Tooltip": "NameID olarak E-posta kullanın - Araç ipucu",
|
||||
"Vertical": "Vertical",
|
||||
"Vertical": "Dikey",
|
||||
"You are unexpected to see this prompt page": "Bu uyarı sayfasını görmeye beklemiyordunuz"
|
||||
},
|
||||
"cert": {
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "Genişlik"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "Normal bir kullanıcı yalnızca kendi gönderdiği izni değiştirebilir",
|
||||
"AI Assistant": "Yapay Zeka Asistanı",
|
||||
"API key": "API anahtarı",
|
||||
"API key - Tooltip": "Hizmete erişim için API anahtarı",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "İş ve Ödemeler",
|
||||
"Cancel": "Vazgeç",
|
||||
"Captcha": "Captcha",
|
||||
"Cart": "Cart",
|
||||
"Cart": "Sepet",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "Sertifika",
|
||||
"Cert - Tooltip": "Bu uygulamaya karşılık gelen istemci SDK tarafından doğrulanması gereken genel anahtar sertifikası",
|
||||
"Certs": "Sertifikalar",
|
||||
"Clear": "Clear",
|
||||
"Clear": "Temizle",
|
||||
"Click to Upload": "Yüklemek için tıklayın",
|
||||
"Client IP": "İstemci IP'si",
|
||||
"Close": "Kapat",
|
||||
@@ -307,12 +323,12 @@
|
||||
"Delete": "Sil",
|
||||
"Description": "Açıklama",
|
||||
"Description - Tooltip": "Referans için ayrıntılı açıklama bilgileri, Casdoor'un kendisi bunları kullanmayacaktır",
|
||||
"Detail": "详情",
|
||||
"Detail": "Detaylar",
|
||||
"Disable": "Devre dışı bırak",
|
||||
"Display name": "Görünen isim",
|
||||
"Display name - Tooltip": "Kullanıcı dostu, kolayca okunabilir, arayüzde genel olarak görüntülenen isim",
|
||||
"Down": "Aşağı",
|
||||
"Download template": "Download template",
|
||||
"Download template": "Şablonu indir",
|
||||
"Edit": "Düzenle",
|
||||
"Email": "E-Posta",
|
||||
"Email - Tooltip": "Geçerli e-posta adresi",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "Başarıyla etkinleştirildi",
|
||||
"Enforcers": "Zorlayıcılar",
|
||||
"Failed to add": "Ekleme başarısız oldu.",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "İptal edilemedi",
|
||||
"Failed to connect to server": "Sunucuya bağlanılamıyor",
|
||||
"Failed to copy": "Kopyalama başarısız",
|
||||
"Failed to delete": "Silme başarısız oldu",
|
||||
"Failed to enable": "Etkinleştirme başarısız",
|
||||
"Failed to get": "Alınamadı",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "Yüklenemedi",
|
||||
"Failed to log out": "Çıkış yapılamadı",
|
||||
"Failed to remove": "Kaldırma başarısız",
|
||||
"Failed to save": "Kaydetme başarısız oldu",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "Gönderilemedi",
|
||||
"Failed to sync": "Senkronizasyon başarısız",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "Bağlantı kaldırılamadı",
|
||||
"Failed to update": "Güncellenemedi",
|
||||
"Failed to upload": "Yüklenemedi",
|
||||
"Failed to verify": "Doğrulama başarısız",
|
||||
"False": "Yanlış",
|
||||
"Favicon": "Favicon",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "\"Parolayı unuttum\" sayfası için özel URL. Ayarlanmamışsa, varsayılan Casdoor \"Parolayı unuttum\" sayfası kullanılacaktır. Ayarlanırsa, giriş sayfasındaki \"Parolayı unuttum\" bağlantısı bu URL'ye yönlendirilecektir",
|
||||
"Forms": "Formlar",
|
||||
"Found some texts still not translated? Please help us translate at": "Henüz çevrilmemiş bazı metinler buldunuz mu? Lütfen aşağıdaki adreste bize çeviri yaparak yardım edin",
|
||||
"Generate": "Generate",
|
||||
"Generate": "Oluştur",
|
||||
"Go to enable": "Etkinleştirmek için git",
|
||||
"Go to writable demo site?": "Yazılabilir demo sitesine gitmek ister misiniz?",
|
||||
"Groups": "Gruplar",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "IP beyaz listesi",
|
||||
"IP whitelist - Tooltip": "IP beyaz listesi",
|
||||
"Identity": "Kimlik",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "Kimliğe bürünme",
|
||||
"Invitations": "Davetler",
|
||||
"Is enabled": "Aktif Mi?",
|
||||
"Is enabled - Tooltip": "Kullanılabilir olup olmadığını ayarla",
|
||||
@@ -381,7 +397,7 @@
|
||||
"Last name - Tooltip": "Kullanıcının soyadı",
|
||||
"Later": "Sonra",
|
||||
"Logging & Auditing": "Günlük ve Denetim",
|
||||
"Login page": "Login page",
|
||||
"Login page": "Giriş sayfası",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Uygulamanın dışarıya suntuğu simgeler",
|
||||
"Logo dark": "Koyu logo",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "Ad",
|
||||
"Name - Tooltip": "Benzersiz, dize tabanlı kimlik",
|
||||
"Name format": "Ad formatı",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "Ürün bulunamadı",
|
||||
"No sheets found in file": "Dosyada sayfa bulunamadı",
|
||||
"No verification method": "Doğrulama yöntemi yok",
|
||||
"Non-LDAP": "LDAP dışı",
|
||||
"None": "Hiçbiri",
|
||||
"OAuth providers": "OAuth sağlayıcıları",
|
||||
"OFF": "KAPALI",
|
||||
"OK": "Tamam",
|
||||
"ON": "AÇIK",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "Yalnızca 1 MFA yöntemi zorunlu olabilir",
|
||||
"Or": "Veya",
|
||||
"Orders": "Siparişler",
|
||||
"Organization": "Organizasyon",
|
||||
"Organization - Tooltip": "Kiracılar veya kullanıcı havuzları gibi kavramlara benzer, her kullanıcı ve uygulama bir organizasyona aittir",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "Organizasyon boş",
|
||||
"Organizations": "Organizasyonlar",
|
||||
"Password": "Şifre",
|
||||
"Password - Tooltip": "Şifrenizin doğru olduğundan emin olun",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "Telefon numarası",
|
||||
"Phone only": "Yalnızca telefon",
|
||||
"Phone or Email": "Telefon veya e-posta",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "Sipariş ver",
|
||||
"Plain": "Düz",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Abonelik planı",
|
||||
"Plans": "Planlar",
|
||||
"Plans - Tooltip": "Planlar - Araç ipucu",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "Lütfen captcha'yı doğru tamamlayın",
|
||||
"Please input your search": "Lütfen aramanızı girin",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "Lütfen önce en az 1 kullanıcı seçin",
|
||||
"Preview": "Önizleme",
|
||||
"Preview - Tooltip": "Yapılandırılmış efektleri önizle",
|
||||
"Pricing": "Fiyatlandırma",
|
||||
"Pricing - Tooltip": "Fiyatlandırma - Araç ipucu",
|
||||
"Pricings": "Fiyatlandırmalar",
|
||||
"Product Store": "Product Store",
|
||||
"Product Store": "Ürün Mağazası",
|
||||
"Products": "Ürünler",
|
||||
"Provider": "Sağlayıcı",
|
||||
"Provider - Tooltip": "Yapılandırılacak ödeme sağlayıcıları, bunlar arasında PayPal, Alipay, WeChat Pay vb. yer alır",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "SSH bağlantısının kimlik doğrulama türü",
|
||||
"Save": "Kaydet",
|
||||
"Save & Exit": "Kaydet ve Çık",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Ara",
|
||||
"Send": "Gönder",
|
||||
"Session ID": "Oturum ID",
|
||||
@@ -493,13 +511,13 @@
|
||||
"Sorry, you do not have permission to access this page or logged in status invalid.": "Üzgünüz, bu sayfaya erişim izniniz yok veya giriş durumu geçersiz.",
|
||||
"State": "Durum",
|
||||
"State - Tooltip": "Durum",
|
||||
"Status": "Status",
|
||||
"Status": "Durum",
|
||||
"Subscriptions": "Abonelikler",
|
||||
"Successfully added": "Başarıyla eklendi",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "Başarıyla iptal edildi",
|
||||
"Successfully copied": "Başarıyla kopyalandı",
|
||||
"Successfully deleted": "Başarıyla silindi",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "Başarıyla çalıştırıldı",
|
||||
"Successfully removed": "Başarıyla kaldırıldı",
|
||||
"Successfully saved": "Başarıyla kaydedildi",
|
||||
"Successfully sent": "Başarıyla gönderildi",
|
||||
@@ -514,12 +532,12 @@
|
||||
"Syncers": "Senkronizörler",
|
||||
"System Info": "Sistem Bilgisi",
|
||||
"Tab": "Sekme",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "Eylemler boş olamaz",
|
||||
"The resources cannot be empty": "Kaynaklar boş olamaz",
|
||||
"The users and roles cannot be empty at the same time": "Kullanıcılar ve roller aynı anda boş olamaz",
|
||||
"There was a problem signing you in..": "Oturum açarken bir sorun oluştu...",
|
||||
"This is a read-only demo site!": "Bu site sadece görüntüleme amaçlıdır!",
|
||||
"Tickets": "Tickets",
|
||||
"Tickets": "Destek Talepleri",
|
||||
"Timestamp": "Zaman damgası",
|
||||
"Title": "Başlık",
|
||||
"Title - Tooltip": "Başlık",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "İşlemler",
|
||||
"True": "Doğru",
|
||||
"Type": "Tür",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "URL bağlantısı",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "Bilinmeyen uygulama adı",
|
||||
"Unknown authentication type": "Bilinmeyen kimlik doğrulama türü",
|
||||
"Up": "Yukarı",
|
||||
"Updated time": "Güncellenme zamanı",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"Upload (.xlsx)": "Yükle (.xlsx)",
|
||||
"User": "Kullanıcı",
|
||||
"User - Tooltip": "Kullanıcı adının doğru olduğundan emin olun",
|
||||
"User Management": "Kullanıcı Yönetimi",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "Kullanıcı zaten mevcut",
|
||||
"User containers": "Kullanıcı havuzları",
|
||||
"User type": "Kullanıcı türü",
|
||||
"User type - Tooltip": "Kullanıcının ait olduğu etiketler, varsayılan olarak \"normal-user\"",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "Kullanıcılar - Araç ipucu",
|
||||
"Users under all organizations": "Tüm organizasyonlar altındaki kullanıcılar",
|
||||
"Verifications": "Doğrulamalar",
|
||||
"View": "View",
|
||||
"View": "Görüntüle",
|
||||
"Webhooks": "Webhook'lar",
|
||||
"You can only select one physical group": "Yalnızca bir fiziksel grup seçebilirsiniz",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "Önce bir resim seçmelisiniz",
|
||||
"empty": "boş",
|
||||
"remove": "kaldır",
|
||||
"{total} in total": "Toplam {total} adet"
|
||||
@@ -619,14 +638,14 @@
|
||||
"Server port": "Sunucu portu",
|
||||
"Server port - Tooltip": "LDAP sunucusu portu",
|
||||
"The Auto Sync option will sync all users to specify organization": "Otomatik Senkronizasyon seçeneği, tüm kullanıcıları belirli organizasyona senkronize edecektir",
|
||||
"User property name": "User property name",
|
||||
"User property name": "Kullanıcı özelliği adı",
|
||||
"synced": "senkronize edildi",
|
||||
"unsynced": "senkronize edilmedi"
|
||||
},
|
||||
"login": {
|
||||
"Auto sign in": "Otomatik Oturum Aç",
|
||||
"Back button": "Geri düğmesi",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "Telegram ile giriş yapmak için aşağıdaki düğmeye tıklayın",
|
||||
"Continue with": "İle devam et",
|
||||
"Email or phone": "E-posta veya telefon",
|
||||
"Face ID": "Yüz Tanıma",
|
||||
@@ -649,12 +668,12 @@
|
||||
"Please input your Email!": "Lütfen e-posta adresinizi girin!",
|
||||
"Please input your LDAP username!": "Lütfen LDAP kullanıcı adınızı girin!",
|
||||
"Please input your Phone!": "Lütfen telefon numaranızı girin!",
|
||||
"Please input your RADIUS password!": "Please input your RADIUS password!",
|
||||
"Please input your RADIUS username!": "Please input your RADIUS username!",
|
||||
"Please input your RADIUS password!": "Lütfen RADIUS şifrenizi girin!",
|
||||
"Please input your RADIUS username!": "Lütfen RADIUS kullanıcı adınızı girin!",
|
||||
"Please input your code!": "Lütfen size gönderilen kodu girin!",
|
||||
"Please input your organization name!": "Lütfen organizasyon adınızı girin!",
|
||||
"Please input your password!": "Lütfen şifrenizi girin!",
|
||||
"Please input your push notification receiver!": "Please input your push notification receiver!",
|
||||
"Please input your push notification receiver!": "Lütfen push bildirimi alıcısını girin!",
|
||||
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Lütfen web sayfasını HTTPS üzerinden yükleyin, aksi takdirde kameraya erişilemez",
|
||||
"Please provide permission to access the camera": "Lütfen kameraya erişim izni verin",
|
||||
"Please select an organization": "Lütfen bir organizasyon seçin",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "Organizasyon seç",
|
||||
"Sign In": "Oturum aç",
|
||||
"Sign in with Face ID": "Face ID ile oturum aç",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "Telegram ile giriş yap",
|
||||
"Sign in with WebAuthn": "WebAuthn ile giriş yap",
|
||||
"Sign in with {type}": "{type} ile giriş yap",
|
||||
"Signin button": "Oturum aç düğmesi",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "Lütfen aşağıdaki bilgileri onaylayın",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "Lütfen bu kurtarma kodunu kaydedin. Cihazınız bir doğrulama kodu sağlayamazsa, bu kurtarma kodu ile MFA kimlik doğrulamasını sıfırlayabilirsiniz",
|
||||
"Protect your account with Multi-factor authentication": "Hesabınızı çok faktörlü kimlik doğrulama ile koruyun",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "Push bildirim alıcısı",
|
||||
"Recovery code": "Kurtarma kodu",
|
||||
"Remember this account for {hour} hours": "Bu hesabı {hour} saat boyunca hatırla",
|
||||
"Scan the QR code with your Authenticator App": "Authenticator uygulamanızla QR kodu tarayın",
|
||||
@@ -708,53 +727,54 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "Hesabınızın güvenliğini sağlamak için çok faktörlü kimlik doğrulamanın etkinleştirilmesi gerekir",
|
||||
"Use Authenticator App": "Authenticator Uygulamasını Kullan",
|
||||
"Use Email": "E-postayı Kullan",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "Push Bildirim Kullan",
|
||||
"Use Radius": "RADIUS Kullan",
|
||||
"Use SMS": "SMS'i Kullan",
|
||||
"Use SMS verification code": "SMS doğrulama kodunu kullan",
|
||||
"Use a recovery code": "Kurtarma kodu kullan",
|
||||
"Verify Code": "Kodu Doğrula",
|
||||
"Verify Password": "Şifreyi Doğrula",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "Çok Faktörlü Kimlik Doğrulamayı etkinleştirdiniz, lütfen devam etmek için 'Kod Gönder' düğmesine tıklayın",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "Çok Faktörlü Kimlik Doğrulamayı etkinleştirdiniz, lütfen RADIUS şifresini girin",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "Çok Faktörlü Kimlik Doğrulamayı etkinleştirdiniz, lütfen TOTP kodunu girin",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "Çok Faktörlü Kimlik Doğrulamayı etkinleştirdiniz, lütfen push bildiriminden doğrulama kodunu girin",
|
||||
"Your email is": "E-posta adresiniz",
|
||||
"Your phone is": "Telefon numaranız",
|
||||
"preferred": "tercih edilen"
|
||||
},
|
||||
"model": {
|
||||
"Advanced Editor": "Advanced Editor",
|
||||
"Basic Editor": "Basic Editor",
|
||||
"Advanced Editor": "Gelişmiş Düzenleyici",
|
||||
"Basic Editor": "Temel Düzenleyici",
|
||||
"Edit Model": "Modeli Düzenle",
|
||||
"Model text": "Model text",
|
||||
"Model text - Tooltip": "Casbin access control model, including built-in models like ACL, RBAC, ABAC, RESTful, etc. You can also create custom models. For more information, please visit the Casbin website",
|
||||
"New Model": "New Model"
|
||||
"Model text": "Model metni",
|
||||
"Model text - Tooltip": "Casbin erişim kontrol modeli; ACL, RBAC, ABAC, RESTful vb. yerleşik modelleri içerir. Ayrıca özel modeller oluşturabilirsiniz. Daha fazla bilgi için Casbin web sitesini ziyaret edin",
|
||||
"New Model": "Yeni Model"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "İptal zamanı",
|
||||
"Edit Order": "Siparişi Düzenle",
|
||||
"New Order": "Yeni Sipariş",
|
||||
"Order not found": "Sipariş bulunamadı",
|
||||
"Pay": "Öde",
|
||||
"Payment failed time": "Ödeme başarısız zamanı",
|
||||
"Payment time": "Ödeme zamanı",
|
||||
"Price": "Fiyat",
|
||||
"Return to Order List": "Sipariş listesine dön",
|
||||
"Timeout time": "Zaman aşımı",
|
||||
"View Order": "Siparişi Görüntüle"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "Hesap öğeleri",
|
||||
"Account items - Tooltip": "Kişisel ayarlar sayfasındaki öğeler",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Account menu": "Hesap menüsü",
|
||||
"Account menu - Tooltip": "Hesap menüsü - Araç ipucu",
|
||||
"Admin navbar items": "Yönetici gezinme çubuğu öğeleri",
|
||||
"Admin navbar items - Tooltip": "Yönetici gezinme çubuğu öğeleri - Araç ipucu",
|
||||
"All": "All",
|
||||
"Balance credit": "Bakiye kredisi",
|
||||
"Balance credit - Tooltip": "Bakiye kredisi - Araç ipucu",
|
||||
"Balance currency": "Bakiye para birimi",
|
||||
"Balance currency - Tooltip": "Bakiye para birimi - Araç ipucu",
|
||||
"Edit Organization": "Organizasyonu Düzenle",
|
||||
"Follow global theme": "Küresel temayı takip et",
|
||||
"Has privilege consent": "Ayrıcalık onayı var",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "Kuralı Değiştir",
|
||||
"New Organization": "Yeni Organizasyon",
|
||||
"Optional": "İsteğe bağlı",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "Organizasyon bakiyesi",
|
||||
"Org balance - Tooltip": "Organizasyon bakiyesi - Araç ipucu",
|
||||
"Password expire days": "Şifre son kullanma günleri",
|
||||
"Password expire days - Tooltip": "Şifre son kullanma günleri - Araç ipucu",
|
||||
"Prompt": "İstem",
|
||||
@@ -778,10 +798,10 @@
|
||||
"Tags": "Etiketler",
|
||||
"Use Email as username": "Kullanıcı adı olarak E-posta kullan",
|
||||
"Use Email as username - Tooltip": "Kullanıcı adı alanı kayıtta görünür değilse kullanıcı adı olarak E-posta kullan",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User balance": "Kullanıcı bakiyesi",
|
||||
"User balance - Tooltip": "Kullanıcı bakiyesi - Araç ipucu",
|
||||
"User navbar items": "Kullanıcı gezinme çubuğu öğeleri",
|
||||
"User navbar items - Tooltip": "Kullanıcı gezinme çubuğu öğeleri - Araç ipucu",
|
||||
"User types": "Kullanıcı türleri",
|
||||
"User types - Tooltip": "Kullanıcı türleri - Araç ipucu",
|
||||
"View rule": "Kuralı Görüntüle",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Lütfen fatura bilgilerinizi dikkatlice kontrol edin. Fatura çıkartıldıktan sonra geri alınamaz veya değiştirilemez.",
|
||||
"Please pay the order first!": "Lütfen önce siparişi ödeyin!",
|
||||
"Processing...": "İşleniyor...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "Ürünler - Araç ipucu",
|
||||
"Recharged successfully": "Başarıyla yenilendi",
|
||||
"Result": "Sonuç",
|
||||
"The payment has been canceled": "Ödeme iptal edildi",
|
||||
"The payment has failed": "Ödeme başarısız oldu",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "Ödeme zaman aşımına uğradı",
|
||||
"The payment is still under processing": "Ödeme hala işleniyor",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "Ödemeyi Görüntüle",
|
||||
"You can view your order details or return to the order list": "Sipariş ayrıntılarını görüntüleyebilir veya sipariş listesine dönebilirsiniz",
|
||||
"You have successfully completed the payment": "Ödemeyi başarıyla tamamladınız",
|
||||
"You have successfully recharged": "Başarıyla yenilendiniz",
|
||||
"Your current balance is": "Mevcut bakiyeniz",
|
||||
@@ -867,13 +887,15 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Planı Düzenle",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "Yeni Plan",
|
||||
"Period": "Dönem",
|
||||
"Period - Tooltip": "Dönem",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "Plan adı",
|
||||
"Price - Tooltip": "Fiyat",
|
||||
"Related product": "İlgili ürün",
|
||||
"View Plan": "View Plan",
|
||||
"View Plan": "Planı Görüntüle",
|
||||
"per month": "aylık",
|
||||
"per year": "yılda bir"
|
||||
},
|
||||
@@ -883,55 +905,62 @@
|
||||
"Free": "Ücretsiz",
|
||||
"Getting started": "Başlarken",
|
||||
"New Pricing": "Yeni Fiyatlandırma",
|
||||
"Pricing name": "Pricing name",
|
||||
"Pricing name": "Fiyatlandırma adı",
|
||||
"Trial duration": "Deneme süresi",
|
||||
"Trial duration - Tooltip": "Deneme süresi dönemi",
|
||||
"View Pricing": "View Pricing",
|
||||
"View Pricing": "Fiyatlandırmayı Görüntüle",
|
||||
"days trial available!": "gün deneme süresi mevcut!",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "Ücretli kullanıcının aktif veya bekleyen aboneliği yok, lütfen satın almak için bir plan seçin"
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "Sepete ekle",
|
||||
"AirWallex": "AirWallex",
|
||||
"Alipay": "Alipay",
|
||||
"Amount": "Amount",
|
||||
"Amount": "Tutar",
|
||||
"Buy": "Satın Al",
|
||||
"Buy Product": "Ürün Satın Al",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Özel tutar kullanılabilir",
|
||||
"Custom price should be greater than zero": "Özel fiyat sıfırdan büyük olmalıdır",
|
||||
"Detail - Tooltip": "Ürün detayı",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Disable custom amount": "Özel tutarı devre dışı bırak",
|
||||
"Disable custom amount - Tooltip": "Özel tutarı devre dışı bırak - Araç ipucu",
|
||||
"Dummy": "Kukla",
|
||||
"Edit Product": "Ürünü Düzenle",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
"Failed to create order": "Failed to create order",
|
||||
"Enter preset amounts": "Ön tanımlı tutarları gir",
|
||||
"Failed to create order": "Sipariş oluşturulamadı",
|
||||
"Image": "Resim",
|
||||
"Image - Tooltip": "Ürün resmi",
|
||||
"Information": "Information",
|
||||
"Information": "Bilgi",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "Yeniden yükleme mi",
|
||||
"Is recharge - Tooltip": "Mevcut ürün bakiye yeniden yüklemesi ise",
|
||||
"Name": "Name",
|
||||
"New Product": "Yeni Ürün",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Sipariş başarıyla oluşturuldu",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "Ödeme iptal edildi",
|
||||
"Payment failed": "Ödeme başarısız",
|
||||
"Payment providers": "Ödeme sağlayıcıları",
|
||||
"Payment providers - Tooltip": "Ödeme hizmetleri sağlayıcıları",
|
||||
"Placing order...": "Sipariş veriliyor...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Özel tutar devre dışıyken en az bir yeniden yükleme seçeneği ekleyin",
|
||||
"Please select a currency": "Lütfen bir para birimi seçin",
|
||||
"Please select at least one payment provider": "Lütfen en az bir ödeme sağlayıcısı seçin",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Ödeme işleniyor...",
|
||||
"Product list cannot be empty": "Ürün listesi boş olamaz",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Miktar",
|
||||
"Quantity - Tooltip": "Ürün miktarı",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge options": "Yeniden yükleme seçenekleri",
|
||||
"Recharge options - Tooltip": "Yeniden yükleme seçenekleri - Araç ipucu",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "Dönüş URL'si",
|
||||
"Return URL - Tooltip": "Satın alımdan sonra dönülecek URL",
|
||||
"SKU": "SKU",
|
||||
"Select amount": "Select amount",
|
||||
"Select amount": "Tutar seç",
|
||||
"Sold": "Satılmış",
|
||||
"Sold - Tooltip": "Satılan miktar",
|
||||
"Stripe": "Stripe",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "Satın almadan sonra dönülecek URL",
|
||||
"Tag - Tooltip": "Ürün etiketi",
|
||||
"Test buy page..": "Test satın alım sayfası..",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "Eklediğiniz ürünün para birimi sepetteki ürünlerin para biriminden farklı",
|
||||
"There is no payment channel for this product.": "Bu ürün için ödeme kanalı yoktur.",
|
||||
"This product is currently not in sale.": "Bu ürün şu anda satışta değil.",
|
||||
"This product is currently not purchasable (No options available)": "This product is currently not purchasable (No options available)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"This product is currently not purchasable (No options available)": "Bu ürün şu anda satın alınamaz (seçenek yok)",
|
||||
"Total Price": "Toplam Fiyat",
|
||||
"View Product": "Ürünü Görüntüle",
|
||||
"WeChat Pay": "WeChat Ödeme"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Kimlik Doğrulama Anahtarı - Araç ipucu",
|
||||
"Auth URL": "Yetkilendirme URL'si",
|
||||
"Auth URL - Tooltip": "Yetkilendirme URL'si",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "Temel URL",
|
||||
"Base URL - Tooltip": "Temel URL - Araç ipucu",
|
||||
"Bucket": "Bucket",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "İkinci istemci gizli anahtarı",
|
||||
"Content": "İçerik",
|
||||
"Content - Tooltip": "İçerik - Araç ipucu",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "SSL'yi Devre Dışı Bırak",
|
||||
"Disable SSL - Tooltip": "STMP sunucusu ile iletişim kurarken SSL protokolünü devre dışı bırakıp bırakmayacağı",
|
||||
"DB test": "Veritabanı testi",
|
||||
"DB test - Tooltip": "Veritabanı testi - Araç ipucu",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Alan adı",
|
||||
"Domain - Tooltip": "Nesne depolama için özel alan adı",
|
||||
"Edit Provider": "Sağlayıcıyı Düzenle",
|
||||
@@ -1001,10 +1030,11 @@
|
||||
"Email regex - Tooltip": "E-posta düzenli ifadesi - Araç ipucu",
|
||||
"Email title": "E-posta başlığı",
|
||||
"Email title - Tooltip": "E-posta başlığı",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "PKCE'yi etkinleştir",
|
||||
"Enable PKCE - Tooltip": "PKCE'yi etkinleştir - Araç ipucu",
|
||||
"Enable proxy": "Proxy'yi etkinleştir",
|
||||
"Enable proxy - Tooltip": "E-posta veya SMS gönderirken socks5 proxy'yi etkinleştir",
|
||||
"Endpoint": "Uç nokta",
|
||||
"Endpoint (Intranet)": "Uç nokta (İç ağ)",
|
||||
"Endpoint - Tooltip": "Uç nokta - Araç ipucu",
|
||||
@@ -1031,13 +1061,13 @@
|
||||
"Key ID - Tooltip": "Anahtar ID'si",
|
||||
"Key text": "Anahtar metni",
|
||||
"Key text - Tooltip": "Anahtar metni",
|
||||
"LDAP port": "LDAP port",
|
||||
"LDAP port": "LDAP portu",
|
||||
"Metadata": "Meta veriler",
|
||||
"Metadata - Tooltip": "SAML meta verileri",
|
||||
"Metadata url": "Meta veri URL'si",
|
||||
"Metadata url - Tooltip": "Meta veri URL'si - Araç ipucu",
|
||||
"Method - Tooltip": "Giriş yöntemi, QR kodu veya sessiz giriş",
|
||||
"Mobile": "Mobile",
|
||||
"Mobile": "Mobil",
|
||||
"New Provider": "Yeni Sağlayıcı",
|
||||
"Parameter": "Parametre",
|
||||
"Parameter - Tooltip": "Parametre - Araç ipucu",
|
||||
@@ -1055,10 +1085,10 @@
|
||||
"Prompted": "İstemlendi",
|
||||
"Provider URL": "Sağlayıcı URL'si",
|
||||
"Provider URL - Tooltip": "Hizmet sağlayıcısını yapılandırmak için URL, bu alan yalnızca referans amacıyla kullanılır ve Casdoor'da kullanılmaz",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "Sağlayıcı testi başarılı",
|
||||
"Public key": "Açık anahtar",
|
||||
"Public key - Tooltip": "Açık anahtar - Araç ipucu",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret of RADIUS",
|
||||
"RADIUS Shared Secret - Tooltip": "RADIUS paylaşılan gizli anahtarı",
|
||||
"Region": "Bölge",
|
||||
"Region - Tooltip": "Bölge - Araç ipucu",
|
||||
"Region ID": "Bölge ID'si",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "SP ACS URL'si",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL'si",
|
||||
"SP Entity ID": "SP Varlık ID'si",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Senaryo",
|
||||
"Scene - Tooltip": "Senaryo",
|
||||
"Scope": "Kapsam",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Gizli erişim anahtarı",
|
||||
"Secret access key - Tooltip": "Gizli erişim anahtarı",
|
||||
"Secret key": "Gizli anahtar",
|
||||
@@ -1091,7 +1124,7 @@
|
||||
"Service ID identifier": "Servis Kimliği tanımlayıcısı",
|
||||
"Service ID identifier - Tooltip": "Hizmet ID tanımlayıcısı",
|
||||
"Service account JSON": "Servis hesabı JSON",
|
||||
"Service account JSON - Tooltip": "Service account JSON - Tooltip",
|
||||
"Service account JSON - Tooltip": "Servis hesabı JSON - Araç ipucu",
|
||||
"Sign Name": "İmza Adı",
|
||||
"Sign Name - Tooltip": "Kullanılacak imzanın adı",
|
||||
"Sign request": "İstek imzalama",
|
||||
@@ -1111,12 +1144,12 @@
|
||||
"Sub type - Tooltip": "Alt tür",
|
||||
"Subject": "Konu",
|
||||
"Subject - Tooltip": "E-posta konusu",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype": "Alt tür",
|
||||
"Subtype - Tooltip": "Alt tür - Araç ipucu",
|
||||
"Syncer test": "Senkronizasyon testi",
|
||||
"Syncer test - Tooltip": "Senkronizasyon bağlantısının çalışıp çalışmadığını test et",
|
||||
"Team ID": "Takım Kimliği",
|
||||
"Team ID - Tooltip": "Team ID - Tooltip",
|
||||
"Team ID - Tooltip": "Takım Kimliği - Araç ipucu",
|
||||
"Template code": "Şablon kodu",
|
||||
"Template code - Tooltip": "Şablon kodu",
|
||||
"Tenant ID": "Tenant ID",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "SMTP Bağlantısını Test Et",
|
||||
"Third-party": "Üçüncü taraf",
|
||||
"This field is required": "Bu alan zorunludur",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "Alıcı adresi",
|
||||
"To address - Tooltip": "\"Kime\" alanının e-posta adresi",
|
||||
"Token URL": "Jeton URL'si",
|
||||
"Token URL - Tooltip": "Jeton URL'si",
|
||||
"Use WeChat Media Platform in PC": "WeChat Medya Platformunu PC'de kullan",
|
||||
@@ -1139,7 +1172,7 @@
|
||||
"Use id as name": "Kimliği ad olarak kullan",
|
||||
"Use id as name - Tooltip": "Kullanıcının adı olarak kimliği kullan",
|
||||
"User flow": "Kullanıcı akışı",
|
||||
"User flow - Tooltip": "User flow - Tooltip",
|
||||
"User flow - Tooltip": "Kullanıcı akışı - Araç ipucu",
|
||||
"User mapping": "Kullanıcı eşleştirmesi",
|
||||
"User mapping - Tooltip": "Kullanıcı eşleştirmesi - Araç ipucu",
|
||||
"UserInfo URL": "Kullanıcı Bilgisi URL'si",
|
||||
@@ -1169,7 +1202,7 @@
|
||||
"Sub domains": "Alt alanlar",
|
||||
"Sub domains - Tooltip": "Mevcut role dahil edilen alanlar",
|
||||
"Sub groups": "Alt gruplar",
|
||||
"Sub groups - Tooltip": "Sub groups - Tooltip",
|
||||
"Sub groups - Tooltip": "Alt gruplar - İpucu",
|
||||
"Sub roles": "Alt roller",
|
||||
"Sub roles - Tooltip": "Mevcut role dahil edilen roller",
|
||||
"Sub users": "Alt kullanıcılar",
|
||||
@@ -1224,12 +1257,12 @@
|
||||
"Active": "Aktif",
|
||||
"Edit Subscription": "Aboneliği Düzenle",
|
||||
"End time": "Bitiş zamanı",
|
||||
"End time - Tooltip": "End time - Tooltip",
|
||||
"End time - Tooltip": "Bitiş zamanı - İpucu",
|
||||
"Error": "Hata",
|
||||
"Expired": "Süresi doldu",
|
||||
"New Subscription": "Yeni Abonelik",
|
||||
"Start time": "Başlangıç zamanı",
|
||||
"Start time - Tooltip": "Start time - Tooltip",
|
||||
"Start time - Tooltip": "Başlangıç zamanı - İpucu",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Suspended": "Askıya alındı",
|
||||
@@ -1238,6 +1271,9 @@
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "Admin Email",
|
||||
"Affiliation table": "İlişki tablosu",
|
||||
"Affiliation table - Tooltip": "Çalışma biriminin veritabanı tablo adı",
|
||||
@@ -1256,7 +1292,7 @@
|
||||
"Database type - Tooltip": "Veritabanı türü, XORM tarafından desteklenen tüm veritabanlarını destekler, örneğin MySQL, PostgreSQL, SQL Server, Oracle, SQLite vb.",
|
||||
"Edit Syncer": "Senkronizatörü Düzenle",
|
||||
"Error text": "Hata metni",
|
||||
"Error text - Tooltip": "Hata metni",
|
||||
"Error text - Tooltip": "Hata metni - İpucu",
|
||||
"Failed to connect": "Bağlantı başarısız",
|
||||
"Is hashed": "Özetlenmiş mi",
|
||||
"Is key": "Anahtar mı",
|
||||
@@ -1270,7 +1306,7 @@
|
||||
"SSH port": "SSH portu",
|
||||
"SSH user": "SSH kullanıcısı",
|
||||
"SSL mode": "SSL modu",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"SSL mode - Tooltip": "SSL modu - İpucu",
|
||||
"Service account key": "Service account key",
|
||||
"Sync interval": "Senkronizasyon aralığı",
|
||||
"Sync interval - Tooltip": "Birimi saniye cinsinden",
|
||||
@@ -1363,7 +1399,7 @@
|
||||
"Captcha Verify Success": "Captcha doğrulaması başarılı",
|
||||
"City": "Şehir",
|
||||
"Country code": "Ülke kodu",
|
||||
"Country code - Tooltip": "Country code - Tooltip",
|
||||
"Country code - Tooltip": "Ülke kodu - İpucu",
|
||||
"Country/Region": "Ülke/Bölge",
|
||||
"Country/Region - Tooltip": "Ülke veya bölge",
|
||||
"Edit User": "Kullanıcıyı Düzenle",
|
||||
@@ -1387,7 +1423,7 @@
|
||||
"ID card type - Tooltip": "Kimlik kartı türü - Araç ipucu",
|
||||
"ID card with person": "Kimlik kartı ve kişi",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"ID verification - Tooltip": "Kimlik doğrulama - İpucu",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"Input your email": "E-postanızı girin",
|
||||
@@ -1433,7 +1469,7 @@
|
||||
"Ranking": "Sıralama",
|
||||
"Ranking - Tooltip": "Sıralama - Araç ipucu",
|
||||
"Re-enter New": "Yeniden Girin",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Real name - Tooltip": "Gerçek ad - İpucu",
|
||||
"Register source": "Register source",
|
||||
"Register source - Tooltip": "Kullanıcının kaydedildiği kaynak",
|
||||
"Register type": "Register type",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "Вийти з режиму особи",
|
||||
"Logout": "Вийти",
|
||||
"My Account": "Мій обліковий запис",
|
||||
"Sign Up": "Реєстрація"
|
||||
@@ -11,33 +11,33 @@
|
||||
"Failed to sync policies": "Не вдалося синхронізувати політики",
|
||||
"New Adapter": "Новий адаптер",
|
||||
"Policies": "Політики",
|
||||
"Policies - Tooltip": "Правила політики Casbin",
|
||||
"Policies - Tooltip": "Правила політики Casbin - Підказка",
|
||||
"Rule type": "Тип правила",
|
||||
"Sync policies successfully": "Політики успішно синхронізовані",
|
||||
"Use same DB": "Використовувати ту саму БД",
|
||||
"Use same DB - Tooltip": "Використовувати ту саму базу даних - Підказка"
|
||||
"Use same DB - Tooltip": "Використовувати ту саму базу даних що і Casdoor - Підказка"
|
||||
},
|
||||
"application": {
|
||||
"Add Face ID": "Додати Face ID",
|
||||
"Add Face ID with Image": "Додати Face ID за допомогою зображення",
|
||||
"Always": "Завжди",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Array": "Масив",
|
||||
"Authentication": "Автентифікація",
|
||||
"Auto signin": "Автоматичний вхід",
|
||||
"Auto signin - Tooltip": "Коли існує сеанс входу в Casdoor, він автоматично використовується для входу в програму",
|
||||
"Background URL": "URL фону",
|
||||
"Background URL - Tooltip": "URL зображення фону, яке використовується на сторінці входу",
|
||||
"Background URL Mobile": "URL фону для мобілок",
|
||||
"Background URL Mobile - Tooltip": "URL фону для мобілок - підказка",
|
||||
"Basic": "Basic",
|
||||
"Background URL Mobile - Tooltip": "URL зображення фону для мобільних пристроїв - Підказка",
|
||||
"Basic": "Базовий",
|
||||
"Big icon": "Велика іконка",
|
||||
"Binding providers": "Прив’язка провайдерів",
|
||||
"CSS style": "Стиль CSS",
|
||||
"Center": "Центр",
|
||||
"Code resend timeout": "Час очікування повторної відправки коду",
|
||||
"Code resend timeout - Tooltip": "Період часу (у секундах), який користувачі повинні чекати перед запитом іншого коду перевірки. Встановіть 0, щоб використовувати глобальне значення за замовчуванням (60 секунд)",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Термін дії Cookie",
|
||||
"Cookie expire - Tooltip": "Термін дії Cookie - Підказка",
|
||||
"Copy SAML metadata URL": "Копіювати URL метаданих SAML",
|
||||
"Copy prompt page URL": "Копіювати URL сторінки запиту",
|
||||
"Copy signin page URL": "Копіювати URL сторінки входу",
|
||||
@@ -47,9 +47,9 @@
|
||||
"Custom CSS - Tooltip": "Стилізація CSS для форм реєстрації, входу і забутих паролів (наприклад, додавання меж і тіней)",
|
||||
"Custom CSS Mobile": "Мобільний спеціальний CSS",
|
||||
"Custom CSS Mobile - Edit": "Редагувати мобільний спеціальний CSS",
|
||||
"Custom CSS Mobile - Tooltip": "Мобільний спеціальний CSS - Підказка",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Custom CSS Mobile - Tooltip": "Спеціальний CSS для мобільних пристроїв - Підказка",
|
||||
"Disable SAML attributes": "Вимкнути атрибути SAML",
|
||||
"Disable SAML attributes - Tooltip": "Вимкнути атрибути SAML - Підказка",
|
||||
"Disable signin": "Вимкнути вхід",
|
||||
"Disable signin - Tooltip": "Вимкнути вхід для користувачів",
|
||||
"Dynamic": "Динамічний",
|
||||
@@ -57,23 +57,24 @@
|
||||
"Enable Email linking": "Дозволити зв’язок з Email",
|
||||
"Enable Email linking - Tooltip": "Під час входу за допомогою сторонніх провайдерів, якщо у організації є користувач з такою ж електронною поштою, метод входу стороннім провайдером автоматично асоціюється з цим користувачем",
|
||||
"Enable SAML C14N10": "Увімкнути SAML C14N10",
|
||||
"Enable SAML C14N10 - Tooltip": "Увімкнути SAML C14N10 – підказка",
|
||||
"Enable SAML C14N10 - Tooltip": "Використовувати C14N10 замість C14N11 у SAML - Підказка",
|
||||
"Enable SAML POST binding": "Увімкнути зв’язування SAML POST",
|
||||
"Enable SAML POST binding - Tooltip": "Прив’язка HTTP POST використовує поля введення у формі HTML для надсилання повідомлень SAML. Увімкніть, якщо це використовує ваш SP",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "Увімкнути підпис утвердження SAML",
|
||||
"Enable SAML assertion signature - Tooltip": "Чи підписувати SAML утвердження - Підказка",
|
||||
"Enable SAML compression": "Увімкнути стиснення SAML",
|
||||
"Enable SAML compression - Tooltip": "Чи стискати повідомлення-відповіді SAML, коли Casdoor використовується як SAML idp",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "Увімкнути ексклюзивний вхід",
|
||||
"Enable exclusive signin - Tooltip": "Коли ексклюзивний вхід увімкнено, користувач не може мати кілька активних сеансів",
|
||||
"Enable side panel": "Увімкнути бічну панель",
|
||||
"Enable signin session - Tooltip": "Чи підтримує Casdoor сеанс після входу в Casdoor із програми",
|
||||
"Enable signup": "Увімкнути реєстрацію",
|
||||
"Enable signup - Tooltip": "Чи дозволяти користувачам реєструвати новий обліковий запис",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Помилка входу заморожений час",
|
||||
"Failed signin frozen time - Tooltip": "Помилка входу, заморожений час – підказка",
|
||||
"Failed signin frozen time - Tooltip": "Час після якого обліковий запис заморожується після невдалих спроб входу - Підказка",
|
||||
"Failed signin limit": "Обмеження невдалого входу",
|
||||
"Failed signin limit - Tooltip": "Ліміт невдалого входу – підказка",
|
||||
"Failed signin limit - Tooltip": "Максимальна кількість невдалих спроб входу перед заморожуванням - Підказка",
|
||||
"Failed to sign in": "Не вдалося ввійти",
|
||||
"File uploaded successfully": "Файл успішно завантажено",
|
||||
"First, last": "Перший Останній",
|
||||
@@ -89,7 +90,7 @@
|
||||
"Header HTML": "Заголовок HTML",
|
||||
"Header HTML - Edit": "HTML-код заголовка – Редагувати",
|
||||
"Header HTML - Tooltip": "Налаштуйте тег head на сторінці входу до програми",
|
||||
"Horizontal": "Horizontal",
|
||||
"Horizontal": "Горизонтальний",
|
||||
"Incremental": "Інкрементний",
|
||||
"Inline": "Вбудований",
|
||||
"Input": "Введення",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "Успішно вийшов",
|
||||
"MFA remember time": "Час запам'ятовування MFA",
|
||||
"MFA remember time - Tooltip": "Налаштовує тривалість, протягом якої обліковий запис запам'ятовується як довірений після успішного входу з MFA",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "Режим меню",
|
||||
"Menu mode - Tooltip": "Режим меню - підказка",
|
||||
"Multiple Choices": "Кілька варіантів",
|
||||
"New Application": "Нова заявка",
|
||||
"No verification": "Без підтвердження",
|
||||
@@ -112,12 +113,19 @@
|
||||
"Order - Tooltip": "Чим менше значення, тим вище воно ранжується на сторінці програм",
|
||||
"Org choice mode": "Режим вибору організації",
|
||||
"Org choice mode - Tooltip": "Режим вибору організації – підказка",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Спочатку увімкніть \"Сесію входу\", перш ніж увімкнути \"Автоматичний вхід\"",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "Будь ласка, введіть свою заявку!",
|
||||
"Please input your organization!": "Будь ласка, введіть вашу організацію!",
|
||||
"Please select a HTML file": "Виберіть файл HTML",
|
||||
"Pop up": "Вспливаюче вікно",
|
||||
"Providers": "Providers",
|
||||
"Providers": "Постачальники",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "Випадковий",
|
||||
"Real name": "Справжнє ім'я",
|
||||
"Redirect URL": "URL-адреса перенаправлення",
|
||||
@@ -127,6 +135,7 @@
|
||||
"Refresh token expire": "Термін дії маркера оновлення закінчився",
|
||||
"Refresh token expire - Tooltip": "Оновити термін дії маркера",
|
||||
"Reset to Empty": "Скинути до порожнього",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "правильно",
|
||||
"Rule": "правило",
|
||||
"SAML hash algorithm": "Хеш-алгоритм SAML",
|
||||
@@ -134,7 +143,9 @@
|
||||
"SAML metadata": "Метадані SAML",
|
||||
"SAML metadata - Tooltip": "Метадані протоколу SAML",
|
||||
"SAML reply URL": "URL-адреса відповіді SAML",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "Безпека",
|
||||
"Select": "Виберіть",
|
||||
"Side panel HTML": "HTML бічної панелі",
|
||||
"Side panel HTML - Edit": "Бічна панель HTML - Редагувати",
|
||||
@@ -151,7 +162,8 @@
|
||||
"Signup items - Tooltip": "Пункти, які користувачі повинні заповнити під час реєстрації нових облікових записів",
|
||||
"Single Choice": "Один варіант",
|
||||
"Small icon": "Маленький значок",
|
||||
"String": "String",
|
||||
"Static Value": "Static Value",
|
||||
"String": "Рядок",
|
||||
"Tags - Tooltip": "Увійти можуть лише користувачі з тегом, указаним у тегах програми",
|
||||
"The application does not allow to sign up new account": "Програма не дозволяє зареєструвати новий обліковий запис",
|
||||
"Token expire": "Термін дії маркера закінчується",
|
||||
@@ -162,10 +174,12 @@
|
||||
"Token format - Tooltip": "Формат маркера доступу",
|
||||
"Token signing method": "Метод підпису токена",
|
||||
"Token signing method - Tooltip": "Метод підпису JWT-токена, повинен бути тим же алгоритмом, що і сертифікат",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "Налаштування інтерфейсу",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "Використовувати Email як NameID",
|
||||
"Use Email as NameID - Tooltip": "Використовувати Email як NameID - підказка",
|
||||
"Vertical": "Vertical",
|
||||
"Vertical": "Вертикальний",
|
||||
"You are unexpected to see this prompt page": "Ви неочікувано побачите цю сторінку запиту"
|
||||
},
|
||||
"cert": {
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "Ширина"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "Звичайний користувач може змінювати лише дозвіл, поданий ним самим",
|
||||
"AI Assistant": "AI Асистент",
|
||||
"API key": "Ключ API",
|
||||
"API key - Tooltip": "Ключ API для доступу до сервісу",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "Бізнес",
|
||||
"Cancel": "Скасувати",
|
||||
"Captcha": "Капча",
|
||||
"Cart": "Cart",
|
||||
"Cart": "Кошик",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "сертифікат",
|
||||
"Cert - Tooltip": "Сертифікат відкритого ключа, який потрібно перевірити клієнтським SDK, що відповідає цій програмі",
|
||||
"Certs": "Сертифікати",
|
||||
"Clear": "Clear",
|
||||
"Clear": "Очистити",
|
||||
"Click to Upload": "Натисніть, щоб завантажити",
|
||||
"Client IP": "IP клієнта",
|
||||
"Close": "Закрити",
|
||||
@@ -312,7 +328,7 @@
|
||||
"Display name": "Відображуване ім'я",
|
||||
"Display name - Tooltip": "Зручне ім’я, яке легко читається, відображається публічно в інтерфейсі користувача",
|
||||
"Down": "вниз",
|
||||
"Download template": "Download template",
|
||||
"Download template": "Завантажити шаблон",
|
||||
"Edit": "Редагувати",
|
||||
"Email": "Електронна пошта",
|
||||
"Email - Tooltip": "Дійсна електронна пошта",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "Успішно ввімкнено",
|
||||
"Enforcers": "Силовики",
|
||||
"Failed to add": "Не вдалося додати",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "Не вдалося скасувати",
|
||||
"Failed to connect to server": "Не вдалося підключитися до сервера",
|
||||
"Failed to copy": "Не вдалося скопіювати",
|
||||
"Failed to delete": "Не вдалося видалити",
|
||||
"Failed to enable": "Не вдалося ввімкнути",
|
||||
"Failed to get": "Не вдалося отримати",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "Не вдалося завантажити",
|
||||
"Failed to log out": "Не вдалося вийти",
|
||||
"Failed to remove": "Не вдалося видалити",
|
||||
"Failed to save": "Не вдалося зберегти",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "Не вдалося надіслати",
|
||||
"Failed to sync": "Не вдалося синхронізувати",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "Не вдалося від'єднати",
|
||||
"Failed to update": "Не вдалося оновити",
|
||||
"Failed to upload": "Не вдалося завантажити",
|
||||
"Failed to verify": "Не вдалося перевірити",
|
||||
"False": "Ні",
|
||||
"Favicon": "Фавікон",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "Користувацька URL-адреса для сторінки \"Забути пароль\". ",
|
||||
"Forms": "Форми",
|
||||
"Found some texts still not translated? Please help us translate at": "Знайшли ще неперекладені тексти? ",
|
||||
"Generate": "Generate",
|
||||
"Generate": "Генерувати",
|
||||
"Go to enable": "Перейдіть до включення",
|
||||
"Go to writable demo site?": "Перейти на демонстраційний сайт для запису?",
|
||||
"Groups": "Групи",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "Белый список IP",
|
||||
"IP whitelist - Tooltip": "Белый список IP - підказка",
|
||||
"Identity": "Ідентичність",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "Втілення",
|
||||
"Invitations": "Запрошення",
|
||||
"Is enabled": "Увімкнено",
|
||||
"Is enabled - Tooltip": "Встановіть, чи можна використовувати",
|
||||
@@ -381,7 +397,7 @@
|
||||
"Last name - Tooltip": "Прізвище користувача",
|
||||
"Later": "Пізніше",
|
||||
"Logging & Auditing": "Лісозаготівля",
|
||||
"Login page": "Login page",
|
||||
"Login page": "Сторінка входу",
|
||||
"Logo": "логотип",
|
||||
"Logo - Tooltip": "Значки, які програма представляє зовнішньому світу",
|
||||
"Logo dark": "Логотип темний",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "Ім'я",
|
||||
"Name - Tooltip": "Унікальний ідентифікатор на основі рядка",
|
||||
"Name format": "Формат імені",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "Немає доступних товарів",
|
||||
"No sheets found in file": "У файлі не знайдено листів",
|
||||
"No verification method": "Немає методу перевірки",
|
||||
"Non-LDAP": "Не LDAP",
|
||||
"None": "Жодного",
|
||||
"OAuth providers": "Постачальники OAuth",
|
||||
"OFF": "ВИМКНЕНО",
|
||||
"OK": "в порядку",
|
||||
"ON": "УВІМКНЕНО",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "Може бути потрібен лише 1 метод MFA",
|
||||
"Or": "Або",
|
||||
"Orders": "Замовлення",
|
||||
"Organization": "організація",
|
||||
"Organization - Tooltip": "Подібно до таких концепцій, як орендарі або пули користувачів, кожен користувач і програма належать до організації",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "Організація порожня",
|
||||
"Organizations": "організації",
|
||||
"Password": "Пароль",
|
||||
"Password - Tooltip": "Переконайтеся, що пароль правильний",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "Номер телефону",
|
||||
"Phone only": "Тільки телефон",
|
||||
"Phone or Email": "Телефон або Email",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "Розмістити замовлення",
|
||||
"Plain": "Простий",
|
||||
"Plan": "План",
|
||||
"Plan - Tooltip": "План підписки",
|
||||
"Plans": "Плани",
|
||||
"Plans - Tooltip": "Плани - підказка",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "Будь ласка, правильно заповніть капчу",
|
||||
"Please input your search": "Будь ласка, введіть ваш запит",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "Спочатку виберіть щонайменше 1 користувача",
|
||||
"Preview": "Попередній перегляд",
|
||||
"Preview - Tooltip": "Перегляньте налаштовані ефекти",
|
||||
"Pricing": "Ціноутворення",
|
||||
"Pricing - Tooltip": "Ціноутворення – підказка",
|
||||
"Pricings": "Ціноутворення",
|
||||
"Product Store": "Product Store",
|
||||
"Product Store": "Магазин товарів",
|
||||
"Products": "Продукти",
|
||||
"Provider": "Провайдер",
|
||||
"Provider - Tooltip": "Платіжні постачальники, які потрібно налаштувати, зокрема PayPal, Alipay, WeChat Pay тощо.",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "Тип авторизації підключення SSH",
|
||||
"Save": "зберегти",
|
||||
"Save & Exit": "зберегти",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Пошук",
|
||||
"Send": "Надіслати",
|
||||
"Session ID": "Ідентифікатор сеансу",
|
||||
@@ -493,13 +511,13 @@
|
||||
"Sorry, you do not have permission to access this page or logged in status invalid.": "Вибачте, у вас немає дозволу на доступ до цієї сторінки або статус входу недійсний.",
|
||||
"State": "Держава",
|
||||
"State - Tooltip": "Держава",
|
||||
"Status": "Status",
|
||||
"Status": "Статус",
|
||||
"Subscriptions": "Підписки",
|
||||
"Successfully added": "Успішно додано",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "Успішно скасовано",
|
||||
"Successfully copied": "Успішно скопійовано",
|
||||
"Successfully deleted": "Успішно видалено",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "Успішно виконано",
|
||||
"Successfully removed": "Успішно видалено",
|
||||
"Successfully saved": "Успішно збережено",
|
||||
"Successfully sent": "Успішно відправлено",
|
||||
@@ -514,12 +532,12 @@
|
||||
"Syncers": "Синхронизатори",
|
||||
"System Info": "Інформація про систему",
|
||||
"Tab": "Вкладка",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "Дії не можуть бути порожніми",
|
||||
"The resources cannot be empty": "Ресурси не можуть бути порожніми",
|
||||
"The users and roles cannot be empty at the same time": "Користувачі і ролі не можуть бути порожніми одночасно",
|
||||
"There was a problem signing you in..": "Під час входу виникла проблема.",
|
||||
"This is a read-only demo site!": "Це демо-сайт лише для читання!",
|
||||
"Tickets": "Tickets",
|
||||
"Tickets": "Квитки",
|
||||
"Timestamp": "Мітка часу",
|
||||
"Title": "Заголовок",
|
||||
"Title - Tooltip": "Заголовок",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "транзакції",
|
||||
"True": "Так",
|
||||
"Type": "Тип",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "URL-посилання",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "Невідома назва програми",
|
||||
"Unknown authentication type": "Невідомий тип аутентифікації",
|
||||
"Up": "вгору",
|
||||
"Updated time": "Оновлений час",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"Upload (.xlsx)": "Завантажити (.xlsx)",
|
||||
"User": "Користувач",
|
||||
"User - Tooltip": "Переконайтеся, що ім'я користувача правильне",
|
||||
"User Management": "Керування користувачами",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "Користувач вже існує",
|
||||
"User containers": "Пули користувачів",
|
||||
"User type": "Тип користувача",
|
||||
"User type - Tooltip": "Теги, до яких належить користувач, за умовчанням \"звичайний користувач\"",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "Користувачі - підказка",
|
||||
"Users under all organizations": "Користувачі в усіх організаціях",
|
||||
"Verifications": "Перевірки",
|
||||
"View": "View",
|
||||
"View": "Перегляд",
|
||||
"Webhooks": "Веб-хуки",
|
||||
"You can only select one physical group": "Ви можете вибрати лише одну фізичну групу",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "Спочатку ви повинні вибрати зображення",
|
||||
"empty": "порожній",
|
||||
"remove": "видалити",
|
||||
"{total} in total": "загалом {total}"
|
||||
@@ -619,14 +638,14 @@
|
||||
"Server port": "Порт сервера",
|
||||
"Server port - Tooltip": "Порт сервера LDAP",
|
||||
"The Auto Sync option will sync all users to specify organization": "Опція автоматичної синхронізації синхронізує всіх користувачів для визначення організації",
|
||||
"User property name": "User property name",
|
||||
"User property name": "Назва властивості користувача",
|
||||
"synced": "синхронізовано",
|
||||
"unsynced": "несинхронізований"
|
||||
},
|
||||
"login": {
|
||||
"Auto sign in": "Автоматичний вхід",
|
||||
"Back button": "Кнопка \"Назад\".",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "Натисніть кнопку нижче, щоб увійти через Telegram",
|
||||
"Continue with": "Продовжити з",
|
||||
"Email or phone": "Електронна пошта або телефон",
|
||||
"Face ID": "Face ID",
|
||||
@@ -649,12 +668,12 @@
|
||||
"Please input your Email!": "Будь ласка, введіть свою електронну адресу!",
|
||||
"Please input your LDAP username!": "Будь ласка, введіть своє ім'я користувача LDAP!",
|
||||
"Please input your Phone!": "Будь ласка, введіть свій телефон!",
|
||||
"Please input your RADIUS password!": "Please input your RADIUS password!",
|
||||
"Please input your RADIUS username!": "Please input your RADIUS username!",
|
||||
"Please input your RADIUS password!": "Будь ласка, введіть ваш пароль RADIUS!",
|
||||
"Please input your RADIUS username!": "Будь ласка, введіть ваше ім'я користувача RADIUS!",
|
||||
"Please input your code!": "Будь ласка, введіть свій код!",
|
||||
"Please input your organization name!": "Будь ласка, введіть назву вашої організації!",
|
||||
"Please input your password!": "Будь ласка, введіть свій пароль!",
|
||||
"Please input your push notification receiver!": "Please input your push notification receiver!",
|
||||
"Please input your push notification receiver!": "Будь ласка, введіть ваш отримувач push-сповіщень!",
|
||||
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Завантажте веб-сторінку за допомогою HTTPS, інакше доступ до камери буде неможливий",
|
||||
"Please provide permission to access the camera": "Будь ласка, надайте дозвіл на доступ до камери",
|
||||
"Please select an organization": "Виберіть організацію",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "Вибрати організацію",
|
||||
"Sign In": "Увійти",
|
||||
"Sign in with Face ID": "Увійдіть за допомогою Face ID",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "Увійти через Telegram",
|
||||
"Sign in with WebAuthn": "Увійдіть за допомогою WebAuthn",
|
||||
"Sign in with {type}": "Увійдіть за допомогою {type}",
|
||||
"Signin button": "Кнопка входу",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "Підтвердьте інформацію нижче",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "Будь ласка, збережіть цей код відновлення. ",
|
||||
"Protect your account with Multi-factor authentication": "Захистіть свій обліковий запис за допомогою багатофакторної автентифікації",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "Отримувач push-сповіщень",
|
||||
"Recovery code": "Код відновлення",
|
||||
"Remember this account for {hour} hours": "Запам'ятати цей обліковий запис на {hour} годин",
|
||||
"Scan the QR code with your Authenticator App": "Відскануйте QR-код за допомогою програми Authenticator",
|
||||
@@ -708,17 +727,17 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "Для забезпечення безпеки вашого облікового запису необхідно ввімкнути багатофакторну аутентифікацію",
|
||||
"Use Authenticator App": "Використовуйте додаток Authenticator",
|
||||
"Use Email": "Використовуйте електронну пошту",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "Використовувати Push-сповіщення",
|
||||
"Use Radius": "Використовувати Radius",
|
||||
"Use SMS": "Використовуйте SMS",
|
||||
"Use SMS verification code": "Використовуйте код підтвердження SMS",
|
||||
"Use a recovery code": "Використовуйте код відновлення",
|
||||
"Verify Code": "Підтвердити код",
|
||||
"Verify Password": "Підтвердіть пароль",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "Ви ввімкнули багаторівневу аутентифікацію. Натисніть «Надіслати код», щоб продовжити",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "Ви увімкнули багаторівневу аутентифікацію, будь ласка, введіть пароль RADIUS",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "Ви ввімкнули багаторівневу аутентифікацію, введіть TOTP-код",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "Ви увімкнули багаторівневу аутентифікацію, введіть код підтвердження з push-сповіщення",
|
||||
"Your email is": "Ваша електронна адреса",
|
||||
"Your phone is": "Ваш телефон",
|
||||
"preferred": "бажаний"
|
||||
@@ -732,11 +751,11 @@
|
||||
"New Model": "Нова модель"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Cancel time": "Час скасування",
|
||||
"Edit Order": "Редагувати замовлення",
|
||||
"New Order": "Нове замовлення",
|
||||
"Order not found": "Замовлення не знайдено",
|
||||
"Pay": "Оплатити",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
@@ -745,51 +764,52 @@
|
||||
"View Order": "View Order"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "Елементи облікового запису",
|
||||
"Account items - Tooltip": "Пункти на сторінці особистих налаштувань",
|
||||
"Account items": "Account items",
|
||||
"Account items - Tooltip": "Account items - Tooltip",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"All": "All",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Edit Organization": "Редагувати організацію",
|
||||
"Follow global theme": "Дотримуйтеся глобальної теми",
|
||||
"Has privilege consent": "Має згоду на привілеї",
|
||||
"Has privilege consent - Tooltip": "Заборонити додавання користувачів до вбудованої організації, якщо HasPrivilegeConsent встановлено в false",
|
||||
"Has privilege consent warning": "Додавання нового користувача до організації «built-in» (вбудованої) на даний момент вимкнено. Зауважте: усі користувачі в організації «built-in» є глобальними адміністраторами в Casdoor. Дивіться документацію: https://casdoor.org/docs/basic/core-concepts#how-does-casdoor-manage-itself. Якщо ви все ще хочете створити користувача для організації «built-in», перейдіть на сторінку налаштувань організації та увімкніть опцію «Має згоду на привілеї».",
|
||||
"Init score": "Початкова оцінка",
|
||||
"Init score - Tooltip": "Початкові бали, нараховані користувачам під час реєстрації",
|
||||
"Is profile public": "Профіль загальнодоступний",
|
||||
"Is profile public - Tooltip": "Після закриття лише глобальні адміністратори або користувачі в одній організації можуть отримати доступ до сторінки профілю користувача",
|
||||
"Modify rule": "Змінити правило",
|
||||
"New Organization": "Нова організація",
|
||||
"Optional": "Додатково",
|
||||
"Edit Organization": "Edit Organization",
|
||||
"Follow global theme": "Follow global theme",
|
||||
"Has privilege consent": "Has privilege consent",
|
||||
"Has privilege consent - Tooltip": "Has privilege consent - Tooltip",
|
||||
"Has privilege consent warning": "Has privilege consent warning",
|
||||
"Init score": "Init score",
|
||||
"Init score - Tooltip": "Init score - Tooltip",
|
||||
"Is profile public": "Is profile public",
|
||||
"Is profile public - Tooltip": "Is profile public - Tooltip",
|
||||
"Modify rule": "Modify rule",
|
||||
"New Organization": "New Organization",
|
||||
"Optional": "Optional",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Password expire days": "Кількість днів дії паролю",
|
||||
"Password expire days - Tooltip": "Кількість днів дії паролю - підказка",
|
||||
"Prompt": "Підкажіть",
|
||||
"Required": "вимагається",
|
||||
"Soft deletion": "М'яке видалення",
|
||||
"Soft deletion - Tooltip": "Якщо ввімкнено, видалення користувачів не призведе до їх повного видалення з бази даних. ",
|
||||
"Tags": "Теги",
|
||||
"Use Email as username": "Використовувати Email як ім'я користувача",
|
||||
"Use Email as username - Tooltip": "Використовувати Email як ім'я користувача, якщо поле імені користувача не відображається під час реєстрації",
|
||||
"Password expire days": "Password expire days",
|
||||
"Password expire days - Tooltip": "Password expire days - Tooltip",
|
||||
"Prompt": "Prompt",
|
||||
"Required": "Required",
|
||||
"Soft deletion": "Soft deletion",
|
||||
"Soft deletion - Tooltip": "Soft deletion - Tooltip",
|
||||
"Tags": "Tags",
|
||||
"Use Email as username": "Use Email as username",
|
||||
"Use Email as username - Tooltip": "Use Email as username - Tooltip",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User types": "Типи користувачів",
|
||||
"User types - Tooltip": "Типи користувачів - підказка",
|
||||
"View rule": "Переглянути правило",
|
||||
"Visible": "Видно",
|
||||
"Website URL": "адреса вебсайту",
|
||||
"Website URL - Tooltip": "URL-адреса домашньої сторінки організації. ",
|
||||
"Widget items": "Елементи віджета",
|
||||
"Widget items - Tooltip": "Елементи віджета - підказка"
|
||||
"User types": "User types",
|
||||
"User types - Tooltip": "User types - Tooltip",
|
||||
"View rule": "View rule",
|
||||
"Visible": "Visible",
|
||||
"Website URL": "Website URL",
|
||||
"Website URL - Tooltip": "Website URL - Tooltip",
|
||||
"Widget items": "Widget items",
|
||||
"Widget items - Tooltip": "Widget items - Tooltip"
|
||||
},
|
||||
"payment": {
|
||||
"Confirm your invoice information": "Підтвердьте інформацію про рахунок",
|
||||
@@ -826,7 +846,7 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Будь ласка, уважно перевірте інформацію про рахунок-фактуру. ",
|
||||
"Please pay the order first!": "Будь ласка, спочатку оплатите замовлення!",
|
||||
"Processing...": "Обробка...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "Продукти - Підказка",
|
||||
"Recharged successfully": "Поповнення успішне",
|
||||
"Result": "Результат",
|
||||
"The payment has been canceled": "Платіж скасовано",
|
||||
@@ -867,6 +887,8 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Редагувати план",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "Новий план",
|
||||
"Period": "Крапка",
|
||||
"Period - Tooltip": "Період",
|
||||
@@ -897,11 +919,12 @@
|
||||
"Amount": "Amount",
|
||||
"Buy": "купити",
|
||||
"Buy Product": "Купити товар",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Detail - Tooltip": "Деталь продукту",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Disable custom amount - Tooltip": "Вимкнути користувацьку суму - Підказка",
|
||||
"Dummy": "манекен",
|
||||
"Edit Product": "Редагувати товар",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
@@ -909,9 +932,12 @@
|
||||
"Image": "Зображення",
|
||||
"Image - Tooltip": "Зображення товару",
|
||||
"Information": "Information",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "Чи є поповненням",
|
||||
"Is recharge - Tooltip": "Чи є поточний продукт для поповнення балансу",
|
||||
"Name": "Name",
|
||||
"New Product": "Новий продукт",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"PayPal": "Пейпал",
|
||||
"Payment cancelled": "Платіж скасовано",
|
||||
@@ -922,12 +948,15 @@
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Кількість",
|
||||
"Quantity - Tooltip": "Кількість товару",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge options - Tooltip": "Варіанти поповнення - Підказка",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "Повернута URL-адреса",
|
||||
"Return URL - Tooltip": "URL-адреса для повернення після успішної покупки",
|
||||
"SKU": "SKU",
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Ключ автентифікації для сервісу",
|
||||
"Auth URL": "URL авторизації",
|
||||
"Auth URL - Tooltip": "URL для автентифікації",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "Базовий URL",
|
||||
"Base URL - Tooltip": "Базовий URL сервісу",
|
||||
"Bucket": "Відро",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "Резервний ключ перевірки клієнта, що використовується для перевірки при збої основного ключа або в особливих сценаріях",
|
||||
"Content": "Зміст",
|
||||
"Content - Tooltip": "Вміст – підказка",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "Вимкнути SSL",
|
||||
"Disable SSL - Tooltip": "Чи вимикати протокол SSL під час зв’язку із сервером STMP",
|
||||
"DB test": "Тест БД",
|
||||
"DB test - Tooltip": "Тест бази даних - підказка",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Домен",
|
||||
"Domain - Tooltip": "Спеціальний домен для зберігання об'єктів",
|
||||
"Edit Provider": "Редагувати постачальника",
|
||||
@@ -1001,10 +1030,11 @@
|
||||
"Email regex - Tooltip": "Email регулярний вираз - підказка",
|
||||
"Email title": "Назва електронної пошти",
|
||||
"Email title - Tooltip": "Заголовок електронного листа",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "Увімкнути PKCE",
|
||||
"Enable PKCE - Tooltip": "Увімкнути PKCE - підказка",
|
||||
"Enable proxy": "Увімкнути проксі",
|
||||
"Enable proxy - Tooltip": "Увімкнути проксі socks5 при відправці email або SMS",
|
||||
"Endpoint": "Кінцева точка",
|
||||
"Endpoint (Intranet)": "Кінцева точка (Інтранет)",
|
||||
"Endpoint - Tooltip": "Кінцева точка – підказка",
|
||||
@@ -1030,14 +1060,14 @@
|
||||
"Key ID": "ID ключа",
|
||||
"Key ID - Tooltip": "ID ключа – підказка",
|
||||
"Key text": "Ключовий текст",
|
||||
"Key text - Tooltip": "Ключовий текст - підказка",
|
||||
"LDAP port": "LDAP port",
|
||||
"Key text - Tooltip": "Текст ключа - підказка",
|
||||
"LDAP port": "Порт LDAP",
|
||||
"Metadata": "Метадані",
|
||||
"Metadata - Tooltip": "Метадані SAML",
|
||||
"Metadata url": "URL метаданих",
|
||||
"Metadata url - Tooltip": "URL метаданих - підказка",
|
||||
"Method - Tooltip": "Метод входу, QR-код або тихий вхід",
|
||||
"Mobile": "Mobile",
|
||||
"Mobile": "Мобільний",
|
||||
"New Provider": "Новий постачальник",
|
||||
"Parameter": "Параметр",
|
||||
"Parameter - Tooltip": "Параметр - Підказка",
|
||||
@@ -1055,10 +1085,10 @@
|
||||
"Prompted": "Запропоновано",
|
||||
"Provider URL": "URL-адреса постачальника",
|
||||
"Provider URL - Tooltip": "URL-адреса для налаштування постачальника послуг, це поле використовується лише для довідки та не використовується в Casdoor",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "Тест постачальника успішний",
|
||||
"Public key": "Відкритий ключ",
|
||||
"Public key - Tooltip": "Відкритий ключ - підказка",
|
||||
"RADIUS Shared Secret - Tooltip": "Shared Secret of RADIUS",
|
||||
"RADIUS Shared Secret - Tooltip": "Спільний секрет RADIUS",
|
||||
"Region": "Регіон",
|
||||
"Region - Tooltip": "Регіон - підказка",
|
||||
"Region ID": "ID регіону",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "URL ACS СП",
|
||||
"SP ACS URL - Tooltip": "URL ACS СП",
|
||||
"SP Entity ID": "Ідентифікатор особи SP",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Сцена",
|
||||
"Scene - Tooltip": "Сцена",
|
||||
"Scope": "Область застосування",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Секретний ключ доступу",
|
||||
"Secret access key - Tooltip": "Секретний ключ доступу",
|
||||
"Secret key": "Секретний ключ",
|
||||
@@ -1112,11 +1145,11 @@
|
||||
"Subject": "Тема",
|
||||
"Subject - Tooltip": "Тема електронного листа",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype - Tooltip": "Підтип - Підказка",
|
||||
"Syncer test": "Тест синхронізатора",
|
||||
"Syncer test - Tooltip": "Тест синхронізатора - Підказка",
|
||||
"Team ID": "ID команди",
|
||||
"Team ID - Tooltip": "ID команди – підказка",
|
||||
"Team ID - Tooltip": "Ідентифікатор команди - підказка",
|
||||
"Template code": "Код шаблону",
|
||||
"Template code - Tooltip": "Код шаблону",
|
||||
"Tenant ID": "ID Tenant",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "Перевірте з'єднання SMTP",
|
||||
"Third-party": "Сторонні",
|
||||
"This field is required": "Це поле є обов'язковим",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "На адресу",
|
||||
"To address - Tooltip": "Email адреса одержувача",
|
||||
"Token URL": "URL маркера",
|
||||
"Token URL - Tooltip": "URL маркера",
|
||||
"Use WeChat Media Platform in PC": "Використовуйте медіаплатформу WeChat на ПК",
|
||||
@@ -1139,7 +1172,7 @@
|
||||
"Use id as name": "Використовувати id як ім'я",
|
||||
"Use id as name - Tooltip": "Використовувати id як ім'я користувача",
|
||||
"User flow": "Потік користувачів",
|
||||
"User flow - Tooltip": "Потік користувача – підказка",
|
||||
"User flow - Tooltip": "Потік користувача - підказка",
|
||||
"User mapping": "Відображення користувача",
|
||||
"User mapping - Tooltip": "Відображення користувача – підказка",
|
||||
"UserInfo URL": "URL-адреса інформації про користувача",
|
||||
@@ -1238,6 +1271,9 @@
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "Admin Email",
|
||||
"Affiliation table": "Таблиця приналежності",
|
||||
"Affiliation table - Tooltip": "Назва робочої одиниці таблиці бази даних",
|
||||
@@ -1387,7 +1423,7 @@
|
||||
"ID card type - Tooltip": "Тип посвідчення особи",
|
||||
"ID card with person": "ID-картка з особою",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"ID verification - Tooltip": "Перевірка ID - Підказка",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"Input your email": "Введіть адресу електронної пошти",
|
||||
@@ -1433,7 +1469,7 @@
|
||||
"Ranking": "Рейтинг",
|
||||
"Ranking - Tooltip": "Позиція користувача в рейтингу на основі балів, рівня активності та інших метрик",
|
||||
"Re-enter New": "Повторно введіть новий",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Real name - Tooltip": "Справжнє ім'я - Підказка",
|
||||
"Register source": "Register source",
|
||||
"Register source - Tooltip": "Джерело, з якого було зареєстровано користувача",
|
||||
"Register type": "Register type",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "Thoát khỏi chế độ giả danh",
|
||||
"Logout": "Đăng xuất",
|
||||
"My Account": "Tài khoản của tôi",
|
||||
"Sign Up": "Đăng ký"
|
||||
@@ -21,23 +21,23 @@
|
||||
"Add Face ID": "Thêm Face ID",
|
||||
"Add Face ID with Image": "Thêm Face ID với hình ảnh",
|
||||
"Always": "luôn luôn",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Array": "Mảng",
|
||||
"Authentication": "Xác thực",
|
||||
"Auto signin": "Tự động đăng nhập",
|
||||
"Auto signin - Tooltip": "Khi một phiên đăng nhập đã được tạo trong Casdoor, nó sẽ tự động được sử dụng để đăng nhập tại ứng dụng",
|
||||
"Background URL": "URL nền",
|
||||
"Background URL - Tooltip": "Đường dẫn URL của hình ảnh nền được sử dụng trong trang đăng nhập",
|
||||
"Background URL Mobile": "URL nền Mobile",
|
||||
"Background URL Mobile - Tooltip": "URL hình nền cho thiết bị di động",
|
||||
"Basic": "Basic",
|
||||
"Basic": "Cơ bản",
|
||||
"Big icon": "Biểu tượng lớn",
|
||||
"Binding providers": "Nhà cung cấp liên kết",
|
||||
"CSS style": "Kiểu CSS",
|
||||
"Center": "Trung tâm",
|
||||
"Code resend timeout": "Thời gian chờ gửi lại mã",
|
||||
"Code resend timeout - Tooltip": "Khoảng thời gian (tính bằng giây) mà người dùng phải đợi trước khi yêu cầu mã xác minh khác. Đặt thành 0 để sử dụng giá trị mặc định toàn cục (60 giây)",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Cookie hết hạn",
|
||||
"Cookie expire - Tooltip": "Thời gian hết hạn của cookie - Gợi ý",
|
||||
"Copy SAML metadata URL": "Sao chép URL siêu dữ liệu SAML",
|
||||
"Copy prompt page URL": "Sao chép URL của trang nhắc nhở",
|
||||
"Copy signin page URL": "Sao chép URL trang đăng nhập",
|
||||
@@ -47,9 +47,9 @@
|
||||
"Custom CSS - Tooltip": "Phong cách CSS của các biểu mẫu đăng ký, đăng nhập và quên mật khẩu (ví dụ: thêm đường viền và bóng)",
|
||||
"Custom CSS Mobile": "CSS tùy chỉnh Mobile",
|
||||
"Custom CSS Mobile - Edit": "Chỉnh sửa CSS tùy chỉnh Mobile",
|
||||
"Custom CSS Mobile - Tooltip": "CSS tùy chỉnh cho thiết bị di động",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Custom CSS Mobile - Tooltip": "CSS tùy chỉnh cho thiết bị di động - Gợi ý",
|
||||
"Disable SAML attributes": "Tắt thuộc tính SAML",
|
||||
"Disable SAML attributes - Tooltip": "Vô hiệu hóa thuộc tính SAML - Gợi ý",
|
||||
"Disable signin": "Vô hiệu hóa đăng nhập",
|
||||
"Disable signin - Tooltip": "Vô hiệu hóa đăng nhập cho người dùng",
|
||||
"Dynamic": "Động",
|
||||
@@ -60,16 +60,17 @@
|
||||
"Enable SAML C14N10 - Tooltip": "Sử dụng C14N10 thay vì C14N11 trong SAML",
|
||||
"Enable SAML POST binding": "Bật liên kết SAML POST",
|
||||
"Enable SAML POST binding - Tooltip": "Liên kết HTTP POST sử dụng các trường trong biểu mẫu HTML để gửi tin nhắn SAML, bật khi SP của bạn sử dụng",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "Bật chữ ký xác nhận SAML",
|
||||
"Enable SAML assertion signature - Tooltip": "Kích hoạt chữ ký khẳng định SAML - Gợi ý",
|
||||
"Enable SAML compression": "Cho phép nén SAML",
|
||||
"Enable SAML compression - Tooltip": "Liệu có nén các thông điệp phản hồi SAML khi Casdoor được sử dụng làm SAML idp không?",
|
||||
"Enable exclusive signin": "Enable exclusive signin",
|
||||
"Enable exclusive signin - Tooltip": "When exclusive signin enabled, user cannot have multiple active session",
|
||||
"Enable exclusive signin": "Bật đăng nhập độc quyền",
|
||||
"Enable exclusive signin - Tooltip": "Khi đăng nhập độc quyền được bật, người dùng không thể có nhiều phiên hoạt động",
|
||||
"Enable side panel": "Cho phép bên thanh phẩm",
|
||||
"Enable signin session - Tooltip": "Có phải Casdoor duy trì phiên sau khi đăng nhập vào Casdoor từ ứng dụng không?",
|
||||
"Enable signup": "Kích hoạt đăng ký",
|
||||
"Enable signup - Tooltip": "Có cho phép người dùng đăng ký tài khoản mới không?",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "Thời gian khóa khi đăng nhập thất bại",
|
||||
"Failed signin frozen time - Tooltip": "Thời gian tài khoản bị đóng băng sau các lần đăng nhập thất bại",
|
||||
"Failed signin limit": "Giới hạn đăng nhập thất bại",
|
||||
@@ -89,7 +90,7 @@
|
||||
"Header HTML": "HTML đầu trang",
|
||||
"Header HTML - Edit": "Chỉnh sửa HTML đầu trang",
|
||||
"Header HTML - Tooltip": "Tùy chỉnh thẻ head của trang đầu vào ứng dụng",
|
||||
"Horizontal": "Horizontal",
|
||||
"Horizontal": "Ngang",
|
||||
"Incremental": "Tăng dần",
|
||||
"Inline": "Nội tuyến",
|
||||
"Input": "Nhập",
|
||||
@@ -101,8 +102,8 @@
|
||||
"Logged out successfully": "Đã đăng xuất thành công",
|
||||
"MFA remember time": "Thời gian nhớ MFA",
|
||||
"MFA remember time - Tooltip": "Cấu hình thời gian một tài khoản được ghi nhớ là đáng tin cậy sau khi đăng nhập MFA thành công",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "Chế độ menu",
|
||||
"Menu mode - Tooltip": "Chế độ hiển thị menu - Gợi ý",
|
||||
"Multiple Choices": "Nhiều lựa chọn",
|
||||
"New Application": "Ứng dụng mới",
|
||||
"No verification": "Không xác minh",
|
||||
@@ -111,48 +112,59 @@
|
||||
"Order": "Thứ tự",
|
||||
"Order - Tooltip": "Giá trị càng nhỏ, xếp hạng càng cao trong trang Ứng dụng",
|
||||
"Org choice mode": "Chế độ chọn tổ chức",
|
||||
"Org choice mode - Tooltip": "Chế độ chọn tổ chức",
|
||||
"Org choice mode - Tooltip": "Phương thức chọn tổ chức để đăng nhập - Gợi ý",
|
||||
"Other domains": "Other domains",
|
||||
"Other domains - Tooltip": "Other domains - Tooltip",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "Vui lòng kích hoạt \"Phiên đăng nhập\" trước khi kích hoạt \"Đăng nhập tự động\"",
|
||||
"Please input additional domains": "Please input additional domains",
|
||||
"Please input your application!": "Vui lòng nhập ứng dụng của bạn!",
|
||||
"Please input your organization!": "Vui lòng nhập tổ chức của bạn!",
|
||||
"Please select a HTML file": "Vui lòng chọn tệp HTML",
|
||||
"Pop up": "Bật lên",
|
||||
"Providers": "Providers",
|
||||
"Providers": "Nhà cung cấp",
|
||||
"Proxy SSL mode": "Proxy SSL mode",
|
||||
"Proxy SSL mode - Tooltip": "Proxy SSL mode - Tooltip",
|
||||
"Proxy domain": "Proxy domain",
|
||||
"Proxy domain - Tooltip": "Proxy domain - Tooltip",
|
||||
"Random": "Ngẫu nhiên",
|
||||
"Real name": "Tên thật",
|
||||
"Redirect URL": "Chuyển hướng URL",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Điều hướng URL (URL khung POST Dịch vụ Tiêu thụ Khẳng định)",
|
||||
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Điều hướng URL (URL khung POST Dịch vụ Tiêu thụ Khẳng định) - Gợi ý",
|
||||
"Redirect URLs": "Chuyển hướng URL",
|
||||
"Redirect URLs - Tooltip": "Danh sách URL chuyển hướng được phép, hỗ trợ khớp biểu thức chính quy; các URL không có trong danh sách sẽ không được chuyển hướng",
|
||||
"Refresh token expire": "Làm mới mã thông báo hết hạn",
|
||||
"Refresh token expire - Tooltip": "Thời gian hết hạn của mã thông báo làm mới",
|
||||
"Reset to Empty": "Đặt lại thành trống",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
"Right": "Đúng",
|
||||
"Rule": "Quy tắc",
|
||||
"SAML hash algorithm": "Thuật toán hash SAML",
|
||||
"SAML hash algorithm - Tooltip": "Thuật toán hash cho chữ ký SAML",
|
||||
"SAML hash algorithm - Tooltip": "Thuật toán hash cho chữ ký SAML - Gợi ý",
|
||||
"SAML metadata": "SAML metadata: Siêu dữ liệu SAML",
|
||||
"SAML metadata - Tooltip": "Các siêu dữ liệu của giao thức SAML",
|
||||
"SAML metadata - Tooltip": "Metadata của giao thức SAML - Gợi ý",
|
||||
"SAML reply URL": "URL phản hồi SAML",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL cert",
|
||||
"SSL cert - Tooltip": "SSL cert - Tooltip",
|
||||
"Security": "Bảo mật",
|
||||
"Select": "Chọn",
|
||||
"Side panel HTML": "Bảng điều khiển HTML bên lề",
|
||||
"Side panel HTML - Edit": "Bảng Panel Bên - Chỉnh sửa HTML",
|
||||
"Side panel HTML - Tooltip": "Tùy chỉnh mã HTML cho bảng điều khiển bên của trang đăng nhập",
|
||||
"Side panel HTML - Tooltip": "Tùy chỉnh mã HTML của bảng bên trang đăng nhập - Gợi ý",
|
||||
"Sign Up Error": "Lỗi đăng ký",
|
||||
"Signin": "Đăng nhập",
|
||||
"Signin (Default True)": "Đăng nhập (Mặc định True)",
|
||||
"Signin items": "Các mục đăng nhập",
|
||||
"Signin items - Tooltip": "Mục đăng nhập",
|
||||
"Signin items - Tooltip": "Mục đăng nhập - Gợi ý",
|
||||
"Signin methods": "Phương thức đăng nhập",
|
||||
"Signin methods - Tooltip": "Gợi ý phương thức đăng nhập",
|
||||
"Signin methods - Tooltip": "Gợi ý phương thức đăng nhập - Gợi ý",
|
||||
"Signin session": "Phiên đăng nhập",
|
||||
"Signup items": "Các mục đăng ký",
|
||||
"Signup items - Tooltip": "Các thông tin cần được người dùng điền khi đăng ký tài khoản mới",
|
||||
"Signup items - Tooltip": "Mục cho người dùng đề điền khi đăng nhập - Gợi ý",
|
||||
"Single Choice": "Lựa chọn đơn",
|
||||
"Small icon": "Biểu tượng nhỏ",
|
||||
"String": "String",
|
||||
"Tags - Tooltip": "Chỉ người dùng có thẻ được liệt kê trong thẻ ứng dụng mới có thể đăng nhập",
|
||||
"Static Value": "Static Value",
|
||||
"String": "Chuỗi",
|
||||
"Tags - Tooltip": "Chỉ người dùng có thẻ được liệt kê trong thẻ ứng dụng mới có thể đăng nhập - Gợi ý",
|
||||
"The application does not allow to sign up new account": "Ứng dụng không cho phép đăng ký tài khoản mới",
|
||||
"Token expire": "Mã thông báo hết hạn",
|
||||
"Token expire - Tooltip": "Thời gian hết hạn của mã truy cập",
|
||||
@@ -162,10 +174,12 @@
|
||||
"Token format - Tooltip": "Định dạng của mã thông báo truy cập",
|
||||
"Token signing method": "Phương thức ký token",
|
||||
"Token signing method - Tooltip": "Phương thức ký token JWT, cần cùng thuật toán với chứng chỉ",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "Tùy chỉnh giao diện",
|
||||
"Upstream host": "Upstream host",
|
||||
"Upstream host - Tooltip": "Upstream host - Tooltip",
|
||||
"Use Email as NameID": "Sử dụng Email làm NameID",
|
||||
"Use Email as NameID - Tooltip": "Gợi ý sử dụng Email làm NameID",
|
||||
"Vertical": "Vertical",
|
||||
"Vertical": "Dọc",
|
||||
"You are unexpected to see this prompt page": "Bạn không mong đợi thấy trang này hiện lên"
|
||||
},
|
||||
"cert": {
|
||||
@@ -250,7 +264,7 @@
|
||||
"Width": "Chiều rộng"
|
||||
},
|
||||
"general": {
|
||||
"A normal user can only modify the permission submitted by itself": "A normal user can only modify the permission submitted by itself",
|
||||
"A normal user can only modify the permission submitted by itself": "Người dùng thường chỉ có thể sửa đổi quyền do chính họ gửi",
|
||||
"AI Assistant": "Trợ lý AI",
|
||||
"API key": "Khóa API",
|
||||
"API key - Tooltip": "Khóa API để truy cập dịch vụ",
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "Kinh doanh & Thanh toán",
|
||||
"Cancel": "Hủy bỏ",
|
||||
"Captcha": "Mã xác nhận",
|
||||
"Cart": "Cart",
|
||||
"Cart": "Giỏ hàng",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "Chứng chỉ",
|
||||
"Cert - Tooltip": "Chứng chỉ khóa công khai cần được xác minh bởi SDK khách hàng tương ứng với ứng dụng này",
|
||||
"Certs": "Chứng chỉ",
|
||||
"Clear": "Clear",
|
||||
"Clear": "Xóa",
|
||||
"Click to Upload": "Nhấp để tải lên",
|
||||
"Client IP": "IP khách hàng",
|
||||
"Close": "Đóng lại",
|
||||
@@ -307,12 +323,12 @@
|
||||
"Delete": "Xóa",
|
||||
"Description": "Mô tả",
|
||||
"Description - Tooltip": "Thông tin chi tiết mô tả cho tham khảo, Casdoor chính nó sẽ không sử dụng nó",
|
||||
"Detail": "详情",
|
||||
"Detail": "Chi tiết",
|
||||
"Disable": "Tắt",
|
||||
"Display name": "Tên hiển thị",
|
||||
"Display name - Tooltip": "Một tên dễ sử dụng, dễ đọc được hiển thị công khai trên giao diện người dùng",
|
||||
"Down": "Xuống",
|
||||
"Download template": "Download template",
|
||||
"Download template": "Tải template",
|
||||
"Edit": "Sửa",
|
||||
"Email": "Email: Thư điện tử",
|
||||
"Email - Tooltip": "Địa chỉ email hợp lệ",
|
||||
@@ -327,21 +343,21 @@
|
||||
"Enabled successfully": "Bật thành công",
|
||||
"Enforcers": "Trình thực thi",
|
||||
"Failed to add": "Không thể thêm được",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "Không thể hủy",
|
||||
"Failed to connect to server": "Không thể kết nối đến máy chủ",
|
||||
"Failed to copy": "Sao chép thất bại",
|
||||
"Failed to delete": "Không thể xoá",
|
||||
"Failed to enable": "Bật thất bại",
|
||||
"Failed to get": "Không lấy được",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to log out": "Failed to log out",
|
||||
"Failed to load": "Không thể tải",
|
||||
"Failed to log out": "Không thể đăng xuất",
|
||||
"Failed to remove": "Xóa thất bại",
|
||||
"Failed to save": "Không thể lưu lại",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "Không thể gửi",
|
||||
"Failed to sync": "Đồng bộ thất bại",
|
||||
"Failed to unlink": "Failed to unlink",
|
||||
"Failed to update": "Failed to update",
|
||||
"Failed to upload": "Failed to upload",
|
||||
"Failed to unlink": "Không thể hủy liên kết",
|
||||
"Failed to update": "Không thể cập nhật",
|
||||
"Failed to upload": "Không thể tải lên",
|
||||
"Failed to verify": "Xác minh thất bại",
|
||||
"False": "Sai",
|
||||
"Favicon": "Biểu tượng trang",
|
||||
@@ -354,7 +370,7 @@
|
||||
"Forget URL - Tooltip": "Đường dẫn tùy chỉnh cho trang \"Quên mật khẩu\". Nếu không được thiết lập, trang \"Quên mật khẩu\" mặc định của Casdoor sẽ được sử dụng. Khi cài đặt, liên kết \"Quên mật khẩu\" trên trang đăng nhập sẽ chuyển hướng đến URL này",
|
||||
"Forms": "Biểu mẫu",
|
||||
"Found some texts still not translated? Please help us translate at": "Tìm thấy một số văn bản vẫn chưa được dịch? Vui lòng giúp chúng tôi dịch tại",
|
||||
"Generate": "Generate",
|
||||
"Generate": "Tạo",
|
||||
"Go to enable": "Đi để bật",
|
||||
"Go to writable demo site?": "Bạn có muốn đi đến trang demo có thể viết được không?",
|
||||
"Groups": "Nhóm",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "Danh sách trắng IP",
|
||||
"IP whitelist - Tooltip": "Danh sách trắng IP",
|
||||
"Identity": "Danh tính",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "Giả danh",
|
||||
"Invitations": "Lời mời",
|
||||
"Is enabled": "Đã được kích hoạt",
|
||||
"Is enabled - Tooltip": "Đặt liệu nó có thể sử dụng hay không",
|
||||
@@ -381,7 +397,7 @@
|
||||
"Last name - Tooltip": "Họ của người dùng",
|
||||
"Later": "Để sau",
|
||||
"Logging & Auditing": "Nhật ký & Kiểm toán",
|
||||
"Login page": "Login page",
|
||||
"Login page": "Trang đăng nhập",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Biểu tượng mà ứng dụng hiển thị ra ngoài thế giới",
|
||||
"Logo dark": "Logo tối",
|
||||
@@ -400,21 +416,21 @@
|
||||
"Name": "Tên",
|
||||
"Name - Tooltip": "ID duy nhất dựa trên chuỗi",
|
||||
"Name format": "Định dạng tên",
|
||||
"No products available": "No products available",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No verification method": "No verification method",
|
||||
"No products available": "Không có sản phẩm nào",
|
||||
"No sheets found in file": "Không tìm thấy trang tính trong file",
|
||||
"No verification method": "Không có phương thức xác minh",
|
||||
"Non-LDAP": "Không phải LDAP",
|
||||
"None": "Không có",
|
||||
"OAuth providers": "Nhà cung cấp OAuth",
|
||||
"OFF": "TẮT",
|
||||
"OK": "OK",
|
||||
"ON": "BẬT",
|
||||
"Only 1 MFA method can be required": "Only 1 MFA method can be required",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Only 1 MFA method can be required": "Chỉ có thể yêu cầu 1 phương thức MFA",
|
||||
"Or": "Hoặc",
|
||||
"Orders": "Đơn hàng",
|
||||
"Organization": "Tổ chức",
|
||||
"Organization - Tooltip": "Tương tự như các khái niệm như người thuê hoặc nhóm người dùng, mỗi người dùng và ứng dụng đều thuộc về một tổ chức",
|
||||
"Organization is null": "Organization is null",
|
||||
"Organization is null": "Tổ chức trống",
|
||||
"Organizations": "Tổ chức",
|
||||
"Password": "Mật khẩu",
|
||||
"Password - Tooltip": "Hãy đảm bảo rằng mật khẩu là chính xác",
|
||||
@@ -437,21 +453,21 @@
|
||||
"Phone - Tooltip": "Số điện thoại",
|
||||
"Phone only": "Chỉ điện thoại",
|
||||
"Phone or Email": "Điện thoại hoặc email",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "Đặt hàng",
|
||||
"Plain": "Thường",
|
||||
"Plan": "Gói",
|
||||
"Plan - Tooltip": "Gói đăng ký",
|
||||
"Plans": "Kế hoạch",
|
||||
"Plans - Tooltip": "Gợi ý các gói",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "Vui lòng hoàn thành captcha chính xác",
|
||||
"Please input your search": "Vui lòng nhập tìm kiếm của bạn",
|
||||
"Please select at least 1 user first": "Please select at least 1 user first",
|
||||
"Please select at least 1 user first": "Vui lòng chọn ít nhất 1 người dùng trước",
|
||||
"Preview": "Xem trước",
|
||||
"Preview - Tooltip": "Xem trước các hiệu ứng đã cấu hình",
|
||||
"Pricing": "Giá",
|
||||
"Pricing - Tooltip": "Gợi ý giá",
|
||||
"Pricings": "Bảng giá",
|
||||
"Product Store": "Product Store",
|
||||
"Product Store": "Cửa hàng sản phẩm",
|
||||
"Products": "Sản phẩm",
|
||||
"Provider": "Nhà cung cấp",
|
||||
"Provider - Tooltip": "Cung cấp thanh toán được cấu hình, bao gồm PayPal, Alipay, WeChat Pay, vv.",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "Loại xác thực kết nối SSH",
|
||||
"Save": "Lưu",
|
||||
"Save & Exit": "Lưu và Thoát",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "Tìm kiếm",
|
||||
"Send": "Gửi",
|
||||
"Session ID": "ID phiên làm việc",
|
||||
@@ -493,13 +511,13 @@
|
||||
"Sorry, you do not have permission to access this page or logged in status invalid.": "Xin lỗi, bạn không có quyền truy cập trang này hoặc trạng thái đăng nhập không hợp lệ.",
|
||||
"State": "Nhà nước",
|
||||
"State - Tooltip": "Trạng thái",
|
||||
"Status": "Status",
|
||||
"Status": "Trạng thái",
|
||||
"Subscriptions": "Đăng ký",
|
||||
"Successfully added": "Đã thêm thành công",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "Hủy thành công",
|
||||
"Successfully copied": "Đã sao chép thành công",
|
||||
"Successfully deleted": "Đã xóa thành công",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "Thực hiện thành công",
|
||||
"Successfully removed": "Đã xóa thành công",
|
||||
"Successfully saved": "Thành công đã được lưu lại",
|
||||
"Successfully sent": "Đã gửi thành công",
|
||||
@@ -514,9 +532,9 @@
|
||||
"Syncers": "Công cụ đồng bộ",
|
||||
"System Info": "Thông tin hệ thống",
|
||||
"Tab": "Tab",
|
||||
"The actions cannot be empty": "The actions cannot be empty",
|
||||
"The resources cannot be empty": "The resources cannot be empty",
|
||||
"The users and roles cannot be empty at the same time": "The users and roles cannot be empty at the same time",
|
||||
"The actions cannot be empty": "Các hành động không được để trống",
|
||||
"The resources cannot be empty": "Các tài nguyên không được để trống",
|
||||
"The users and roles cannot be empty at the same time": "Người dùng và vai trò không được trống cùng lúc",
|
||||
"There was a problem signing you in..": "Đã xảy ra lỗi khi đăng nhập..",
|
||||
"This is a read-only demo site!": "Đây là trang web giới thiệu chỉ có chức năng đọc!",
|
||||
"Tickets": "Tickets",
|
||||
@@ -530,17 +548,18 @@
|
||||
"Transactions": "Giao dịch",
|
||||
"True": "Đúng",
|
||||
"Type": "Loại",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "URL",
|
||||
"URL - Tooltip": "Đường dẫn URL",
|
||||
"Unknown application name": "Unknown application name",
|
||||
"Unknown authentication type": "Unknown authentication type",
|
||||
"Unknown application name": "Tên ứng dụng không xác định",
|
||||
"Unknown authentication type": "Loại xác thực không xác định",
|
||||
"Up": "Lên",
|
||||
"Updated time": "Thời gian cập nhật",
|
||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||
"Upload (.xlsx)": "Tải lên (.xlsx)",
|
||||
"User": "Người dùng",
|
||||
"User - Tooltip": "Hãy đảm bảo tên đăng nhập chính xác",
|
||||
"User Management": "Quản lý người dùng",
|
||||
"User already exists": "User already exists",
|
||||
"User already exists": "Người dùng đã tồn tại",
|
||||
"User containers": "Nhóm người dùng",
|
||||
"User type": "Loại người dùng",
|
||||
"User type - Tooltip": "Các thẻ mà người dùng thuộc vào, mặc định là \"người dùng bình thường\"",
|
||||
@@ -548,10 +567,10 @@
|
||||
"Users - Tooltip": "Gợi ý người dùng",
|
||||
"Users under all organizations": "Người dùng trong tất cả các tổ chức",
|
||||
"Verifications": "Xác minh",
|
||||
"View": "View",
|
||||
"View": "Xem",
|
||||
"Webhooks": "Webhooks",
|
||||
"You can only select one physical group": "Bạn chỉ có thể chọn một nhóm vật lý",
|
||||
"You must select a picture first": "You must select a picture first",
|
||||
"You must select a picture first": "Bạn phải chọn một hình ảnh trước",
|
||||
"empty": "trống",
|
||||
"remove": "xóa",
|
||||
"{total} in total": "Trong tổng số {total}"
|
||||
@@ -619,14 +638,14 @@
|
||||
"Server port": "Cổng máy chủ",
|
||||
"Server port - Tooltip": "Cổng máy chủ LDAP",
|
||||
"The Auto Sync option will sync all users to specify organization": "Tùy chọn Auto Sync sẽ đồng bộ tất cả người dùng vào tổ chức cụ thể",
|
||||
"User property name": "User property name",
|
||||
"User property name": "Tên thuộc tính người dùng",
|
||||
"synced": "đã đồng bộ",
|
||||
"unsynced": "chưa đồng bộ"
|
||||
},
|
||||
"login": {
|
||||
"Auto sign in": "Tự động đăng nhập",
|
||||
"Back button": "Nút quay lại",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "Nhấp vào nút bên dưới để đăng nhập bằng Telegram",
|
||||
"Continue with": "Tiếp tục với",
|
||||
"Email or phone": "Email hoặc điện thoại",
|
||||
"Face ID": "Xác thực khuôn mặt",
|
||||
@@ -649,12 +668,12 @@
|
||||
"Please input your Email!": "Vui lòng nhập Email của bạn!",
|
||||
"Please input your LDAP username!": "Vui lòng nhập tên người dùng LDAP!",
|
||||
"Please input your Phone!": "Vui lòng nhập số điện thoại!",
|
||||
"Please input your RADIUS password!": "Please input your RADIUS password!",
|
||||
"Please input your RADIUS username!": "Please input your RADIUS username!",
|
||||
"Please input your RADIUS password!": "Vui lòng nhập mật khẩu RADIUS của bạn!",
|
||||
"Please input your RADIUS username!": "Vui lòng nhập tên người dùng RADIUS của bạn!",
|
||||
"Please input your code!": "Vui lòng nhập mã của bạn!",
|
||||
"Please input your organization name!": "Vui lòng nhập tên tổ chức!",
|
||||
"Please input your password!": "Vui lòng nhập mật khẩu của bạn!",
|
||||
"Please input your push notification receiver!": "Please input your push notification receiver!",
|
||||
"Please input your push notification receiver!": "Vui lòng nhập người nhận thông báo đẩy của bạn!",
|
||||
"Please load the webpage using HTTPS, otherwise the camera cannot be accessed": "Vui lòng tải trang bằng HTTPS, nếu không camera không thể truy cập",
|
||||
"Please provide permission to access the camera": "Vui lòng cấp quyền truy cập camera",
|
||||
"Please select an organization": "Vui lòng chọn một tổ chức",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "Chọn tổ chức",
|
||||
"Sign In": "Đăng nhập",
|
||||
"Sign in with Face ID": "Đăng nhập bằng Face ID",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "Đăng nhập bằng Telegram",
|
||||
"Sign in with WebAuthn": "Đăng nhập với WebAuthn",
|
||||
"Sign in with {type}": "Đăng nhập bằng {type}",
|
||||
"Signin button": "Nút đăng nhập",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "Vui lòng xác nhận thông tin dưới đây",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "Vui lòng lưu mã khôi phục này. Khi thiết bị không thể cung cấp mã xác thực, bạn có thể đặt lại xác thực mfa bằng mã này",
|
||||
"Protect your account with Multi-factor authentication": "Bảo vệ tài khoản của bạn với xác thực đa yếu tố",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "Người nhận thông báo đẩy",
|
||||
"Recovery code": "Mã khôi phục",
|
||||
"Remember this account for {hour} hours": "Nhớ tài khoản này trong {hour} giờ",
|
||||
"Scan the QR code with your Authenticator App": "Quét mã QR bằng ứng dụng xác thực của bạn",
|
||||
@@ -708,17 +727,17 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "Để đảm bảo an toàn cho tài khoản, bắt buộc bật xác thực đa yếu tố",
|
||||
"Use Authenticator App": "Sử dụng ứng dụng xác thực",
|
||||
"Use Email": "Sử dụng Email",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Radius": "Use Radius",
|
||||
"Use Push Notification": "Sử dụng thông báo đẩy",
|
||||
"Use Radius": "Sử dụng Radius",
|
||||
"Use SMS": "Sử dụng SMS",
|
||||
"Use SMS verification code": "Sử dụng mã xác minh SMS",
|
||||
"Use a recovery code": "Sử dụng mã khôi phục",
|
||||
"Verify Code": "Mã xác minh",
|
||||
"Verify Password": "Xác minh mật khẩu",
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "Bạn đã bật xác thực đa yếu tố, vui lòng nhấp 'Gửi mã' để tiếp tục",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "You have enabled Multi-Factor Authentication, please enter the RADIUS password",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "Bạn đã bật xác thực đa yếu tố, vui lòng nhập mật khẩu RADIUS",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "Bạn đã bật xác thực đa yếu tố, vui lòng nhập mã TOTP",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "Bạn đã bật xác thực đa yếu tố, vui lòng nhập mã xác minh từ thông báo đẩy",
|
||||
"Your email is": "Email của bạn là",
|
||||
"Your phone is": "Số điện thoại của bạn là",
|
||||
"preferred": "ưu tiên"
|
||||
@@ -732,30 +751,31 @@
|
||||
"New Model": "Mô hình mới"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "Thời gian hủy",
|
||||
"Edit Order": "Chỉnh sửa đơn hàng",
|
||||
"New Order": "Đơn hàng mới",
|
||||
"Order not found": "Không tìm thấy đơn hàng",
|
||||
"Pay": "Thanh toán",
|
||||
"Payment failed time": "Thời gian thanh toán thất bại",
|
||||
"Payment time": "Thời gian thanh toán",
|
||||
"Price": "Giá",
|
||||
"Return to Order List": "Quay lại danh sách đơn hàng",
|
||||
"Timeout time": "Thời gian hết hạn",
|
||||
"View Order": "Xem đơn hàng"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "Mục tài khoản",
|
||||
"Account items - Tooltip": "Các mục trong trang Cài đặt cá nhân",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Edit Organization": "Sửa tổ chức",
|
||||
"Account menu": "Menu tài khoản",
|
||||
"Account menu - Tooltip": "Menu tài khoản",
|
||||
"Admin navbar items": "Mục navbar quản trị",
|
||||
"Admin navbar items - Tooltip": "Mục navbar quản trị",
|
||||
"All": "All",
|
||||
"Balance credit": "Số dư tín dụng",
|
||||
"Balance credit - Tooltip": "Số dư tín dụng",
|
||||
"Balance currency": "Đơn vị tiền tệ",
|
||||
"Balance currency - Tooltip": "Đơn vị tiền tệ",
|
||||
"Edit Organization": "Chỉnh sửa tổ chức",
|
||||
"Follow global theme": "Theo giao diện chung",
|
||||
"Has privilege consent": "Có sự đồng ý đặc quyền",
|
||||
"Has privilege consent - Tooltip": "Ngăn thêm người dùng cho tổ chức tích hợp nếu HasPrivilegeConsent là false",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "Sửa đổi quy tắc",
|
||||
"New Organization": "Tổ chức mới",
|
||||
"Optional": "Tùy chọn",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "Số dư tổ chức",
|
||||
"Org balance - Tooltip": "Số dư tổ chức - Gợi ý",
|
||||
"Password expire days": "Số ngày hết hạn mật khẩu",
|
||||
"Password expire days - Tooltip": "Gợi ý số ngày hết hạn mật khẩu",
|
||||
"Prompt": "Nhắc",
|
||||
@@ -778,10 +798,10 @@
|
||||
"Tags": "Thẻ",
|
||||
"Use Email as username": "Sử dụng Email làm tên người dùng",
|
||||
"Use Email as username - Tooltip": "Sử dụng Email làm tên người dùng nếu trường tên người dùng không hiển thị khi đăng ký",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User balance": "Số dư người dùng",
|
||||
"User balance - Tooltip": "Số dư người dùng - Gợi ý",
|
||||
"User navbar items": "Các mục thanh điều hướng người dùng",
|
||||
"User navbar items - Tooltip": "Các mục thanh điều hướng người dùng - Gợi ý",
|
||||
"User types": "Loại người dùng",
|
||||
"User types - Tooltip": "Gợi ý loại người dùng",
|
||||
"View rule": "Xem quy tắc",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Hãy kiểm tra thông tin hóa đơn của bạn cẩn thận. Một khi hóa đơn đã được phát hành, nó không thể được thu hồi hoặc chỉnh sửa.",
|
||||
"Please pay the order first!": "Vui lòng thanh toán đơn hàng trước!",
|
||||
"Processing...": "Đang xử lý...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "Sản phẩm - Gợi ý",
|
||||
"Recharged successfully": "Nạp tiền thành công",
|
||||
"Result": "Kết quả",
|
||||
"The payment has been canceled": "Thanh toán đã bị hủy",
|
||||
"The payment has failed": "Thanh toán đã thất bại",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "Thanh toán đã hết hạn",
|
||||
"The payment is still under processing": "Thanh toán vẫn đang được xử lý",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "Xem thanh toán",
|
||||
"You can view your order details or return to the order list": "Bạn có thể xem chi tiết đơn hàng hoặc quay lại danh sách đơn hàng",
|
||||
"You have successfully completed the payment": "Bạn đã hoàn thành thanh toán thành công",
|
||||
"You have successfully recharged": "Bạn đã nạp tiền thành công",
|
||||
"Your current balance is": "Số dư hiện tại của bạn là",
|
||||
@@ -867,13 +887,15 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "Chỉnh sửa gói",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "Gói mới",
|
||||
"Period": "Kỳ",
|
||||
"Period - Tooltip": "Thời kỳ",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "Tên gói",
|
||||
"Price - Tooltip": "Giá",
|
||||
"Related product": "Sản phẩm liên quan",
|
||||
"View Plan": "View Plan",
|
||||
"View Plan": "Xem gói",
|
||||
"per month": "mỗi tháng",
|
||||
"per year": "mỗi năm"
|
||||
},
|
||||
@@ -883,55 +905,62 @@
|
||||
"Free": "Miễn phí",
|
||||
"Getting started": "Bắt đầu",
|
||||
"New Pricing": "Giá mới",
|
||||
"Pricing name": "Pricing name",
|
||||
"Pricing name": "Tên bảng giá",
|
||||
"Trial duration": "Thời gian thử nghiệm",
|
||||
"Trial duration - Tooltip": "Thời gian thử nghiệm",
|
||||
"View Pricing": "View Pricing",
|
||||
"View Pricing": "Xem bảng giá",
|
||||
"days trial available!": "ngày dùng thử có sẵn!",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "người dùng trả phí không có đăng ký hoạt động hoặc đang chờ, vui lòng chọn gói để mua"
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "Thêm vào giỏ hàng",
|
||||
"AirWallex": "AirWallex",
|
||||
"Alipay": "Alipay",
|
||||
"Amount": "Amount",
|
||||
"Amount": "Số tiền",
|
||||
"Buy": "Mua",
|
||||
"Buy Product": "Mua sản phẩm",
|
||||
"Custom amount available": "Custom amount available",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "Số tiền tùy chỉnh có sẵn",
|
||||
"Custom price should be greater than zero": "Giá tùy chỉnh phải lớn hơn không",
|
||||
"Detail - Tooltip": "Chi tiết sản phẩm",
|
||||
"Disable custom amount": "Disable custom amount",
|
||||
"Disable custom amount - Tooltip": "Disable custom amount - Tooltip",
|
||||
"Disable custom amount": "Tắt số tiền tùy chỉnh",
|
||||
"Disable custom amount - Tooltip": "Tắt số tiền tùy chỉnh - Gợi ý",
|
||||
"Dummy": "Giả",
|
||||
"Edit Product": "Sửa sản phẩm",
|
||||
"Enter preset amounts": "Enter preset amounts",
|
||||
"Failed to create order": "Failed to create order",
|
||||
"Enter preset amounts": "Nhập số tiền đặt trước",
|
||||
"Failed to create order": "Không thể tạo đơn hàng",
|
||||
"Image": "Ảnh",
|
||||
"Image - Tooltip": "Hình ảnh sản phẩm",
|
||||
"Information": "Information",
|
||||
"Information": "Thông tin",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "Là nạp tiền",
|
||||
"Is recharge - Tooltip": "Sản phẩm hiện tại có phải để nạp số dư",
|
||||
"Name": "Name",
|
||||
"New Product": "Sản phẩm mới",
|
||||
"Order created successfully": "Order created successfully",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "Tạo đơn hàng thành công",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "Thanh toán đã bị hủy",
|
||||
"Payment failed": "Thanh toán thất bại",
|
||||
"Payment providers": "Nhà cung cấp thanh toán",
|
||||
"Payment providers - Tooltip": "Nhà cung cấp dịch vụ thanh toán",
|
||||
"Placing order...": "Đặt hàng...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Please add at least one recharge option when custom amount is disabled",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please add at least one recharge option when custom amount is disabled": "Vui lòng thêm ít nhất một tùy chọn nạp tiền khi số tiền tùy chỉnh bị tắt",
|
||||
"Please select a currency": "Vui lòng chọn một loại tiền tệ",
|
||||
"Please select at least one payment provider": "Vui lòng chọn ít nhất một nhà cung cấp thanh toán",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "Đang xử lý thanh toán...",
|
||||
"Product list cannot be empty": "Danh sách sản phẩm không thể trống",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "Số lượng",
|
||||
"Quantity - Tooltip": "Số lượng sản phẩm",
|
||||
"Recharge options": "Recharge options",
|
||||
"Recharge options - Tooltip": "Recharge options - Tooltip",
|
||||
"Recharge options": "Tùy chọn nạp tiền",
|
||||
"Recharge options - Tooltip": "Tùy chọn nạp tiền - Gợi ý",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "Địa chỉ URL trở lại",
|
||||
"Return URL - Tooltip": "URL để quay lại sau khi mua hàng thành công",
|
||||
"SKU": "SKU",
|
||||
"Select amount": "Select amount",
|
||||
"Select amount": "Chọn số tiền",
|
||||
"Sold": "Đã bán",
|
||||
"Sold - Tooltip": "Số lượng bán ra",
|
||||
"Stripe": "Stripe",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "URL để quay lại sau khi mua",
|
||||
"Tag - Tooltip": "Nhãn sản phẩm",
|
||||
"Test buy page..": "Trang mua thử.",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "Tiền tệ của sản phẩm bạn đang thêm khác với tiền tệ của các mặt hàng trong giỏ hàng",
|
||||
"There is no payment channel for this product.": "Không có kênh thanh toán cho sản phẩm này.",
|
||||
"This product is currently not in sale.": "Sản phẩm này hiện không được bán.",
|
||||
"This product is currently not purchasable (No options available)": "This product is currently not purchasable (No options available)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"This product is currently not purchasable (No options available)": "Sản phẩm này hiện không thể mua được (Không có tùy chọn)",
|
||||
"Total Price": "Tổng giá",
|
||||
"View Product": "Xem sản phẩm",
|
||||
"WeChat Pay": "WeChat Pay"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "Gợi ý khóa xác thực",
|
||||
"Auth URL": "URL xác thực",
|
||||
"Auth URL - Tooltip": "URL chứng thực",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "URL cơ sở",
|
||||
"Base URL - Tooltip": "Gợi ý URL cơ sở",
|
||||
"Bucket": "Thùng đựng nước",
|
||||
@@ -989,9 +1019,8 @@
|
||||
"Content": "Nội dung",
|
||||
"Content - Tooltip": "Gợi ý nội dung",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "Vô hiệu hóa SSL",
|
||||
"Disable SSL - Tooltip": "Có nên vô hiệu hóa giao thức SSL khi giao tiếp với máy chủ STMP hay không?",
|
||||
"DB test - Tooltip": "Kiểm tra DB - Gợi ý",
|
||||
"Disable": "Disable",
|
||||
"Domain": "Miền",
|
||||
"Domain - Tooltip": "Tên miền tùy chỉnh cho lưu trữ đối tượng",
|
||||
"Edit Provider": "Chỉnh sửa nhà cung cấp",
|
||||
@@ -1001,8 +1030,9 @@
|
||||
"Email regex - Tooltip": "Gợi ý biểu thức chính quy Email",
|
||||
"Email title": "Tiêu đề email",
|
||||
"Email title - Tooltip": "Tiêu đề của email",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable PKCE - Tooltip": "Kích hoạt PKCE - Gợi ý",
|
||||
"Enable proxy": "Enable proxy",
|
||||
"Enable proxy - Tooltip": "Enable socks5 Proxy when sending email or sms",
|
||||
"Endpoint": "Điểm cuối",
|
||||
@@ -1030,7 +1060,7 @@
|
||||
"Key ID": "ID khóa",
|
||||
"Key ID - Tooltip": "ID khóa",
|
||||
"Key text": "Văn bản khóa",
|
||||
"Key text - Tooltip": "Key text - Tooltip",
|
||||
"Key text - Tooltip": "Văn bản khóa - Gợi ý",
|
||||
"LDAP port": "LDAP port",
|
||||
"Metadata": "Siêu dữ liệu",
|
||||
"Metadata - Tooltip": "SAML metadata: siêu dữ liệu SAML",
|
||||
@@ -1072,11 +1102,14 @@
|
||||
"SMS account - Tooltip": "Tài khoản SMS",
|
||||
"SMTP connected successfully": "Kết nối SMTP thành công",
|
||||
"SP ACS URL": "SP ACC URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||
"SP ACS URL - Tooltip": "URL ACS của SP - Gợi ý",
|
||||
"SP Entity ID": "SP Entity ID: Định danh thực thể SP",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "Cảnh",
|
||||
"Scene - Tooltip": "Cảnh",
|
||||
"Scope": "Phạm vi",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "Chìa khóa truy cập bí mật",
|
||||
"Secret access key - Tooltip": "Khóa truy cập bí mật",
|
||||
"Secret key": "Chìa khóa bí mật",
|
||||
@@ -1089,9 +1122,9 @@
|
||||
"Sender number": "Số người gửi",
|
||||
"Sender number - Tooltip": "Gợi ý số người gửi",
|
||||
"Service ID identifier": "Định danh ID dịch vụ",
|
||||
"Service ID identifier - Tooltip": "Service ID identifier - Tooltip",
|
||||
"Service ID identifier - Tooltip": "Định danh ID dịch vụ - Gợi ý",
|
||||
"Service account JSON": "Tài khoản dịch vụ JSON",
|
||||
"Service account JSON - Tooltip": "Service account JSON - Tooltip",
|
||||
"Service account JSON - Tooltip": "Tài khoản dịch vụ JSON - Gợi ý",
|
||||
"Sign Name": "Ký tên",
|
||||
"Sign Name - Tooltip": "Tên chữ ký sẽ được sử dụng",
|
||||
"Sign request": "Yêu cầu ký tên",
|
||||
@@ -1112,11 +1145,11 @@
|
||||
"Subject": "Tiêu đề",
|
||||
"Subject - Tooltip": "Tiêu đề email",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype - Tooltip": "Kiểu phụ - Gợi ý",
|
||||
"Syncer test": "Kiểm tra bộ đồng bộ",
|
||||
"Syncer test - Tooltip": "Kiểm tra xem kết nối bộ đồng bộ có hoạt động không",
|
||||
"Team ID": "ID nhóm",
|
||||
"Team ID - Tooltip": "Team ID - Tooltip",
|
||||
"Team ID - Tooltip": "ID nhóm - Gợi ý",
|
||||
"Template code": "Mã mẫu của template",
|
||||
"Template code - Tooltip": "Mã mẫu của template",
|
||||
"Tenant ID": "ID Tenant",
|
||||
@@ -1139,7 +1172,7 @@
|
||||
"Use id as name": "Sử dụng ID làm tên",
|
||||
"Use id as name - Tooltip": "Sử dụng ID làm tên người dùng",
|
||||
"User flow": "Luồng người dùng",
|
||||
"User flow - Tooltip": "User flow - Tooltip",
|
||||
"User flow - Tooltip": "Luồng người dùng - Gợi ý",
|
||||
"User mapping": "Ánh xạ người dùng",
|
||||
"User mapping - Tooltip": "Gợi ý ánh xạ người dùng",
|
||||
"UserInfo URL": "Đường dẫn UserInfo",
|
||||
@@ -1169,7 +1202,7 @@
|
||||
"Sub domains": "Các phân miền con",
|
||||
"Sub domains - Tooltip": "Các lĩnh vực được bao gồm trong vai trò hiện tại",
|
||||
"Sub groups": "Nhóm con",
|
||||
"Sub groups - Tooltip": "Sub groups - Tooltip",
|
||||
"Sub groups - Tooltip": "Các nhóm được bao gồm trong vai trò hiện tại",
|
||||
"Sub roles": "Các vai trò phụ",
|
||||
"Sub roles - Tooltip": "Các vai trò bao gồm trong vai trò hiện tại",
|
||||
"Sub users": "Người dùng trong phụ",
|
||||
@@ -1197,7 +1230,7 @@
|
||||
"Please input your last name!": "Vui lòng nhập họ của bạn!",
|
||||
"Please input your phone number!": "Vui lòng nhập số điện thoại của bạn!",
|
||||
"Please input your real name!": "Vui lòng nhập tên thật của bạn!",
|
||||
"Please input your {label}!": "Please input your {label}!",
|
||||
"Please input your {label}!": "Vui lòng nhập {label} của bạn!",
|
||||
"Please select your country code!": "Vui lòng chọn mã quốc gia của bạn!",
|
||||
"Please select your country/region!": "Vui lòng chọn quốc gia/vùng của bạn!",
|
||||
"Regex": "Biểu thức chính quy",
|
||||
@@ -1210,7 +1243,7 @@
|
||||
"Text 4": "Văn bản 4",
|
||||
"Text 5": "Văn bản 5",
|
||||
"The input Email doesn't match the signup item regex!": "Email nhập vào không khớp biểu thức chính quy của mục đăng ký!",
|
||||
"The input doesn't match the signup item regex!": "The input doesn't match the signup item regex!",
|
||||
"The input doesn't match the signup item regex!": "Đầu vào không khớp biểu thức chính quy của mục đăng ký!",
|
||||
"The input is not invoice Tax ID!": "Đầu vào không phải là Mã số thuế của hóa đơn!",
|
||||
"The input is not invoice title!": "Đầu vào không phải là tiêu đề hóa đơn!",
|
||||
"The input is not valid Phone!": "Đầu vào không hợp lệ! Số điện thoại không hợp lệ!",
|
||||
@@ -1224,63 +1257,66 @@
|
||||
"Active": "Hoạt động",
|
||||
"Edit Subscription": "Chỉnh sửa đăng ký",
|
||||
"End time": "Thời gian kết thúc",
|
||||
"End time - Tooltip": "End time - Tooltip",
|
||||
"End time - Tooltip": "Thời gian kết thúc - Gợi ý",
|
||||
"Error": "Lỗi",
|
||||
"Expired": "Đã hết hạn",
|
||||
"New Subscription": "Đăng ký mới",
|
||||
"Start time": "Thời gian bắt đầu",
|
||||
"Start time - Tooltip": "Start time - Tooltip",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Suspended": "Đình chỉ",
|
||||
"Start time - Tooltip": "Thời gian bắt đầu - Gợi ý",
|
||||
"Subscription plan": "Kế hoạch đăng ký",
|
||||
"Subscription pricing": "Giá đăng ký",
|
||||
"Suspended": "Tạm dừng",
|
||||
"Upcoming": "Sắp tới",
|
||||
"View Subscription": "View Subscription"
|
||||
"View Subscription": "Xem đăng ký"
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"Admin Email": "Admin Email",
|
||||
"API Token / Password": "Mã thông báo API / Mật khẩu",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "Email quản trị viên",
|
||||
"Affiliation table": "Bảng liên kết",
|
||||
"Affiliation table - Tooltip": "Tên bảng cơ sở dữ liệu của đơn vị làm việc",
|
||||
"Avatar base URL": "Địa chỉ cơ sở Avatar URL",
|
||||
"Avatar base URL - Tooltip": "Tiền tố URL cho hình đại diện",
|
||||
"Bind DN": "Bind DN",
|
||||
"Affiliation table - Tooltip": "Bảng liên kết - Gợi ý",
|
||||
"Avatar base URL": "Địa chỉ cơ sở URL ảnh đại diện",
|
||||
"Avatar base URL - Tooltip": "Địa chỉ cơ sở URL ảnh đại diện - Gợi ý",
|
||||
"Bind DN": "Kết nối DN",
|
||||
"Casdoor column": "Cột Casdoor",
|
||||
"Column name": "Tên cột",
|
||||
"Column type": "Loại cột",
|
||||
"Connect successfully": "Kết nối thành công",
|
||||
"Corp ID": "Corp ID",
|
||||
"Corp secret": "Corp secret",
|
||||
"Corp ID": "Mã doanh nghiệp",
|
||||
"Corp secret": "Bí mật doanh nghiệp",
|
||||
"Database": "Cơ sở dữ liệu",
|
||||
"Database - Tooltip": "Tên cơ sở dữ liệu ban đầu",
|
||||
"Database - Tooltip": "Tên cơ sở dữ liệu",
|
||||
"Database type": "Loại cơ sở dữ liệu",
|
||||
"Database type - Tooltip": "Loại cơ sở dữ liệu, hỗ trợ tất cả các cơ sở dữ liệu được hỗ trợ bởi XORM, chẳng hạn như MySQL, PostgreSQL, SQL Server, Oracle, SQLite, vv.",
|
||||
"Edit Syncer": "Chỉnh sửa phù hợp với Syncer",
|
||||
"Database type - Tooltip": "Loại cơ sở dữ liệu như MySQL, PostgreSQL, v.v.",
|
||||
"Edit Syncer": "Chỉnh sửa đồng bộ",
|
||||
"Error text": "Văn bản lỗi",
|
||||
"Error text - Tooltip": "Văn bản lỗi",
|
||||
"Error text - Tooltip": "Thông tin chi tiết về lỗi xảy ra",
|
||||
"Failed to connect": "Kết nối thất bại",
|
||||
"Is hashed": "Đã được băm mã hóa",
|
||||
"Is hashed": "Đã được mã hóa",
|
||||
"Is key": "Là khóa",
|
||||
"Is read-only": "Chỉ đọc",
|
||||
"Is read-only - Tooltip": "Gợi ý chỉ đọc",
|
||||
"New Syncer": "New Syncer: Đồng bộ mới",
|
||||
"Paste your Google Workspace service account JSON key here": "Paste your Google Workspace service account JSON key here",
|
||||
"SCIM Server URL": "SCIM Server URL",
|
||||
"Is read-only - Tooltip": "Chỉ có thể đọc, không thể chỉnh sửa",
|
||||
"New Syncer": "Đồng bộ mới",
|
||||
"Paste your Google Workspace service account JSON key here": "Dán khóa JSON tài khoản dịch vụ Google Workspace của bạn tại đây",
|
||||
"SCIM Server URL": "URL máy chủ SCIM",
|
||||
"SSH host": "Máy chủ SSH",
|
||||
"SSH password": "Mật khẩu SSH",
|
||||
"SSH port": "Cổng SSH",
|
||||
"SSH user": "Người dùng SSH",
|
||||
"SSL mode": "Chế độ SSL",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Service account key": "Service account key",
|
||||
"Sync interval": "Khoảng thời gian đồng bộ hóa",
|
||||
"Sync interval - Tooltip": "Đơn vị giây",
|
||||
"Table": "Bàn",
|
||||
"Table - Tooltip": "Tên của bảng cơ sở dữ liệu",
|
||||
"SSL mode - Tooltip": "Chế độ kết nối SSL với cơ sở dữ liệu",
|
||||
"Service account key": "Khóa tài khoản dịch vụ",
|
||||
"Sync interval": "Khoảng thời gian đồng bộ",
|
||||
"Sync interval - Tooltip": "Khoảng thời gian giữa các lần đồng bộ (tính bằng giây)",
|
||||
"Table": "Bảng",
|
||||
"Table - Tooltip": "Tên bảng trong cơ sở dữ liệu",
|
||||
"Table columns": "Các cột bảng",
|
||||
"Table columns - Tooltip": "Các cột bảng tham gia đồng bộ dữ liệu. Các cột không tham gia đồng bộ không cần thêm vào",
|
||||
"Table columns - Tooltip": "Các cột tham gia đồng bộ dữ liệu",
|
||||
"Test Connection": "Kiểm tra kết nối",
|
||||
"Test DB Connection": "Test DB Connection",
|
||||
"Username (optional)": "Username (optional)"
|
||||
"Test DB Connection": "Kiểm tra kết nối DB",
|
||||
"Username (optional)": "Tên người dùng (tùy chọn)"
|
||||
},
|
||||
"system": {
|
||||
"API Latency": "Độ trễ API",
|
||||
@@ -1311,16 +1347,16 @@
|
||||
"Theme - Tooltip": "Trang trí giao diện của ứng dụng"
|
||||
},
|
||||
"ticket": {
|
||||
"Closed": "Closed",
|
||||
"Edit Ticket": "Edit Ticket",
|
||||
"In Progress": "In Progress",
|
||||
"Messages": "Messages",
|
||||
"New Ticket": "New Ticket",
|
||||
"Open": "Open",
|
||||
"Please enter a message": "Please enter a message",
|
||||
"Press Ctrl+Enter to send": "Press Ctrl+Enter to send",
|
||||
"Resolved": "Resolved",
|
||||
"Type your message here...": "Type your message here..."
|
||||
"Closed": "Đã đóng",
|
||||
"Edit Ticket": "Chỉnh sửa vé",
|
||||
"In Progress": "Đang tiến hành",
|
||||
"Messages": "Tin nhắn",
|
||||
"New Ticket": "Vé mới",
|
||||
"Open": "Mở",
|
||||
"Please enter a message": "Vui lòng nhập tin nhắn",
|
||||
"Press Ctrl+Enter to send": "Nhấn Ctrl+Enter để gửi",
|
||||
"Resolved": "Đã giải quyết",
|
||||
"Type your message here...": "Gõ tin nhắn tại đây..."
|
||||
},
|
||||
"token": {
|
||||
"Access token": "Mã thông báo truy cập",
|
||||
@@ -1342,7 +1378,7 @@
|
||||
"Amount - Tooltip": "Số lượng sản phẩm đã giao dịch",
|
||||
"Edit Transaction": "Chỉnh sửa giao dịch",
|
||||
"New Transaction": "Giao dịch mới",
|
||||
"Recharge": "Recharge"
|
||||
"Recharge": "Nạp tiền"
|
||||
},
|
||||
"user": {
|
||||
"3rd-party logins": "Đăng nhập bên thứ ba",
|
||||
@@ -1363,7 +1399,7 @@
|
||||
"Captcha Verify Success": "Xác thực Captcha Thành công",
|
||||
"City": "Thành phố",
|
||||
"Country code": "Mã quốc gia",
|
||||
"Country code - Tooltip": "Country code - Tooltip",
|
||||
"Country code - Tooltip": "Mã quốc gia - Gợi ý",
|
||||
"Country/Region": "Quốc gia / Vùng miền",
|
||||
"Country/Region - Tooltip": "Quốc gia hoặc khu vực",
|
||||
"Edit User": "Chỉnh sửa người dùng",
|
||||
@@ -1386,10 +1422,10 @@
|
||||
"ID card type": "Loại thẻ ID",
|
||||
"ID card type - Tooltip": "Gợi ý loại thẻ ID",
|
||||
"ID card with person": "Thẻ ID với người",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"ID verification": "Xác minh danh tính",
|
||||
"ID verification - Tooltip": "Xác minh danh tính - Gợi ý",
|
||||
"Identity verification successful": "Xác minh danh tính thành công",
|
||||
"Identity verified": "Danh tính đã được xác minh",
|
||||
"Input your email": "Nhập địa chỉ email của bạn",
|
||||
"Input your phone number": "Nhập số điện thoại của bạn",
|
||||
"Is admin": "Là quản trị viên",
|
||||
@@ -1399,7 +1435,7 @@
|
||||
"Is forbidden": "Bị cấm",
|
||||
"Is forbidden - Tooltip": "Người dùng bị cấm không thể đăng nhập nữa",
|
||||
"Is online": "Đang trực tuyến",
|
||||
"Is verified": "Is verified",
|
||||
"Is verified": "Đã xác minh",
|
||||
"Karma": "Karma",
|
||||
"Karma - Tooltip": "Gợi ý Karma",
|
||||
"Keys": "Chìa khóa",
|
||||
@@ -1424,19 +1460,19 @@
|
||||
"Other": "Khác",
|
||||
"Password set successfully": "Mật khẩu đã được thiết lập thành công",
|
||||
"Phone cannot be empty": "Điện thoại không thể để trống",
|
||||
"Please enter your real name": "Please enter your real name",
|
||||
"Please fill in ID card information first": "Please fill in ID card information first",
|
||||
"Please fill in your real name first": "Please fill in your real name first",
|
||||
"Please enter your real name": "Vui lòng nhập tên thật của bạn",
|
||||
"Please fill in ID card information first": "Vui lòng điền thông tin thẻ ID trước",
|
||||
"Please fill in your real name first": "Vui lòng điền tên thật của bạn trước",
|
||||
"Please select avatar from resources": "Vui lòng chọn avatar từ tài nguyên",
|
||||
"Properties": "Đặc tính",
|
||||
"Properties - Tooltip": "Các thuộc tính của người dùng",
|
||||
"Ranking": "Xếp hạng",
|
||||
"Ranking - Tooltip": "Gợi ý xếp hạng",
|
||||
"Re-enter New": "Nhập lại New",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Register source": "Register source",
|
||||
"Real name - Tooltip": "Tên thật - Gợi ý",
|
||||
"Register source": "Nguồn đăng ký",
|
||||
"Register source - Tooltip": "Nguồn mà người dùng đăng ký",
|
||||
"Register type": "Register type",
|
||||
"Register type": "Loại đăng ký",
|
||||
"Register type - Tooltip": "Phương pháp được sử dụng để đăng ký người dùng",
|
||||
"Reset Email...": "Thiết lập lại Email...",
|
||||
"Reset Phone...": "Đặt lại điện thoại...",
|
||||
@@ -1462,8 +1498,8 @@
|
||||
"User Profile": "Hồ sơ người dùng",
|
||||
"Values": "Giá trị",
|
||||
"Verification code sent": "Mã xác minh đã được gửi",
|
||||
"Verified": "Verified",
|
||||
"Verify Identity": "Verify Identity",
|
||||
"Verified": "Đã xác minh",
|
||||
"Verify Identity": "Xác minh danh tính",
|
||||
"WebAuthn credentials": "Chứng chỉ WebAuthn",
|
||||
"Work": "Làm việc",
|
||||
"You have changed the username, please save your change first before modifying the password": "Bạn đã thay đổi tên người dùng, vui lòng lưu thay đổi trước khi sửa mật khẩu",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"account": {
|
||||
"Exit impersonation": "Exit impersonation",
|
||||
"Exit impersonation": "退出模拟身份",
|
||||
"Logout": "登出",
|
||||
"My Account": "我的账户",
|
||||
"Sign Up": "注册"
|
||||
@@ -21,23 +21,23 @@
|
||||
"Add Face ID": "添加人脸ID",
|
||||
"Add Face ID with Image": "添加图片人脸ID",
|
||||
"Always": "始终开启",
|
||||
"Array": "Array",
|
||||
"Authentication": "Authentication",
|
||||
"Array": "数组",
|
||||
"Authentication": "身份验证",
|
||||
"Auto signin": "启用自动登录",
|
||||
"Auto signin - Tooltip": "当Casdoor存在已登录会话时,自动采用该会话进行应用端的登录",
|
||||
"Background URL": "背景图URL",
|
||||
"Background URL - Tooltip": "登录页背景图的链接",
|
||||
"Background URL Mobile": "背景图URL(移动端)",
|
||||
"Background URL Mobile - Tooltip": "登录页背景图的链接(移动端)",
|
||||
"Basic": "Basic",
|
||||
"Basic": "基础",
|
||||
"Big icon": "大图标",
|
||||
"Binding providers": "绑定提供商",
|
||||
"CSS style": "CSS样式",
|
||||
"Center": "居中",
|
||||
"Code resend timeout": "代码重发超时",
|
||||
"Code resend timeout - Tooltip": "用户在请求另一个验证码之前必须等待的时间段(以秒为单位)。设置为0可使用全局默认值(60秒)",
|
||||
"Cookie expire": "Cookie expire",
|
||||
"Cookie expire - Tooltip": "Cookie expire - Tooltip",
|
||||
"Cookie expire": "Cookie过期时间",
|
||||
"Cookie expire - Tooltip": "Cookie的过期时间设置",
|
||||
"Copy SAML metadata URL": "复制SAML元数据URL",
|
||||
"Copy prompt page URL": "复制提醒页面URL",
|
||||
"Copy signin page URL": "复制登录页面URL",
|
||||
@@ -48,8 +48,8 @@
|
||||
"Custom CSS Mobile": "表单CSS(移动端)",
|
||||
"Custom CSS Mobile - Edit": "编辑表单CSS(移动端)",
|
||||
"Custom CSS Mobile - Tooltip": "注册、登录、忘记密码等表单的CSS样式(如增加边框和阴影)(移动端)",
|
||||
"Disable SAML attributes": "Disable SAML attributes",
|
||||
"Disable SAML attributes - Tooltip": "Disable SAML attributes - Tooltip",
|
||||
"Disable SAML attributes": "禁用SAML属性",
|
||||
"Disable SAML attributes - Tooltip": "是否禁用SAML响应中的属性",
|
||||
"Disable signin": "禁止登录",
|
||||
"Disable signin - Tooltip": "禁止用户进行登录操作",
|
||||
"Dynamic": "动态开启",
|
||||
@@ -60,8 +60,8 @@
|
||||
"Enable SAML C14N10 - Tooltip": "在SAML协议里使用C14N10,而不是C14N11",
|
||||
"Enable SAML POST binding": "启用SAML POST Binding",
|
||||
"Enable SAML POST binding - Tooltip": "HTTP POST绑定使用HTML表单中的输入字段发送SAML消息,当SP使用它时启用",
|
||||
"Enable SAML assertion signature": "Enable SAML assertion signature",
|
||||
"Enable SAML assertion signature - Tooltip": "Enable SAML assertion signature - Tooltip",
|
||||
"Enable SAML assertion signature": "启用SAML断言签名",
|
||||
"Enable SAML assertion signature - Tooltip": "是否对SAML断言进行数字签名",
|
||||
"Enable SAML compression": "压缩SAML响应",
|
||||
"Enable SAML compression - Tooltip": "Casdoor作为SAML IdP时,是否压缩SAML响应信息",
|
||||
"Enable exclusive signin": "互斥登陆",
|
||||
@@ -70,6 +70,7 @@
|
||||
"Enable signin session - Tooltip": "从应用登录Casdoor后,Casdoor是否保持会话",
|
||||
"Enable signup": "启用注册",
|
||||
"Enable signup - Tooltip": "是否允许用户注册",
|
||||
"Existing Field": "Existing Field",
|
||||
"Failed signin frozen time": "登入重试等待时间",
|
||||
"Failed signin frozen time - Tooltip": "超过登入错误重试次数后的等待时间,只有超过等待时间后用户才能重新登入,默认值为15分钟,设置的值需为正整数",
|
||||
"Failed signin limit": "登入错误次数限制",
|
||||
@@ -89,7 +90,7 @@
|
||||
"Header HTML": "Header HTML",
|
||||
"Header HTML - Edit": "Header HTML - 编辑",
|
||||
"Header HTML - Tooltip": "自定义应用页面的head标签",
|
||||
"Horizontal": "Horizontal",
|
||||
"Horizontal": "水平",
|
||||
"Incremental": "递增",
|
||||
"Inline": "内嵌",
|
||||
"Input": "输入",
|
||||
@@ -101,23 +102,30 @@
|
||||
"Logged out successfully": "登出成功",
|
||||
"MFA remember time": "MFA记住时间",
|
||||
"MFA remember time - Tooltip": "配置MFA登录成功后帐户被记住为受信任的持续时间",
|
||||
"Menu mode": "Menu mode",
|
||||
"Menu mode - Tooltip": "Menu mode - Tooltip",
|
||||
"Menu mode": "菜单模式",
|
||||
"Menu mode - Tooltip": "菜单的展示模式",
|
||||
"Multiple Choices": "多选",
|
||||
"New Application": "添加应用",
|
||||
"No verification": "不校验",
|
||||
"Normal": "标准",
|
||||
"Only signup": "仅注册",
|
||||
"Order": "Order",
|
||||
"Order": "排序",
|
||||
"Order - Tooltip": "数值越小,在应用列表页面中排序越靠前",
|
||||
"Org choice mode": "组织选择模式",
|
||||
"Org choice mode - Tooltip": "采用什么方式选择要登录的组织",
|
||||
"Other domains": "其他域名",
|
||||
"Other domains - Tooltip": "也应路由到此应用的其他域名",
|
||||
"Please enable \"Signin session\" first before enabling \"Auto signin\"": "开启 \"保持登录会话\" 后才能开启 \"自动登录\"",
|
||||
"Please input additional domains": "请输入其他域名",
|
||||
"Please input your application!": "请输入你的应用",
|
||||
"Please input your organization!": "请输入你的组织",
|
||||
"Please select a HTML file": "请选择一个HTML文件",
|
||||
"Pop up": "弹框",
|
||||
"Providers": "Providers",
|
||||
"Providers": "提供商",
|
||||
"Proxy SSL mode": "代理SSL模式",
|
||||
"Proxy SSL mode - Tooltip": "反向代理的SSL/TLS模式",
|
||||
"Proxy domain": "代理域名",
|
||||
"Proxy domain - Tooltip": "此应用的公开访问域名(例如:blog.example.com)",
|
||||
"Random": "随机",
|
||||
"Real name": "真实姓名",
|
||||
"Redirect URL": "重定向 URL",
|
||||
@@ -127,6 +135,7 @@
|
||||
"Refresh token expire": "Refresh Token过期",
|
||||
"Refresh token expire - Tooltip": "Refresh Token过期时间",
|
||||
"Reset to Empty": "重置为空",
|
||||
"Reverse Proxy": "反向代理",
|
||||
"Right": "居右",
|
||||
"Rule": "规则",
|
||||
"SAML hash algorithm": "SAML哈希算法",
|
||||
@@ -134,7 +143,9 @@
|
||||
"SAML metadata": "SAML元数据",
|
||||
"SAML metadata - Tooltip": "SAML协议的元数据(Metadata)信息",
|
||||
"SAML reply URL": "SAML回复 URL",
|
||||
"Security": "Security",
|
||||
"SSL cert": "SSL证书",
|
||||
"SSL cert - Tooltip": "用于TLS终止的证书",
|
||||
"Security": "安全设置",
|
||||
"Select": "选择",
|
||||
"Side panel HTML": "侧面板HTML",
|
||||
"Side panel HTML - Edit": "侧面板HTML - 编辑",
|
||||
@@ -151,7 +162,8 @@
|
||||
"Signup items - Tooltip": "注册用户注册时需要填写的项目",
|
||||
"Single Choice": "单选",
|
||||
"Small icon": "小图标",
|
||||
"String": "String",
|
||||
"Static Value": "Static Value",
|
||||
"String": "字符串",
|
||||
"Tags - Tooltip": "用户的标签在应用的标签集合中时,用户才可以登录该应用",
|
||||
"The application does not allow to sign up new account": "该应用不允许注册新账户",
|
||||
"Token expire": "Access Token过期",
|
||||
@@ -162,10 +174,12 @@
|
||||
"Token format - Tooltip": "Access Token格式",
|
||||
"Token signing method": "Token签名算法",
|
||||
"Token signing method - Tooltip": "JWT token的签名算法,需要与证书算法相匹配",
|
||||
"UI Customization": "UI Customization",
|
||||
"UI Customization": "界面定制",
|
||||
"Upstream host": "上游主机",
|
||||
"Upstream host - Tooltip": "转发请求的上游后端地址(例如:localhost:8080 或 192.168.1.100)",
|
||||
"Use Email as NameID": "使用邮箱作为NameID",
|
||||
"Use Email as NameID - Tooltip": "使用邮箱作为NameID",
|
||||
"Vertical": "Vertical",
|
||||
"Vertical": "垂直",
|
||||
"You are unexpected to see this prompt page": "错误:该提醒页面不应出现"
|
||||
},
|
||||
"cert": {
|
||||
@@ -282,11 +296,13 @@
|
||||
"Business & Payments": "商业 & 付款",
|
||||
"Cancel": "取消",
|
||||
"Captcha": "人机验证码",
|
||||
"Cart": "Cart",
|
||||
"Cart": "购物车",
|
||||
"Category": "Category",
|
||||
"Category - Tooltip": "Category - Tooltip",
|
||||
"Cert": "证书",
|
||||
"Cert - Tooltip": "该应用所对应的客户端SDK需要验证的公钥证书",
|
||||
"Certs": "证书",
|
||||
"Clear": "Clear",
|
||||
"Clear": "清空",
|
||||
"Click to Upload": "点击上传",
|
||||
"Client IP": "客户端IP",
|
||||
"Close": "关闭",
|
||||
@@ -312,7 +328,7 @@
|
||||
"Display name": "显示名称",
|
||||
"Display name - Tooltip": "在界面里公开显示的、易读的名称",
|
||||
"Down": "下移",
|
||||
"Download template": "Download template",
|
||||
"Download template": "下载模板",
|
||||
"Edit": "编辑",
|
||||
"Email": "电子邮箱",
|
||||
"Email - Tooltip": "合法的电子邮件地址",
|
||||
@@ -327,17 +343,17 @@
|
||||
"Enabled successfully": "启用成功",
|
||||
"Enforcers": "Casbin执行器",
|
||||
"Failed to add": "添加失败",
|
||||
"Failed to cancel": "Failed to cancel",
|
||||
"Failed to cancel": "取消失败",
|
||||
"Failed to connect to server": "连接服务器失败",
|
||||
"Failed to copy": "复制失败",
|
||||
"Failed to delete": "删除失败",
|
||||
"Failed to enable": "启用失败",
|
||||
"Failed to get": "获取失败",
|
||||
"Failed to load": "Failed to load",
|
||||
"Failed to load": "加载失败",
|
||||
"Failed to log out": "登出失败",
|
||||
"Failed to remove": "移除失败",
|
||||
"Failed to save": "保存失败",
|
||||
"Failed to send": "Failed to send",
|
||||
"Failed to send": "发送失败",
|
||||
"Failed to sync": "同步失败",
|
||||
"Failed to unlink": "取消关联失败",
|
||||
"Failed to update": "更新失败",
|
||||
@@ -354,12 +370,12 @@
|
||||
"Forget URL - Tooltip": "自定义忘记密码页面的URL,不设置时采用Casdoor默认的忘记密码页面,设置后Casdoor各类页面的忘记密码链接会跳转到该URL",
|
||||
"Forms": "表单",
|
||||
"Found some texts still not translated? Please help us translate at": "发现有些文字尚未翻译?请移步这里帮我们翻译:",
|
||||
"Generate": "Generate",
|
||||
"Generate": "生成",
|
||||
"Go to enable": "前往启用",
|
||||
"Go to writable demo site?": "跳转至可写演示站点?",
|
||||
"Groups": "群组",
|
||||
"Groups - Tooltip": "用户所属的组",
|
||||
"Hide password": "Hide password",
|
||||
"Hide password": "隐藏密码",
|
||||
"Home": "首页",
|
||||
"Home - Tooltip": "应用的首页",
|
||||
"ID": "ID",
|
||||
@@ -367,7 +383,7 @@
|
||||
"IP whitelist": "IP白名单",
|
||||
"IP whitelist - Tooltip": "允许的IP地址列表",
|
||||
"Identity": "身份认证",
|
||||
"Impersonation": "Impersonation",
|
||||
"Impersonation": "身份模拟",
|
||||
"Invitations": "邀请码",
|
||||
"Is enabled": "已启用",
|
||||
"Is enabled - Tooltip": "是否启用",
|
||||
@@ -401,7 +417,7 @@
|
||||
"Name - Tooltip": "唯一的、字符串式的ID",
|
||||
"Name format": "名称格式",
|
||||
"No products available": "暂无可用商品",
|
||||
"No sheets found in file": "No sheets found in file",
|
||||
"No sheets found in file": "文件中未找到工作表",
|
||||
"No verification method": "没有验证方法",
|
||||
"Non-LDAP": "禁用LDAP",
|
||||
"None": "无",
|
||||
@@ -410,8 +426,8 @@
|
||||
"OK": "确定",
|
||||
"ON": "开",
|
||||
"Only 1 MFA method can be required": "只能要求1个MFA方法",
|
||||
"Or": "Or",
|
||||
"Orders": "Orders",
|
||||
"Or": "或",
|
||||
"Orders": "订单",
|
||||
"Organization": "组织",
|
||||
"Organization - Tooltip": "类似于租户、用户池等概念,每个用户和应用都从属于一个组织",
|
||||
"Organization is null": "组织为空",
|
||||
@@ -437,13 +453,13 @@
|
||||
"Phone - Tooltip": "手机号",
|
||||
"Phone only": "仅支持手机号",
|
||||
"Phone or Email": "手机或电子邮件",
|
||||
"Place Order": "Place Order",
|
||||
"Place Order": "下单",
|
||||
"Plain": "无",
|
||||
"Plan": "计划",
|
||||
"Plan - Tooltip": "订阅里的计划",
|
||||
"Plans": "计划",
|
||||
"Plans - Tooltip": "订阅里的计划",
|
||||
"Please complete the captcha correctly": "Please complete the captcha correctly",
|
||||
"Please complete the captcha correctly": "请正确完成验证码",
|
||||
"Please input your search": "请输入搜索内容",
|
||||
"Please select at least 1 user first": "请至少选择1个用户",
|
||||
"Preview": "预览",
|
||||
@@ -456,7 +472,7 @@
|
||||
"Provider": "提供商",
|
||||
"Provider - Tooltip": "需要配置的支付提供商,包括PayPal、支付宝、微信支付等",
|
||||
"Providers - Tooltip": "需要配置的提供商,包括第三方登录、对象存储、验证码等",
|
||||
"QR Code": "QR Code",
|
||||
"QR Code": "二维码",
|
||||
"QR code is too large": "二维码过大",
|
||||
"Records": "日志",
|
||||
"Request": "请求",
|
||||
@@ -476,6 +492,8 @@
|
||||
"SSH type - Tooltip": "SSH连接的认证类型",
|
||||
"Save": "保存",
|
||||
"Save & Exit": "保存 & 退出",
|
||||
"Scopes": "Scopes",
|
||||
"Scopes - Tooltip": "Scopes - Tooltip",
|
||||
"Search": "搜索",
|
||||
"Send": "发送",
|
||||
"Session ID": "会话ID",
|
||||
@@ -493,13 +511,13 @@
|
||||
"Sorry, you do not have permission to access this page or logged in status invalid.": "抱歉,您无权访问该页面或登录状态失效",
|
||||
"State": "状态",
|
||||
"State - Tooltip": "当前状态或状态信息",
|
||||
"Status": "Status",
|
||||
"Status": "状态",
|
||||
"Subscriptions": "订阅",
|
||||
"Successfully added": "添加成功",
|
||||
"Successfully canceled": "Successfully canceled",
|
||||
"Successfully canceled": "取消成功",
|
||||
"Successfully copied": "复制成功",
|
||||
"Successfully deleted": "删除成功",
|
||||
"Successfully executed": "Successfully executed",
|
||||
"Successfully executed": "执行成功",
|
||||
"Successfully removed": "移除成功",
|
||||
"Successfully saved": "保存成功",
|
||||
"Successfully sent": "发送成功",
|
||||
@@ -519,7 +537,7 @@
|
||||
"The users and roles cannot be empty at the same time": "用户和角色不能同时为空",
|
||||
"There was a problem signing you in..": "登录时遇到问题..",
|
||||
"This is a read-only demo site!": "这是一个只读演示站点!",
|
||||
"Tickets": "Tickets",
|
||||
"Tickets": "工单",
|
||||
"Timestamp": "时间",
|
||||
"Title": "标题",
|
||||
"Title - Tooltip": "浏览器页面标题",
|
||||
@@ -530,6 +548,7 @@
|
||||
"Transactions": "交易",
|
||||
"True": "真",
|
||||
"Type": "类型",
|
||||
"Type - Tooltip": "Type - Tooltip",
|
||||
"URL": "链接",
|
||||
"URL - Tooltip": "URL链接",
|
||||
"Unknown application name": "未知的应用程序名称",
|
||||
@@ -548,7 +567,7 @@
|
||||
"Users - Tooltip": "系统中的用户列表",
|
||||
"Users under all organizations": "所有组织里的用户",
|
||||
"Verifications": "验证",
|
||||
"View": "View",
|
||||
"View": "查看",
|
||||
"Webhooks": "Webhooks",
|
||||
"You can only select one physical group": "只能选择一个实体组",
|
||||
"You must select a picture first": "您必须先选择一张图片",
|
||||
@@ -626,7 +645,7 @@
|
||||
"login": {
|
||||
"Auto sign in": "下次自动登录",
|
||||
"Back button": "返回按钮",
|
||||
"Click the button below to sign in with Telegram": "Click the button below to sign in with Telegram",
|
||||
"Click the button below to sign in with Telegram": "点击下方按钮使用Telegram登录",
|
||||
"Continue with": "使用以下账号继续",
|
||||
"Email or phone": "Email或手机号",
|
||||
"Face ID": "Face ID",
|
||||
@@ -665,7 +684,7 @@
|
||||
"Select organization": "选择组织",
|
||||
"Sign In": "登录",
|
||||
"Sign in with Face ID": "人脸登录",
|
||||
"Sign in with Telegram": "Sign in with Telegram",
|
||||
"Sign in with Telegram": "使用Telegram登录",
|
||||
"Sign in with WebAuthn": "WebAuthn登录",
|
||||
"Sign in with {type}": "{type}登录",
|
||||
"Signin button": "登录按钮",
|
||||
@@ -698,7 +717,7 @@
|
||||
"Please confirm the information below": "请确认以下信息",
|
||||
"Please save this recovery code. Once your device cannot provide an authentication code, you can reset mfa authentication by this recovery code": "请保存此恢复代码。一旦您的设备无法提供身份验证码,您可以通过此恢复码重置多因素认证",
|
||||
"Protect your account with Multi-factor authentication": "通过多因素认证保护您的帐户",
|
||||
"Push notification receiver": "Push notification receiver",
|
||||
"Push notification receiver": "推送通知接收者",
|
||||
"Recovery code": "恢复码",
|
||||
"Remember this account for {hour} hours": "记住这个账户 {hour} 小时",
|
||||
"Scan the QR code with your Authenticator App": "用你的身份验证应用扫描二维码",
|
||||
@@ -708,7 +727,7 @@
|
||||
"To ensure the security of your account, it is required to enable multi-factor authentication": "为了确保您的帐户安全,您需要启用多因素身份验证",
|
||||
"Use Authenticator App": "使用身份验证应用",
|
||||
"Use Email": "使用电子邮件",
|
||||
"Use Push Notification": "Use Push Notification",
|
||||
"Use Push Notification": "使用推送通知",
|
||||
"Use Radius": "使用Radius",
|
||||
"Use SMS": "使用短信",
|
||||
"Use SMS verification code": "使用手机或电子邮件发送验证码认证",
|
||||
@@ -718,7 +737,7 @@
|
||||
"You have enabled Multi-Factor Authentication, Please click 'Send Code' to continue": "您已经启用多因素认证, 请点击 '发送验证码' 继续",
|
||||
"You have enabled Multi-Factor Authentication, please enter the RADIUS password": "您已经启用多因素认证,请输入RADIUS密码",
|
||||
"You have enabled Multi-Factor Authentication, please enter the TOTP code": "您已经启用多因素认证,请输入TOTP认证码",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "You have enabled Multi-Factor Authentication, please enter the verification code from push notification",
|
||||
"You have enabled Multi-Factor Authentication, please enter the verification code from push notification": "您已经启用多因素认证,请输入来自推送通知的验证码",
|
||||
"Your email is": "你的电子邮件",
|
||||
"Your phone is": "你的手机号",
|
||||
"preferred": "首选"
|
||||
@@ -732,29 +751,30 @@
|
||||
"New Model": "添加模型"
|
||||
},
|
||||
"order": {
|
||||
"Cancel time": "Cancel time",
|
||||
"Edit Order": "Edit Order",
|
||||
"New Order": "New Order",
|
||||
"Order not found": "Order not found",
|
||||
"Pay": "Pay",
|
||||
"Payment failed time": "Payment failed time",
|
||||
"Payment time": "Payment time",
|
||||
"Price": "Price",
|
||||
"Return to Order List": "Return to Order List",
|
||||
"Timeout time": "Timeout time",
|
||||
"View Order": "View Order"
|
||||
"Cancel time": "取消时间",
|
||||
"Edit Order": "编辑订单",
|
||||
"New Order": "新订单",
|
||||
"Order not found": "未找到订单",
|
||||
"Pay": "支付",
|
||||
"Payment failed time": "支付失败时间",
|
||||
"Payment time": "支付时间",
|
||||
"Price": "价格",
|
||||
"Return to Order List": "返回订单列表",
|
||||
"Timeout time": "超时时间",
|
||||
"View Order": "查看订单"
|
||||
},
|
||||
"organization": {
|
||||
"Account items": "个人页设置项",
|
||||
"Account items - Tooltip": "用户的个人设置页面中可配置的选项",
|
||||
"Account menu": "Account menu",
|
||||
"Account menu - Tooltip": "Account menu - Tooltip",
|
||||
"Admin navbar items": "Admin navbar items",
|
||||
"Admin navbar items - Tooltip": "Admin navbar items - Tooltip",
|
||||
"Balance credit": "Balance credit",
|
||||
"Balance credit - Tooltip": "Balance credit - Tooltip",
|
||||
"Balance currency": "Balance currency",
|
||||
"Balance currency - Tooltip": "Balance currency - Tooltip",
|
||||
"Account menu": "账户菜单",
|
||||
"Account menu - Tooltip": "账户相关的菜单项",
|
||||
"Admin navbar items": "管理员导航栏项",
|
||||
"Admin navbar items - Tooltip": "管理员导航栏中的项目",
|
||||
"All": "All",
|
||||
"Balance credit": "余额积分",
|
||||
"Balance credit - Tooltip": "用户的余额积分信息",
|
||||
"Balance currency": "余额币种",
|
||||
"Balance currency - Tooltip": "余额使用的币种类型",
|
||||
"Edit Organization": "编辑组织",
|
||||
"Follow global theme": "使用全局默认主题",
|
||||
"Has privilege consent": "特权同意",
|
||||
@@ -767,8 +787,8 @@
|
||||
"Modify rule": "修改规则",
|
||||
"New Organization": "添加组织",
|
||||
"Optional": "可选",
|
||||
"Org balance": "Org balance",
|
||||
"Org balance - Tooltip": "Org balance - Tooltip",
|
||||
"Org balance": "组织余额",
|
||||
"Org balance - Tooltip": "组织的余额信息",
|
||||
"Password expire days": "密码过期天数",
|
||||
"Password expire days - Tooltip": "密码过期前的天数",
|
||||
"Prompt": "提示",
|
||||
@@ -778,10 +798,10 @@
|
||||
"Tags": "标签集合",
|
||||
"Use Email as username": "邮箱作为用户名",
|
||||
"Use Email as username - Tooltip": "如果注册时用户名不可见,则使用邮箱作为用户名",
|
||||
"User balance": "User balance",
|
||||
"User balance - Tooltip": "User balance - Tooltip",
|
||||
"User navbar items": "User navbar items",
|
||||
"User navbar items - Tooltip": "User navbar items - Tooltip",
|
||||
"User balance": "用户余额",
|
||||
"User balance - Tooltip": "用户的余额信息",
|
||||
"User navbar items": "用户导航栏项",
|
||||
"User navbar items - Tooltip": "用户导航栏中的项目",
|
||||
"User types": "用户类型",
|
||||
"User types - Tooltip": "系统中可用的用户类型",
|
||||
"View rule": "查看规则",
|
||||
@@ -826,15 +846,15 @@
|
||||
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "请仔细检查下列发票信息,发票一经开具,无法退换。",
|
||||
"Please pay the order first!": "请先完成支付后再进行操作!",
|
||||
"Processing...": "正在处理...",
|
||||
"Products - Tooltip": "Products - Tooltip",
|
||||
"Products - Tooltip": "商品相关信息",
|
||||
"Recharged successfully": "充值成功",
|
||||
"Result": "结果",
|
||||
"The payment has been canceled": "付款已取消",
|
||||
"The payment has failed": "支付失败",
|
||||
"The payment has timed out": "The payment has timed out",
|
||||
"The payment has timed out": "支付已超时",
|
||||
"The payment is still under processing": "支付正在处理",
|
||||
"View Payment": "View Payment",
|
||||
"You can view your order details or return to the order list": "You can view your order details or return to the order list",
|
||||
"View Payment": "查看支付",
|
||||
"You can view your order details or return to the order list": "您可以查看订单详情或返回订单列表",
|
||||
"You have successfully completed the payment": "支付成功",
|
||||
"You have successfully recharged": "您已成功充值",
|
||||
"Your current balance is": "您现在的余额为",
|
||||
@@ -867,13 +887,15 @@
|
||||
},
|
||||
"plan": {
|
||||
"Edit Plan": "编辑计划",
|
||||
"Is exclusive": "Is exclusive",
|
||||
"Is exclusive - Tooltip": "Is exclusive - Tooltip",
|
||||
"New Plan": "添加计划",
|
||||
"Period": "期限",
|
||||
"Period - Tooltip": "计划对应的期限",
|
||||
"Plan name": "Plan name",
|
||||
"Plan name": "计划名称",
|
||||
"Price - Tooltip": "订阅该计划需要支付的价格",
|
||||
"Related product": "对应的商品",
|
||||
"View Plan": "View Plan",
|
||||
"View Plan": "查看计划",
|
||||
"per month": "每月",
|
||||
"per year": "每年"
|
||||
},
|
||||
@@ -883,22 +905,23 @@
|
||||
"Free": "免费",
|
||||
"Getting started": "开始使用",
|
||||
"New Pricing": "添加定价",
|
||||
"Pricing name": "Pricing name",
|
||||
"Pricing name": "定价名称",
|
||||
"Trial duration": "试用期时长",
|
||||
"Trial duration - Tooltip": "试用期时长",
|
||||
"View Pricing": "View Pricing",
|
||||
"View Pricing": "查看定价",
|
||||
"days trial available!": "天试用期可用!",
|
||||
"paid-user do not have active subscription or pending subscription, please select a plan to buy": "付费用户找不到对应的订阅,请选择购买一个计划"
|
||||
},
|
||||
"product": {
|
||||
"Add to cart": "Add to cart",
|
||||
"Add to cart": "添加到购物车",
|
||||
"AirWallex": "空中云汇",
|
||||
"Alipay": "支付宝",
|
||||
"Amount": "金额",
|
||||
"Buy": "购买",
|
||||
"Buy Product": "购买商品",
|
||||
"Cart contains invalid products, please delete them before placing an order": "Cart contains invalid products, please delete them before placing an order",
|
||||
"Custom amount available": "可自定义金额",
|
||||
"Custom price should be greater than zero": "Custom price should be greater than zero",
|
||||
"Custom price should be greater than zero": "自定义价格必须大于零",
|
||||
"Detail - Tooltip": "商品详情",
|
||||
"Disable custom amount": "禁用自定义金额",
|
||||
"Disable custom amount - Tooltip": "是否禁用自定义充值金额",
|
||||
@@ -908,10 +931,13 @@
|
||||
"Failed to create order": "创建订单失败",
|
||||
"Image": "图片",
|
||||
"Image - Tooltip": "商品图片",
|
||||
"Information": "Information",
|
||||
"Information": "信息",
|
||||
"Invalid product": "Invalid product",
|
||||
"Is recharge": "充值",
|
||||
"Is recharge - Tooltip": "当前商品是否为充值商品",
|
||||
"Name": "Name",
|
||||
"New Product": "添加商品",
|
||||
"No recharge options available": "No recharge options available",
|
||||
"Order created successfully": "订单创建成功",
|
||||
"PayPal": "PayPal",
|
||||
"Payment cancelled": "支付取消",
|
||||
@@ -920,14 +946,17 @@
|
||||
"Payment providers - Tooltip": "支持的支付提供商",
|
||||
"Placing order...": "正在下单...",
|
||||
"Please add at least one recharge option when custom amount is disabled": "当禁用自定义金额时,请至少添加一个充值选项",
|
||||
"Please select a currency": "Please select a currency",
|
||||
"Please select at least one payment provider": "Please select at least one payment provider",
|
||||
"Processing payment...": "Processing payment...",
|
||||
"Product list cannot be empty": "Product list cannot be empty",
|
||||
"Please select a currency": "请选择一种货币",
|
||||
"Please select at least one payment provider": "请至少选择一个支付提供商",
|
||||
"Price": "Price",
|
||||
"Processing payment...": "正在处理支付...",
|
||||
"Product list cannot be empty": "商品列表不能为空",
|
||||
"Product not found or invalid": "Product not found or invalid",
|
||||
"Quantity": "库存",
|
||||
"Quantity - Tooltip": "库存的数量",
|
||||
"Recharge options": "充值选项",
|
||||
"Recharge options - Tooltip": "预设充值金额",
|
||||
"Recharge products need to go to the product detail page to set custom amount": "Recharge products need to go to the product detail page to set custom amount",
|
||||
"Return URL": "返回URL",
|
||||
"Return URL - Tooltip": "购买成功后返回的URL",
|
||||
"SKU": "货号",
|
||||
@@ -939,12 +968,12 @@
|
||||
"Success URL - Tooltip": "支付后跳转的URL",
|
||||
"Tag - Tooltip": "商品类别",
|
||||
"Test buy page..": "测试购买页面..",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "The currency of the product you are adding is different from the currency of the items in the cart",
|
||||
"The currency of the product you are adding is different from the currency of the items in the cart": "您正在添加的商品货币与购物车中物品的货币不同",
|
||||
"There is no payment channel for this product.": "该商品没有付款方式。",
|
||||
"This product is currently not in sale.": "该商品目前未在售。",
|
||||
"This product is currently not purchasable (No options available)": "该产品当前无法购买(没有可用选项)",
|
||||
"Total Price": "Total Price",
|
||||
"View Product": "View Product",
|
||||
"Total Price": "总价格",
|
||||
"View Product": "查看商品",
|
||||
"WeChat Pay": "微信支付"
|
||||
},
|
||||
"provider": {
|
||||
@@ -964,6 +993,7 @@
|
||||
"Auth Key - Tooltip": "服务的认证密钥",
|
||||
"Auth URL": "认证URL",
|
||||
"Auth URL - Tooltip": "用于认证的URL",
|
||||
"Auto": "Auto",
|
||||
"Base URL": "基本URL",
|
||||
"Base URL - Tooltip": "服务的基本URL",
|
||||
"Bucket": "存储桶",
|
||||
@@ -988,10 +1018,9 @@
|
||||
"Client secret 2 - Tooltip": "备用客户端验证密钥",
|
||||
"Content": "内容",
|
||||
"Content - Tooltip": "消息、通知或文档中包含的具体信息或数据内容",
|
||||
"DB test": "DB test",
|
||||
"DB test - Tooltip": "DB test - Tooltip",
|
||||
"Disable SSL": "禁用SSL",
|
||||
"Disable SSL - Tooltip": "与STMP服务器通信时是否禁用SSL协议",
|
||||
"DB test": "数据库测试",
|
||||
"DB test - Tooltip": "测试数据库连接是否正常",
|
||||
"Disable": "Disable",
|
||||
"Domain": "域名",
|
||||
"Domain - Tooltip": "对象存储的自定义域名",
|
||||
"Edit Provider": "编辑提供商",
|
||||
@@ -1001,8 +1030,9 @@
|
||||
"Email regex - Tooltip": "只有符合此正则表达式的Email才能进行注册或登录",
|
||||
"Email title": "邮件标题",
|
||||
"Email title - Tooltip": "邮件标题",
|
||||
"Enable PKCE": "Enable PKCE",
|
||||
"Enable PKCE - Tooltip": "Enable PKCE - Tooltip",
|
||||
"Enable": "Enable",
|
||||
"Enable PKCE": "启用PKCE",
|
||||
"Enable PKCE - Tooltip": "是否启用PKCE扩展协议",
|
||||
"Enable proxy": "启用代理",
|
||||
"Enable proxy - Tooltip": "发送邮件或短信时启用socks5代理",
|
||||
"Endpoint": "地域节点 (外网)",
|
||||
@@ -1037,7 +1067,7 @@
|
||||
"Metadata url": "Metadata链接",
|
||||
"Metadata url - Tooltip": "SAML的Metadata链接",
|
||||
"Method - Tooltip": "登录方法,二维码或者静默授权登录",
|
||||
"Mobile": "Mobile",
|
||||
"Mobile": "移动端",
|
||||
"New Provider": "添加提供商",
|
||||
"Parameter": "参数",
|
||||
"Parameter - Tooltip": "配置参数",
|
||||
@@ -1055,7 +1085,7 @@
|
||||
"Prompted": "注册后提醒绑定",
|
||||
"Provider URL": "提供商URL",
|
||||
"Provider URL - Tooltip": "提供商网址配置对应的URL,该字段仅用来方便跳转,在Casdoor平台中未使用",
|
||||
"Provider test successful": "Provider test successful",
|
||||
"Provider test successful": "提供商测试成功",
|
||||
"Public key": "公钥",
|
||||
"Public key - Tooltip": "用于加密的公钥",
|
||||
"RADIUS Shared Secret - Tooltip": "RADIUS的共享密钥",
|
||||
@@ -1074,9 +1104,12 @@
|
||||
"SP ACS URL": "SP ACS 网址",
|
||||
"SP ACS URL - Tooltip": "服务提供商(SP)的断言消费者服务(ACS)地址",
|
||||
"SP Entity ID": "SP 实体 ID",
|
||||
"SSL mode": "SSL mode",
|
||||
"SSL mode - Tooltip": "SSL mode - Tooltip",
|
||||
"Scene": "场景",
|
||||
"Scene - Tooltip": "表示功能或操作适用的具体业务场景,用于适配不同场景下的逻辑处理",
|
||||
"Scope": "范围",
|
||||
"Scope - Tooltip": "Scope - Tooltip",
|
||||
"Secret access key": "秘密访问密钥",
|
||||
"Secret access key - Tooltip": "与访问密钥配套的私密密钥",
|
||||
"Secret key": "密钥",
|
||||
@@ -1111,8 +1144,8 @@
|
||||
"Sub type - Tooltip": "在主类型下进一步细分的类别",
|
||||
"Subject": "主题",
|
||||
"Subject - Tooltip": "邮件的主题",
|
||||
"Subtype": "Subtype",
|
||||
"Subtype - Tooltip": "Subtype - Tooltip",
|
||||
"Subtype": "子类型",
|
||||
"Subtype - Tooltip": "在主类型下的细分类别",
|
||||
"Syncer test": "同步器测试",
|
||||
"Syncer test - Tooltip": "测试同步器是否连通",
|
||||
"Team ID": "Team ID",
|
||||
@@ -1126,8 +1159,8 @@
|
||||
"Test SMTP Connection": "测试SMTP连接",
|
||||
"Third-party": "第三方",
|
||||
"This field is required": "此字段是必需的",
|
||||
"To address": "To address",
|
||||
"To address - Tooltip": "Email address of \"To\"",
|
||||
"To address": "收件人地址",
|
||||
"To address - Tooltip": "邮件的收件人地址",
|
||||
"Token URL": "Token链接",
|
||||
"Token URL - Tooltip": "自定义OAuth的Token链接",
|
||||
"Use WeChat Media Platform in PC": "在PC端使用微信公众平台",
|
||||
@@ -1138,8 +1171,8 @@
|
||||
"Use global endpoint - Tooltip": "启用全局地址",
|
||||
"Use id as name": "使用id作为用户名",
|
||||
"Use id as name - Tooltip": "使用id作为用户的名字",
|
||||
"User flow": "User flow",
|
||||
"User flow - Tooltip": "User flow",
|
||||
"User flow": "用户流程",
|
||||
"User flow - Tooltip": "用户认证流程配置",
|
||||
"User mapping": "用户映射",
|
||||
"User mapping - Tooltip": "用户属性映射",
|
||||
"UserInfo URL": "UserInfo链接",
|
||||
@@ -1210,7 +1243,7 @@
|
||||
"Text 4": "文本4",
|
||||
"Text 5": "文本5",
|
||||
"The input Email doesn't match the signup item regex!": "您输入的邮箱地址与注册项的regex表达式不匹配!",
|
||||
"The input doesn't match the signup item regex!": "The input doesn't match the signup item regex!",
|
||||
"The input doesn't match the signup item regex!": "输入内容与注册项的正则表达式不匹配!",
|
||||
"The input is not invoice Tax ID!": "您输入的纳税人识别号有误!",
|
||||
"The input is not invoice title!": "您输入的发票抬头有误!",
|
||||
"The input is not valid Phone!": "您输入的手机号格式有误!",
|
||||
@@ -1230,14 +1263,17 @@
|
||||
"New Subscription": "添加订阅",
|
||||
"Start time": "开始时间",
|
||||
"Start time - Tooltip": "订阅的开始时间",
|
||||
"Subscription plan": "Subscription plan",
|
||||
"Subscription pricing": "Subscription pricing",
|
||||
"Subscription plan": "订阅计划",
|
||||
"Subscription pricing": "订阅定价",
|
||||
"Suspended": "已暂停",
|
||||
"Upcoming": "即将到来的",
|
||||
"View Subscription": "View Subscription"
|
||||
"View Subscription": "查看订阅"
|
||||
},
|
||||
"syncer": {
|
||||
"API Token / Password": "API Token / Password",
|
||||
"AWS Access Key ID": "AWS Access Key ID",
|
||||
"AWS Region": "AWS Region",
|
||||
"AWS Secret Access Key": "AWS Secret Access Key",
|
||||
"Admin Email": "Admin Email",
|
||||
"Affiliation table": "工作单位表",
|
||||
"Affiliation table - Tooltip": "工作单位的数据库表名",
|
||||
@@ -1311,16 +1347,16 @@
|
||||
"Theme - Tooltip": "应用的样式主题"
|
||||
},
|
||||
"ticket": {
|
||||
"Closed": "Closed",
|
||||
"Edit Ticket": "Edit Ticket",
|
||||
"In Progress": "In Progress",
|
||||
"Messages": "Messages",
|
||||
"New Ticket": "New Ticket",
|
||||
"Open": "Open",
|
||||
"Please enter a message": "Please enter a message",
|
||||
"Press Ctrl+Enter to send": "Press Ctrl+Enter to send",
|
||||
"Resolved": "Resolved",
|
||||
"Type your message here...": "Type your message here..."
|
||||
"Closed": "已关闭",
|
||||
"Edit Ticket": "编辑工单",
|
||||
"In Progress": "进行中",
|
||||
"Messages": "消息",
|
||||
"New Ticket": "新工单",
|
||||
"Open": "已打开",
|
||||
"Please enter a message": "请输入消息",
|
||||
"Press Ctrl+Enter to send": "按 Ctrl+Enter 发送",
|
||||
"Resolved": "已解决",
|
||||
"Type your message here...": "在此输入您的消息..."
|
||||
},
|
||||
"token": {
|
||||
"Access token": "访问令牌",
|
||||
@@ -1342,7 +1378,7 @@
|
||||
"Amount - Tooltip": "交易产品的金额",
|
||||
"Edit Transaction": "编辑交易",
|
||||
"New Transaction": "添加交易",
|
||||
"Recharge": "Recharge"
|
||||
"Recharge": "充值"
|
||||
},
|
||||
"user": {
|
||||
"3rd-party logins": "第三方登录",
|
||||
@@ -1363,7 +1399,7 @@
|
||||
"Captcha Verify Success": "验证码校验成功",
|
||||
"City": "城市",
|
||||
"Country code": "国家代码",
|
||||
"Country code - Tooltip": "Country code - Tooltip",
|
||||
"Country code - Tooltip": "国家代码提示",
|
||||
"Country/Region": "国家/地区",
|
||||
"Country/Region - Tooltip": "国家或地区",
|
||||
"Edit User": "编辑用户",
|
||||
@@ -1386,10 +1422,10 @@
|
||||
"ID card type": "身份证类型",
|
||||
"ID card type - Tooltip": "身份证类型",
|
||||
"ID card with person": "手持身份证",
|
||||
"ID verification": "ID verification",
|
||||
"ID verification - Tooltip": "ID verification - Tooltip",
|
||||
"Identity verification successful": "Identity verification successful",
|
||||
"Identity verified": "Identity verified",
|
||||
"ID verification": "身份验证",
|
||||
"ID verification - Tooltip": "身份证验证功能",
|
||||
"Identity verification successful": "身份验证成功",
|
||||
"Identity verified": "身份已验证",
|
||||
"Input your email": "请输入邮箱",
|
||||
"Input your phone number": "输入手机号",
|
||||
"Is admin": "是组织管理员",
|
||||
@@ -1399,7 +1435,7 @@
|
||||
"Is forbidden": "被禁用",
|
||||
"Is forbidden - Tooltip": "被禁用的用户无法再登录",
|
||||
"Is online": "在线",
|
||||
"Is verified": "Is verified",
|
||||
"Is verified": "已验证",
|
||||
"Karma": "信誉分",
|
||||
"Karma - Tooltip": "用于衡量用户信用等级的评分,影响权限或服务使用范围",
|
||||
"Keys": "键",
|
||||
@@ -1424,16 +1460,16 @@
|
||||
"Other": "其他",
|
||||
"Password set successfully": "密码设置成功",
|
||||
"Phone cannot be empty": "手机号不能为空",
|
||||
"Please enter your real name": "Please enter your real name",
|
||||
"Please fill in ID card information first": "Please fill in ID card information first",
|
||||
"Please fill in your real name first": "Please fill in your real name first",
|
||||
"Please enter your real name": "请输入您的真实姓名",
|
||||
"Please fill in ID card information first": "请先填写身份证信息",
|
||||
"Please fill in your real name first": "请先填写您的真实姓名",
|
||||
"Please select avatar from resources": "从资源中选择...",
|
||||
"Properties": "属性",
|
||||
"Properties - Tooltip": "用户的属性",
|
||||
"Ranking": "排名",
|
||||
"Ranking - Tooltip": "根据评分、活跃度等指标对用户进行的排序位置",
|
||||
"Re-enter New": "重复新密码",
|
||||
"Real name - Tooltip": "Real name - Tooltip",
|
||||
"Real name - Tooltip": "真实姓名提示",
|
||||
"Register source": "注册来源",
|
||||
"Register source - Tooltip": "用户注册的来源",
|
||||
"Register type": "注册类型",
|
||||
@@ -1462,8 +1498,8 @@
|
||||
"User Profile": "用户个人页",
|
||||
"Values": "值",
|
||||
"Verification code sent": "验证码已发送",
|
||||
"Verified": "Verified",
|
||||
"Verify Identity": "Verify Identity",
|
||||
"Verified": "已验证",
|
||||
"Verify Identity": "验证身份",
|
||||
"WebAuthn credentials": "WebAuthn凭据",
|
||||
"Work": "工作",
|
||||
"You have changed the username, please save your change first before modifying the password": "你已经更改了你的用户名,请你再更改密码前保存更改",
|
||||
|
||||
81
web/src/table/CartTable.js
Normal file
81
web/src/table/CartTable.js
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Table} from "antd";
|
||||
import i18next from "i18next";
|
||||
import * as Setting from "../Setting";
|
||||
|
||||
class CartTable extends React.Component {
|
||||
render() {
|
||||
const columns = [
|
||||
{
|
||||
title: i18next.t("product:Name"),
|
||||
dataIndex: "displayName",
|
||||
key: "displayName",
|
||||
width: "200px",
|
||||
},
|
||||
{
|
||||
title: i18next.t("product:Image"),
|
||||
dataIndex: "image",
|
||||
key: "image",
|
||||
width: "80px",
|
||||
render: (text, record, index) => {
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<a target="_blank" rel="noreferrer" href={text}>
|
||||
<img src={text} alt={record.displayName} width={40} />
|
||||
</a>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("product:Price"),
|
||||
dataIndex: "price",
|
||||
key: "price",
|
||||
width: "120px",
|
||||
render: (text, record, index) => {
|
||||
return Setting.getCurrencySymbol(record.currency) + text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("product:Quantity"),
|
||||
dataIndex: "quantity",
|
||||
key: "quantity",
|
||||
width: "100px",
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Detail"),
|
||||
dataIndex: "detail",
|
||||
key: "detail",
|
||||
},
|
||||
];
|
||||
|
||||
const cart = this.props.cart || [];
|
||||
|
||||
return (
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={cart}
|
||||
rowKey={(record) => `${record.owner}/${record.name}`}
|
||||
size="small"
|
||||
pagination={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CartTable;
|
||||
166
web/src/table/ScopeTable.js
Normal file
166
web/src/table/ScopeTable.js
Normal file
@@ -0,0 +1,166 @@
|
||||
// Copyright 2026 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
|
||||
import {Button, Input, Table, Tooltip} from "antd";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
|
||||
class ScopeTable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
classes: props,
|
||||
};
|
||||
}
|
||||
|
||||
updateTable(table) {
|
||||
this.props.onUpdateTable(table);
|
||||
}
|
||||
|
||||
updateField(table, index, key, value) {
|
||||
table[index][key] = value;
|
||||
this.updateTable(table);
|
||||
}
|
||||
|
||||
addRow(table) {
|
||||
const row = {name: "", displayName: "", description: ""};
|
||||
if (table === undefined) {
|
||||
table = [];
|
||||
}
|
||||
table = Setting.addRow(table, row);
|
||||
this.updateTable(table);
|
||||
}
|
||||
|
||||
deleteRow(table, i) {
|
||||
table = Setting.deleteRow(table, i);
|
||||
this.updateTable(table);
|
||||
}
|
||||
|
||||
upRow(table, i) {
|
||||
table = Setting.swapRow(table, i - 1, i);
|
||||
this.updateTable(table);
|
||||
}
|
||||
|
||||
downRow(table, i) {
|
||||
table = Setting.swapRow(table, i, i + 1);
|
||||
this.updateTable(table);
|
||||
}
|
||||
|
||||
renderTable(table) {
|
||||
if (table === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
width: "25%",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="e.g., files:read"
|
||||
onChange={e => {
|
||||
this.updateField(table, index, "name", e.target.value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Display name"),
|
||||
dataIndex: "displayName",
|
||||
key: "displayName",
|
||||
width: "25%",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="e.g., Read Files"
|
||||
onChange={e => {
|
||||
this.updateField(table, index, "displayName", e.target.value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Description"),
|
||||
dataIndex: "description",
|
||||
key: "description",
|
||||
width: "40%",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Input
|
||||
value={text}
|
||||
placeholder="e.g., Allow reading your files and documents"
|
||||
onChange={e => {
|
||||
this.updateField(table, index, "description", e.target.value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Action"),
|
||||
key: "action",
|
||||
width: "10%",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<div>
|
||||
<Tooltip placement="bottomLeft" title={i18next.t("general:Up")}>
|
||||
<Button style={{marginRight: "5px"}} disabled={index === 0} icon={<UpOutlined />} size="small" onClick={() => this.upRow(table, index)} />
|
||||
</Tooltip>
|
||||
<Tooltip placement="topLeft" title={i18next.t("general:Down")}>
|
||||
<Button style={{marginRight: "5px"}} disabled={index === table.length - 1} icon={<DownOutlined />} size="small" onClick={() => this.downRow(table, index)} />
|
||||
</Tooltip>
|
||||
<Tooltip placement="topLeft" title={i18next.t("general:Delete")}>
|
||||
<Button icon={<DeleteOutlined />} size="small" onClick={() => this.deleteRow(table, index)} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table scroll={{x: "max-content"}} rowKey={(record, index) => index} columns={columns} dataSource={table} size="middle" bordered pagination={false}
|
||||
title={() => (
|
||||
<div>
|
||||
{this.props.title}
|
||||
<Button style={{marginRight: "5px"}} type="primary" size="small" onClick={() => this.addRow(table)}>{i18next.t("general:Add")}</Button>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
this.renderTable(this.props.table)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ScopeTable;
|
||||
@@ -24,6 +24,8 @@ class TokenAttributeTable extends React.Component {
|
||||
this.state = {
|
||||
classes: props,
|
||||
};
|
||||
// List of available user fields for "Existing Field" category
|
||||
this.userFields = ["Owner", "Name", "Id", "DisplayName", "Email", "Phone", "Tag", "Roles", "Permissions", "permissionNames", "Groups"];
|
||||
}
|
||||
|
||||
updateTable(table) {
|
||||
@@ -36,7 +38,8 @@ class TokenAttributeTable extends React.Component {
|
||||
}
|
||||
|
||||
addRow(table) {
|
||||
const row = {Name: "", nameFormat: "", value: ""};
|
||||
// Note: Field names use lowercase to match JSON serialization from backend (json:"name", json:"value", json:"type", json:"category")
|
||||
const row = {name: "", value: "", type: "Array", category: "Static Value"};
|
||||
if (table === undefined || table === null) {
|
||||
table = [];
|
||||
}
|
||||
@@ -74,24 +77,63 @@ class TokenAttributeTable extends React.Component {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Category"),
|
||||
dataIndex: "category",
|
||||
key: "category",
|
||||
width: "150px",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Select virtual={false} style={{width: "100%"}}
|
||||
value={text ?? "Static Value"}
|
||||
options={[
|
||||
{value: "Static Value", label: i18next.t("application:Static Value")},
|
||||
{value: "Existing Field", label: i18next.t("application:Existing Field")},
|
||||
].map((item) =>
|
||||
Setting.getOption(item.label, item.value))
|
||||
}
|
||||
onChange={value => {
|
||||
this.updateField(table, index, "category", value);
|
||||
}} >
|
||||
</Select>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("webhook:Value"),
|
||||
dataIndex: "value",
|
||||
key: "value",
|
||||
width: "200px",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Input value={text} onChange={e => {
|
||||
this.updateField(table, index, "value", e.target.value);
|
||||
}} />
|
||||
);
|
||||
const category = record.category ?? "Static Value";
|
||||
if (category === "Existing Field") {
|
||||
// Show dropdown for existing fields
|
||||
return (
|
||||
<Select virtual={false} style={{width: "100%"}}
|
||||
value={text}
|
||||
options={this.userFields.map((field) =>
|
||||
Setting.getOption(field, field))
|
||||
}
|
||||
onChange={value => {
|
||||
this.updateField(table, index, "value", value);
|
||||
}} >
|
||||
</Select>
|
||||
);
|
||||
} else {
|
||||
// Show text input for static values
|
||||
return (
|
||||
<Input value={text} onChange={e => {
|
||||
this.updateField(table, index, "value", e.target.value);
|
||||
}} />
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Type"),
|
||||
dataIndex: "type",
|
||||
key: "type",
|
||||
width: "200px",
|
||||
width: "150px",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Select virtual={false} style={{width: "100%"}}
|
||||
|
||||
Reference in New Issue
Block a user