mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-22 20:40:40 +08:00
Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a23033758f | ||
![]() |
f7bc822087 | ||
![]() |
e533ff1ee1 | ||
![]() |
9f187f690e | ||
![]() |
fe5aa1f214 | ||
![]() |
eda742a848 | ||
![]() |
83df077a02 | ||
![]() |
ad6080e763 | ||
![]() |
c179324de4 | ||
![]() |
645716e485 | ||
![]() |
955e73ddd1 | ||
![]() |
2493ae9cfe | ||
![]() |
b5c80513fb | ||
![]() |
0653353be1 | ||
![]() |
d6778fb4e6 | ||
![]() |
fee7773839 | ||
![]() |
d47ac6b957 | ||
![]() |
857824df19 | ||
![]() |
1e98d1e11b | ||
![]() |
48ba88de2d | ||
![]() |
a3a142db39 | ||
![]() |
3bb7cc6b81 | ||
![]() |
1fb3249bfd | ||
![]() |
ff8f61a84c | ||
![]() |
a118879dc0 | ||
![]() |
386b673446 | ||
![]() |
6abd46fe81 | ||
![]() |
49d734d249 | ||
![]() |
f5b4cd7fab | ||
![]() |
76f322861a | ||
![]() |
124c28f1e1 | ||
![]() |
e0d9cc7ed1 | ||
![]() |
75c1ae4366 | ||
![]() |
d537377b31 | ||
![]() |
462ecce43b | ||
![]() |
a84664b55d |
@@ -719,7 +719,8 @@ func (c *ApiController) Login() {
|
||||
|
||||
setHttpClient(idProvider, provider.Type)
|
||||
|
||||
if authForm.State != conf.GetConfigString("authState") && authForm.State != application.Name {
|
||||
stateApplicationName := strings.Split(authForm.State, "-org-")[0]
|
||||
if authForm.State != conf.GetConfigString("authState") && stateApplicationName != application.Name {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:State expected: %s, but got: %s"), conf.GetConfigString("authState"), authForm.State))
|
||||
return
|
||||
}
|
||||
|
@@ -40,6 +40,18 @@ func (c *ApiController) Enforce() {
|
||||
enforcerId := c.Input().Get("enforcerId")
|
||||
owner := c.Input().Get("owner")
|
||||
|
||||
params := []string{permissionId, modelId, resourceId, enforcerId, owner}
|
||||
nonEmpty := 0
|
||||
for _, param := range params {
|
||||
if param != "" {
|
||||
nonEmpty++
|
||||
}
|
||||
}
|
||||
if nonEmpty > 1 {
|
||||
c.ResponseError("Only one of the parameters (permissionId, modelId, resourceId, enforcerId, owner) should be provided")
|
||||
return
|
||||
}
|
||||
|
||||
if len(c.Ctx.Input.RequestBody) == 0 {
|
||||
c.ResponseError("The request body should not be empty")
|
||||
return
|
||||
@@ -169,6 +181,18 @@ func (c *ApiController) BatchEnforce() {
|
||||
enforcerId := c.Input().Get("enforcerId")
|
||||
owner := c.Input().Get("owner")
|
||||
|
||||
params := []string{permissionId, modelId, enforcerId, owner}
|
||||
nonEmpty := 0
|
||||
for _, param := range params {
|
||||
if param != "" {
|
||||
nonEmpty++
|
||||
}
|
||||
}
|
||||
if nonEmpty > 1 {
|
||||
c.ResponseError("Only one of the parameters (permissionId, modelId, enforcerId, owner) should be provided")
|
||||
return
|
||||
}
|
||||
|
||||
var requests [][]string
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &requests)
|
||||
if err != nil {
|
||||
|
@@ -25,6 +25,7 @@ const (
|
||||
goCliRepo = "https://api.github.com/repos/casbin/casbin-go-cli/releases/latest"
|
||||
rustCliRepo = "https://api.github.com/repos/casbin-rs/casbin-rust-cli/releases/latest"
|
||||
pythonCliRepo = "https://api.github.com/repos/casbin/casbin-python-cli/releases/latest"
|
||||
dotnetCliRepo = "https://api.github.com/repos/casbin-net/casbin-dotnet-cli/releases/latest"
|
||||
downloadFolder = "bin"
|
||||
)
|
||||
|
||||
@@ -45,6 +46,7 @@ func getBinaryNames() map[string]string {
|
||||
java = "java"
|
||||
rust = "rust"
|
||||
python = "python"
|
||||
dotnet = "dotnet"
|
||||
)
|
||||
|
||||
arch := runtime.GOARCH
|
||||
@@ -65,6 +67,7 @@ func getBinaryNames() map[string]string {
|
||||
java: "casbin-java-cli.jar",
|
||||
rust: fmt.Sprintf("casbin-rust-cli-%s-pc-windows-gnu", archNames.rustArch),
|
||||
python: fmt.Sprintf("casbin-python-cli-windows-%s.exe", archNames.goArch),
|
||||
dotnet: fmt.Sprintf("casbin-dotnet-cli-windows-%s.exe", archNames.goArch),
|
||||
}
|
||||
case "darwin":
|
||||
return map[string]string{
|
||||
@@ -72,6 +75,7 @@ func getBinaryNames() map[string]string {
|
||||
java: "casbin-java-cli.jar",
|
||||
rust: fmt.Sprintf("casbin-rust-cli-%s-apple-darwin", archNames.rustArch),
|
||||
python: fmt.Sprintf("casbin-python-cli-darwin-%s", archNames.goArch),
|
||||
dotnet: fmt.Sprintf("casbin-dotnet-cli-darwin-%s", archNames.goArch),
|
||||
}
|
||||
case "linux":
|
||||
return map[string]string{
|
||||
@@ -79,6 +83,7 @@ func getBinaryNames() map[string]string {
|
||||
java: "casbin-java-cli.jar",
|
||||
rust: fmt.Sprintf("casbin-rust-cli-%s-unknown-linux-gnu", archNames.rustArch),
|
||||
python: fmt.Sprintf("casbin-python-cli-linux-%s", archNames.goArch),
|
||||
dotnet: fmt.Sprintf("casbin-dotnet-cli-linux-%s", archNames.goArch),
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
@@ -108,6 +113,11 @@ func getFinalBinaryName(lang string) string {
|
||||
return "casbin-python-cli.exe"
|
||||
}
|
||||
return "casbin-python-cli"
|
||||
case "dotnet":
|
||||
if runtime.GOOS == "windows" {
|
||||
return "casbin-dotnet-cli.exe"
|
||||
}
|
||||
return "casbin-dotnet-cli"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
@@ -347,6 +357,7 @@ func downloadCLI() error {
|
||||
"go": goCliRepo,
|
||||
"rust": rustCliRepo,
|
||||
"python": pythonCliRepo,
|
||||
"dotnet": dotnetCliRepo,
|
||||
}
|
||||
|
||||
for lang, repo := range repos {
|
||||
|
@@ -17,7 +17,6 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@@ -200,37 +199,28 @@ func (c *ApiController) GetPolicies() {
|
||||
// GetFilteredPolicies
|
||||
// @Title GetFilteredPolicies
|
||||
// @Tag Enforcer API
|
||||
// @Description get filtered policies
|
||||
// @Description get filtered policies with support for multiple filters via POST body
|
||||
// @Param id query string true "The id ( owner/name ) of enforcer"
|
||||
// @Param ptype query string false "Policy type, default is 'p'"
|
||||
// @Param fieldIndex query int false "Field index for filtering"
|
||||
// @Param fieldValues query string false "Field values for filtering, comma-separated"
|
||||
// @Param body body []object.Filter true "Array of filter objects for multiple filters"
|
||||
// @Success 200 {array} xormadapter.CasbinRule
|
||||
// @router /get-filtered-policies [get]
|
||||
// @router /get-filtered-policies [post]
|
||||
func (c *ApiController) GetFilteredPolicies() {
|
||||
id := c.Input().Get("id")
|
||||
ptype := c.Input().Get("ptype")
|
||||
fieldIndexStr := c.Input().Get("fieldIndex")
|
||||
fieldValuesStr := c.Input().Get("fieldValues")
|
||||
|
||||
if ptype == "" {
|
||||
ptype = "p"
|
||||
}
|
||||
|
||||
fieldIndex := util.ParseInt(fieldIndexStr)
|
||||
|
||||
var fieldValues []string
|
||||
if fieldValuesStr != "" {
|
||||
fieldValues = strings.Split(fieldValuesStr, ",")
|
||||
}
|
||||
|
||||
policies, err := object.GetFilteredPolicies(id, ptype, fieldIndex, fieldValues...)
|
||||
var filters []object.Filter
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &filters)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(policies)
|
||||
filteredPolicies, err := object.GetFilteredPoliciesMulti(id, filters)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(filteredPolicies)
|
||||
}
|
||||
|
||||
// UpdatePolicy
|
||||
|
@@ -16,6 +16,8 @@ package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@@ -188,3 +190,73 @@ func (c *ApiController) VerifyInvitation() {
|
||||
|
||||
c.ResponseOk(payment, attachInfo)
|
||||
}
|
||||
|
||||
// SendInvitation
|
||||
// @Title VerifyInvitation
|
||||
// @Tag Invitation API
|
||||
// @Description verify invitation
|
||||
// @Param id query string true "The id ( owner/name ) of the invitation"
|
||||
// @Param body body []string true "The details of the invitation"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /send-invitation [post]
|
||||
func (c *ApiController) SendInvitation() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var destinations []string
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &destinations)
|
||||
|
||||
if !c.IsAdmin() {
|
||||
c.ResponseError(c.T("auth:Unauthorized operation"))
|
||||
return
|
||||
}
|
||||
|
||||
invitation, err := object.GetInvitation(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if invitation == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("invitation:Invitation %s does not exist"), id))
|
||||
return
|
||||
}
|
||||
|
||||
organization, err := object.GetOrganization(fmt.Sprintf("admin/%s", invitation.Owner))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
application, err := object.GetApplicationByOrganizationName(invitation.Owner)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The organization: %s should have one application at least"), invitation.Owner))
|
||||
return
|
||||
}
|
||||
|
||||
provider, err := application.GetEmailProvider("Invitation")
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if provider == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("verification:please add an Email provider to the \"Providers\" list for the application: %s"), invitation.Owner))
|
||||
return
|
||||
}
|
||||
|
||||
content := provider.Metadata
|
||||
|
||||
content = strings.ReplaceAll(content, "%code", invitation.Code)
|
||||
content = strings.ReplaceAll(content, "%link", invitation.GetInvitationLink(c.Ctx.Request.Host, application.Name))
|
||||
|
||||
err = object.SendEmail(provider, provider.Title, content, destinations, organization.DisplayName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk()
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -187,6 +188,11 @@ func (c *ApiController) DeleteResource() {
|
||||
}
|
||||
_, resource.Name = refineFullFilePath(resource.Name)
|
||||
|
||||
tag := c.Input().Get("tag")
|
||||
if tag == "Direct" {
|
||||
resource.Name = path.Join(provider.PathPrefix, resource.Name)
|
||||
}
|
||||
|
||||
err = object.DeleteFile(provider, resource.Name, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
|
@@ -144,7 +144,7 @@ func (c *ApiController) SendEmail() {
|
||||
content = strings.Replace(content, string(matchContent), "", -1)
|
||||
|
||||
for _, receiver := range emailForm.Receivers {
|
||||
err = object.SendEmail(provider, emailForm.Title, content, receiver, emailForm.Sender)
|
||||
err = object.SendEmail(provider, emailForm.Title, content, []string{receiver}, emailForm.Sender)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
@@ -435,9 +435,15 @@ func (c *ApiController) ResetEmailOrPhone() {
|
||||
|
||||
switch destType {
|
||||
case object.VerifyTypeEmail:
|
||||
id := user.GetId()
|
||||
user.Email = dest
|
||||
user.EmailVerified = true
|
||||
_, err = object.UpdateUser(user.GetId(), user, []string{"email", "email_verified"}, false)
|
||||
columns := []string{"email", "email_verified"}
|
||||
if organization.UseEmailAsUsername {
|
||||
user.Name = user.Email
|
||||
columns = append(columns, "name")
|
||||
}
|
||||
_, err = object.UpdateUser(id, user, columns, false)
|
||||
case object.VerifyTypePhone:
|
||||
user.Phone = dest
|
||||
_, err = object.SetUserField(user, "phone", user.Phone)
|
||||
@@ -449,6 +455,9 @@ func (c *ApiController) ResetEmailOrPhone() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if organization.UseEmailAsUsername {
|
||||
c.SetSessionUsername(user.GetId())
|
||||
}
|
||||
|
||||
err = object.DisableVerificationCode(checkDest)
|
||||
if err != nil {
|
||||
|
@@ -96,15 +96,17 @@ func NewAzureACSEmailProvider(accessKey string, endpoint string) *AzureACSEmailP
|
||||
}
|
||||
}
|
||||
|
||||
func newEmail(fromAddress string, toAddress string, subject string, content string) *Email {
|
||||
func newEmail(fromAddress string, toAddress []string, subject string, content string) *Email {
|
||||
var to []EmailAddress
|
||||
for _, addr := range toAddress {
|
||||
to = append(to, EmailAddress{
|
||||
DisplayName: addr,
|
||||
Address: addr,
|
||||
})
|
||||
}
|
||||
return &Email{
|
||||
Recipients: Recipients{
|
||||
To: []EmailAddress{
|
||||
{
|
||||
DisplayName: toAddress,
|
||||
Address: toAddress,
|
||||
},
|
||||
},
|
||||
To: to,
|
||||
},
|
||||
SenderAddress: fromAddress,
|
||||
Content: Content{
|
||||
@@ -116,7 +118,7 @@ func newEmail(fromAddress string, toAddress string, subject string, content stri
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AzureACSEmailProvider) Send(fromAddress string, fromName string, toAddress string, subject string, content string) error {
|
||||
func (a *AzureACSEmailProvider) Send(fromAddress string, fromName string, toAddress []string, subject string, content string) error {
|
||||
email := newEmail(fromAddress, toAddress, subject, content)
|
||||
|
||||
postBody, err := json.Marshal(email)
|
||||
|
@@ -48,21 +48,23 @@ func NewHttpEmailProvider(endpoint string, method string, httpHeaders map[string
|
||||
return client
|
||||
}
|
||||
|
||||
func (c *HttpEmailProvider) Send(fromAddress string, fromName string, toAddress string, subject string, content string) error {
|
||||
func (c *HttpEmailProvider) Send(fromAddress string, fromName string, toAddress []string, subject string, content string) error {
|
||||
var req *http.Request
|
||||
var err error
|
||||
|
||||
fromNameField := "fromName"
|
||||
toAddressField := "toAddress"
|
||||
toAddressesField := "toAddresses"
|
||||
subjectField := "subject"
|
||||
contentField := "content"
|
||||
|
||||
for k, v := range c.bodyMapping {
|
||||
switch k {
|
||||
case "fromName":
|
||||
fromNameField = v
|
||||
case "toAddress":
|
||||
toAddressField = v
|
||||
case "toAddresses":
|
||||
toAddressesField = v
|
||||
case "subject":
|
||||
subjectField = v
|
||||
case "content":
|
||||
@@ -73,7 +75,6 @@ func (c *HttpEmailProvider) Send(fromAddress string, fromName string, toAddress
|
||||
if c.method == "POST" || c.method == "PUT" || c.method == "DELETE" {
|
||||
bodyMap := make(map[string]string)
|
||||
bodyMap[fromNameField] = fromName
|
||||
bodyMap[toAddressField] = toAddress
|
||||
bodyMap[subjectField] = subject
|
||||
bodyMap[contentField] = content
|
||||
|
||||
@@ -89,6 +90,13 @@ func (c *HttpEmailProvider) Send(fromAddress string, fromName string, toAddress
|
||||
for k, v := range bodyMap {
|
||||
formValues.Add(k, v)
|
||||
}
|
||||
if len(toAddress) == 1 {
|
||||
formValues.Add(toAddressField, toAddress[0])
|
||||
} else {
|
||||
for _, addr := range toAddress {
|
||||
formValues.Add(toAddressesField, addr)
|
||||
}
|
||||
}
|
||||
req, err = http.NewRequest(c.method, c.endpoint, strings.NewReader(formValues.Encode()))
|
||||
}
|
||||
|
||||
@@ -105,7 +113,13 @@ func (c *HttpEmailProvider) Send(fromAddress string, fromName string, toAddress
|
||||
|
||||
q := req.URL.Query()
|
||||
q.Add(fromNameField, fromName)
|
||||
q.Add(toAddressField, toAddress)
|
||||
if len(toAddress) == 1 {
|
||||
q.Add(toAddressField, toAddress[0])
|
||||
} else {
|
||||
for _, addr := range toAddress {
|
||||
q.Add(toAddressesField, addr)
|
||||
}
|
||||
}
|
||||
q.Add(subjectField, subject)
|
||||
q.Add(contentField, content)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
|
@@ -15,7 +15,7 @@
|
||||
package email
|
||||
|
||||
type EmailProvider interface {
|
||||
Send(fromAddress string, fromName, toAddress string, subject string, content string) error
|
||||
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) EmailProvider {
|
||||
|
@@ -41,13 +41,22 @@ func NewSendgridEmailProvider(apiKey string, host string, endpoint string) *Send
|
||||
return &SendgridEmailProvider{ApiKey: apiKey, Host: host, Endpoint: endpoint}
|
||||
}
|
||||
|
||||
func (s *SendgridEmailProvider) Send(fromAddress string, fromName string, toAddress string, subject string, content string) error {
|
||||
client := s.initSendgridClient()
|
||||
|
||||
func (s *SendgridEmailProvider) Send(fromAddress string, fromName string, toAddresses []string, subject string, content string) error {
|
||||
from := mail.NewEmail(fromName, fromAddress)
|
||||
to := mail.NewEmail("", toAddress)
|
||||
message := mail.NewSingleEmail(from, subject, to, "", content)
|
||||
message := mail.NewV3Mail()
|
||||
message.SetFrom(from)
|
||||
message.AddContent(mail.NewContent("text/html", content))
|
||||
|
||||
personalization := mail.NewPersonalization()
|
||||
|
||||
for _, toAddress := range toAddresses {
|
||||
to := mail.NewEmail(toAddress, toAddress)
|
||||
personalization.AddTos(to)
|
||||
}
|
||||
|
||||
message.AddPersonalizations(personalization)
|
||||
|
||||
client := s.initSendgridClient()
|
||||
resp, err := client.Send(message)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -44,11 +44,15 @@ func NewSmtpEmailProvider(userName string, password string, host string, port in
|
||||
return &SmtpEmailProvider{Dialer: dialer}
|
||||
}
|
||||
|
||||
func (s *SmtpEmailProvider) Send(fromAddress string, fromName string, toAddress string, subject string, content string) error {
|
||||
func (s *SmtpEmailProvider) Send(fromAddress string, fromName string, toAddresses []string, subject string, content string) error {
|
||||
message := gomail.NewMessage()
|
||||
|
||||
message.SetAddressHeader("From", fromAddress, fromName)
|
||||
message.SetHeader("To", toAddress)
|
||||
var addresses []string
|
||||
for _, address := range toAddresses {
|
||||
addresses = append(addresses, message.FormatAddress(address, ""))
|
||||
}
|
||||
message.SetHeader("To", addresses...)
|
||||
message.SetHeader("Subject", subject)
|
||||
message.SetBody("text/html", content)
|
||||
|
||||
|
@@ -47,7 +47,7 @@ func (form *VerificationForm) CheckParameter(checkType int, lang string) string
|
||||
return i18n.Translate(lang, "general:Missing parameter") + ": dest."
|
||||
}
|
||||
if form.CaptchaType == "" {
|
||||
return i18n.Translate(lang, "general:Missing parameter") + ": checkType."
|
||||
return i18n.Translate(lang, "general:Missing parameter") + ": captchaType."
|
||||
}
|
||||
if !strings.Contains(form.ApplicationId, "/") {
|
||||
return i18n.Translate(lang, "verification:Wrong parameter") + ": applicationId."
|
||||
|
1
go.mod
1
go.mod
@@ -52,7 +52,6 @@ require (
|
||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/stripe/stripe-go/v74 v74.29.0
|
||||
github.com/tealeg/xlsx v1.0.5
|
||||
|
2
go.sum
2
go.sum
@@ -872,8 +872,6 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
|
||||
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/slack-go/slack v0.12.3 h1:92/dfFU8Q5XP6Wp5rr5/T5JHLM5c5Smtn53fhToAP88=
|
||||
github.com/slack-go/slack v0.12.3/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
|
@@ -47,6 +47,7 @@ func TestGenerateI18nFrontend(t *testing.T) {
|
||||
applyToOtherLanguage("frontend", "fa", data)
|
||||
applyToOtherLanguage("frontend", "cs", data)
|
||||
applyToOtherLanguage("frontend", "sk", data)
|
||||
applyToOtherLanguage("frontend", "az", data)
|
||||
}
|
||||
|
||||
func TestGenerateI18nBackend(t *testing.T) {
|
||||
@@ -77,4 +78,5 @@ func TestGenerateI18nBackend(t *testing.T) {
|
||||
applyToOtherLanguage("backend", "fa", data)
|
||||
applyToOtherLanguage("backend", "cs", data)
|
||||
applyToOtherLanguage("backend", "sk", data)
|
||||
applyToOtherLanguage("backend", "az", data)
|
||||
}
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "هذه العملية غير مسموح بها في وضع العرض التوضيحي",
|
||||
"this operation requires administrator to perform": "هذه العملية تتطلب مسؤولاً لتنفيذها"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "خادم LDAP موجود"
|
||||
},
|
||||
|
196
i18n/locales/az/data.json
Normal file
196
i18n/locales/az/data.json
Normal file
@@ -0,0 +1,196 @@
|
||||
{
|
||||
"account": {
|
||||
"Failed to add user": "İstifadəçi əlavə etmə uğursuz oldu",
|
||||
"Get init score failed, error: %w": "Başlanğıc xal alınması uğursuz oldu, xəta: %w",
|
||||
"Please sign out first": "Xahiş edirik əvvəlcə çıxış edin",
|
||||
"The application does not allow to sign up new account": "Tətbiq yeni hesab qeydiyyatına icazə vermir"
|
||||
},
|
||||
"auth": {
|
||||
"Challenge method should be S256": "Çağırış metodu S256 olmalıdır",
|
||||
"DeviceCode Invalid": "Cihaz Kodu Etibarsızdır",
|
||||
"Failed to create user, user information is invalid: %s": "İstifadəçi yaratma uğursuz oldu, istifadəçi məlumatları etibarsızdır: %s",
|
||||
"Failed to login in: %s": "Giriş uğursuz oldu: %s",
|
||||
"Invalid token": "Etibarsız token",
|
||||
"State expected: %s, but got: %s": "Gözlənilən vəziyyət: %s, lakin alınan: %s",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Provayder üçün hesab: %s və istifadəçi adı: %s (%s) mövcud deyil və %%s vasitəsilə yeni hesab olaraq qeydiyyatdan keçməyə icazə verilmir, xahiş edirik qeydiyyat üçün başqa üsul istifadə edin",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Provayder üçün hesab: %s və istifadəçi adı: %s (%s) mövcud deyil və yeni hesab olaraq qeydiyyatdan keçməyə icazə verilmir, xahiş edirik IT dəstəyinizlə əlaqə saxlayın",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Provayder üçün hesab: %s və istifadəçi adı: %s (%s) artıq başqa hesabla əlaqələndirilmişdir: %s (%s)",
|
||||
"The application: %s does not exist": "Tətbiq: %s mövcud deyil",
|
||||
"The application: %s has disabled users to signin": "Tətbiq: %s istifadəçilərin girişini söndürmüşdür",
|
||||
"The login method: login with LDAP is not enabled for the application": "Giriş metodu: LDAP ilə giriş bu tətbiq üçün aktiv deyil",
|
||||
"The login method: login with SMS is not enabled for the application": "Giriş metodu: SMS ilə giriş bu tətbiq üçün aktiv deyil",
|
||||
"The login method: login with email is not enabled for the application": "Giriş metodu: email ilə giriş bu tətbiq üçün aktiv deyil",
|
||||
"The login method: login with face is not enabled for the application": "Giriş metodu: üz ilə giriş bu tətbiq üçün aktiv deyil",
|
||||
"The login method: login with password is not enabled for the application": "Giriş metodu: şifrə ilə giriş bu tətbiq üçün aktiv deyil",
|
||||
"The organization: %s does not exist": "Təşkilat: %s mövcud deyil",
|
||||
"The organization: %s has disabled users to signin": "Təşkilat: %s istifadəçilərin girişini söndürmüşdür",
|
||||
"The provider: %s does not exist": "Provayder: %s mövcud deyil",
|
||||
"The provider: %s is not enabled for the application": "Provayder: %s bu tətbiq üçün aktiv deyil",
|
||||
"Unauthorized operation": "İcazəsiz əməliyyat",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Naməlum təsdiq növü (şifrə və ya provayder deyil), forma = %s",
|
||||
"User's tag: %s is not listed in the application's tags": "İstifadəçinin teqi: %s tətbiqin teqləri siyahısında yoxdur",
|
||||
"UserCode Expired": "İstifadəçi Kodunun Vaxtı Keçib",
|
||||
"UserCode Invalid": "İstifadəçi Kodu Etibarsızdır",
|
||||
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "ödənişli istifadəçi %s aktiv və ya gözləyən abunəyə malik deyil və tətbiq: %s defolt qiymətləndirməyə malik deyil",
|
||||
"the application for user %s is not found": "istifadəçi %s üçün tətbiq tapılmadı",
|
||||
"the organization: %s is not found": "təşkilat: %s tapılmadı"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Xidmət %s və %s uyğun gəlmir"
|
||||
},
|
||||
"check": {
|
||||
"%s does not meet the CIDR format requirements: %s": "%s CIDR format tələblərinə cavab vermir: %s",
|
||||
"Affiliation cannot be blank": "Mənsub sahəsi boş ola bilməz",
|
||||
"CIDR for IP: %s should not be empty": "IP üçün CIDR: %s boş olmamalıdır",
|
||||
"Default code does not match the code's matching rules": "Defolt kod kodun uyğunluq qaydalara uyğun gəlmir",
|
||||
"DisplayName cannot be blank": "Göstərilən Ad boş ola bilməz",
|
||||
"DisplayName is not valid real name": "Göstərilən Ad etibarlı həqiqi ad deyil",
|
||||
"Email already exists": "Email artıq mövcuddur",
|
||||
"Email cannot be empty": "Email boş ola bilməz",
|
||||
"Email is invalid": "Email etibarsızdır",
|
||||
"Empty username.": "Boş istifadəçi adı.",
|
||||
"Face data does not exist, cannot log in": "Üz məlumatları mövcud deyil, giriş edilə bilməz",
|
||||
"Face data mismatch": "Üz məlumatları uyğun gəlmir",
|
||||
"Failed to parse client IP: %s": "Müştəri IP-ni təhlil etmək uğursuz oldu: %s",
|
||||
"FirstName cannot be blank": "Ad boş ola bilməz",
|
||||
"Invitation code cannot be blank": "Dəvət kodu boş ola bilməz",
|
||||
"Invitation code exhausted": "Dəvət kodu tükənib",
|
||||
"Invitation code is invalid": "Dəvət kodu etibarsızdır",
|
||||
"Invitation code suspended": "Dəvət kodu dayandırılıb",
|
||||
"LDAP user name or password incorrect": "LDAP istifadəçi adı və ya şifrə yanlışdır",
|
||||
"LastName cannot be blank": "Soyad boş ola bilməz",
|
||||
"Multiple accounts with same uid, please check your ldap server": "Eyni uid ilə çoxlu hesablar, xahiş edirik ldap serverinizi yoxlayın",
|
||||
"Organization does not exist": "Təşkilat mövcud deyil",
|
||||
"Password cannot be empty": "Şifrə boş ola bilməz",
|
||||
"Phone already exists": "Telefon artıq mövcuddur",
|
||||
"Phone cannot be empty": "Telefon boş ola bilməz",
|
||||
"Phone number is invalid": "Telefon nömrəsi etibarsızdır",
|
||||
"Please register using the email corresponding to the invitation code": "Xahiş edirik dəvət koduna uyğun email istifadə edərək qeydiyyatdan keçin",
|
||||
"Please register using the phone corresponding to the invitation code": "Xahiş edirik dəvət koduna uyğun telefon istifadə edərək qeydiyyatdan keçin",
|
||||
"Please register using the username corresponding to the invitation code": "Xahiş edirik dəvət koduna uyğun istifadəçi adı istifadə edərək qeydiyyatdan keçin",
|
||||
"Session outdated, please login again": "Sessiyanın vaxtı keçib, xahiş edirik yenidən daxil olun",
|
||||
"The invitation code has already been used": "Dəvət kodu artıq istifadə edilib",
|
||||
"The user is forbidden to sign in, please contact the administrator": "İstifadəçinin girişi qadağandır, xahiş edirik administratorla əlaqə saxlayın",
|
||||
"The user: %s doesn't exist in LDAP server": "İstifadəçi: %s LDAP serverində mövcud deyil",
|
||||
"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.": "İstifadəçi adı yalnız hərf-rəqəm simvolları, alt xətt və ya defis ehtiva edə bilər, ardıcıl defis və ya alt xətt ola bilməz və defis və ya alt xəttlə başlaya və ya bitə bilməz.",
|
||||
"The value \\\"%s\\\" for account field \\\"%s\\\" doesn't match the account item regex": "Hesab sahəsi \\\"%s\\\" üçün dəyər \\\"%s\\\" hesab elementi regex-inə uyğun gəlmir",
|
||||
"The value \\\"%s\\\" for signup field \\\"%s\\\" doesn't match the signup item regex of the application \\\"%s\\\"": "Qeydiyyat sahəsi \\\"%s\\\" üçün dəyər \\\"%s\\\" tətbiq \\\"%s\\\"in qeydiyyat elementi regex-inə uyğun gəlmir",
|
||||
"Username already exists": "İstifadəçi adı artıq mövcuddur",
|
||||
"Username cannot be an email address": "İstifadəçi adı email ünvanı ola bilməz",
|
||||
"Username cannot contain white spaces": "İstifadəçi adı boşluqlar ehtiva edə bilməz",
|
||||
"Username cannot start with a digit": "İstifadəçi adı rəqəmlə başlaya bilməz",
|
||||
"Username is too long (maximum is 255 characters).": "İstifadəçi adı çox uzundur (maksimum 255 simvoldur).",
|
||||
"Username must have at least 2 characters": "İstifadəçi adı ən azı 2 simvola malik olmalıdır",
|
||||
"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.": "İstifadəçi adı email formatını dəstəkləyir. Həmçinin istifadəçi adı yalnız hərf-rəqəm simvolları, alt xətt və ya defis ehtiva edə bilər, ardıcıl defis və ya alt xətt ola bilməz və defis və ya alt xəttlə başlaya və ya bitə bilməz. Həmçinin email formatına diqqət edin.",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Yanlış şifrə və ya kod dəfələrlə daxil etmisiniz, xahiş edirik %d dəqiqə gözləyin və yenidən cəhd edin",
|
||||
"Your IP address: %s has been banned according to the configuration of: ": "IP ünvanınız: %s konfiqurasiyaya görə qadağan edilib: ",
|
||||
"Your password has expired. Please reset your password by clicking \\\"Forgot password\\\"": "Şifrənizin vaxtı keçib. Xahiş edirik \\\"Şifrəni unutdum\\\" düyməsinə basaraq şifrənizi sıfırlayın",
|
||||
"Your region is not allow to signup by phone": "Regionunuzda telefonla qeydiyyata icazə verilmir",
|
||||
"password or code is incorrect": "şifrə və ya kod yanlışdır",
|
||||
"password or code is incorrect, you have %s remaining chances": "şifrə və ya kod yanlışdır, %s şansınız qalıb",
|
||||
"unsupported password type: %s": "dəstəklənməyən şifrə növü: %s"
|
||||
},
|
||||
"enforcer": {
|
||||
"the adapter: %s is not found": "adapter: %s tapılmadı"
|
||||
},
|
||||
"general": {
|
||||
"Failed to import groups": "Qrupları idxal etmək uğursuz oldu",
|
||||
"Failed to import users": "İstifadəçiləri idxal etmək uğursuz oldu",
|
||||
"Missing parameter": "Parametr çatışmır",
|
||||
"Only admin user can specify user": "Yalnız admin istifadəçi başqa istifadəçini təyin edə bilər",
|
||||
"Please login first": "Xahiş edirik əvvəlcə daxil olun",
|
||||
"The organization: %s should have one application at least": "Təşkilat: %s ən azı bir tətbiqə malik olmalıdır",
|
||||
"The user: %s doesn't exist": "İstifadəçi: %s mövcud deyil",
|
||||
"Wrong userId": "Yanlış istifadəçi ID-si",
|
||||
"don't support captchaProvider: ": "captcha provayderini dəstəkləmir: ",
|
||||
"this operation is not allowed in demo mode": "bu əməliyyat demo rejimində icazə verilmir",
|
||||
"this operation requires administrator to perform": "bu əməliyyat administrator tərəfindən yerinə yetirilməsini tələb edir"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP serveri mövcuddur"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "Xahiş edirik əvvəlcə əlaqələndirin",
|
||||
"This application has no providers": "Bu tətbiqin provayderləri yoxdur",
|
||||
"This application has no providers of type": "Bu tətbiqin bu növdə provayderi yoxdur",
|
||||
"This provider can't be unlinked": "Bu provayderin əlaqəsi kəsilə bilməz",
|
||||
"You are not the global admin, you can't unlink other users": "Siz qlobal admin deyilsiniz, digər istifadəçilərin əlaqəsini kəsə bilməzsiniz",
|
||||
"You can't unlink yourself, you are not a member of any application": "Öz əlaqənizi kəsə bilməzsiniz, heç bir tətbiqin üzvü deyilsiniz"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "Yalnız admin %s-ni dəyişdirə bilər.",
|
||||
"The %s is immutable.": "%s dəyişilməzdir.",
|
||||
"Unknown modify rule %s.": "Naməlum dəyişdirmə qaydası %s.",
|
||||
"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' təşkilatına yeni istifadəçi əlavə etmək hazırda söndürülüb. Qeyd edin: 'built-in' təşkilatındakı bütün istifadəçilər Casdoor-da qlobal administratorlardır. Sənədlərə baxın: https://casdoor.org/docs/basic/core-concepts#how-does-casdoor-manage-itself. Əgər hələ də 'built-in' təşkilat üçün istifadəçi yaratmaq istəyirsinizsə, təşkilatın tənzimləmələr səhifəsinə gedib 'İmtiyaz razılığına malikdir' seçimini aktiv edin."
|
||||
},
|
||||
"permission": {
|
||||
"The permission: \\\"%s\\\" doesn't exist": "İcazə: \\\"%s\\\" mövcud deyil"
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "Etibarsız tətbiq id-si",
|
||||
"the provider: %s does not exist": "provayder: %s mövcud deyil"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "Avatar teqi üçün istifadəçi nil-dir",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "İstifadəçi adı və ya tam fayl yolu boşdur: istifadəçi adı = %s, tam fayl yolu = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "Tətbiq %s tapılmadı"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "provayder %s-in kateqoriyası SAML deyil"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "emailForm üçün boş parametrlər: %v",
|
||||
"Invalid Email receivers: %s": "Etibarsız Email qəbuledicilər: %s",
|
||||
"Invalid phone receivers: %s": "Etibarsız telefon qəbuledicilər: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "obyekt açarı: %s icazə verilmir",
|
||||
"The provider type: %s is not supported": "provayder növü: %s dəstəklənmir"
|
||||
},
|
||||
"subscription": {
|
||||
"Error": "Xəta"
|
||||
},
|
||||
"token": {
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s bu tətbiqdə dəstəklənmir",
|
||||
"Invalid application or wrong clientSecret": "Etibarsız tətbiq və ya yanlış müştəri sirri",
|
||||
"Invalid client_id": "Etibarsız client_id",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Yönləndirmə URI: %s icazə verilən Yönləndirmə URI siyahısında mövcud deyil",
|
||||
"Token not found, invalid accessToken": "Token tapılmadı, etibarsız accessToken"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Göstərilən ad boş ola bilməz",
|
||||
"MFA email is enabled but email is empty": "MFA email aktiv edilib, lakin email boşdur",
|
||||
"MFA phone is enabled but phone number is empty": "MFA telefon aktiv edilib, lakin telefon nömrəsi boşdur",
|
||||
"New password cannot contain blank space.": "Yeni şifrə boş yer ehtiva edə bilməz.",
|
||||
"the user's owner and name should not be empty": "istifadəçinin sahibi və adı boş olmamalıdır"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "İstifadəçi ID-si üçün heç bir tətbiq tapılmadı: %s",
|
||||
"No provider for category: %s is found for application: %s": "Tətbiq üçün kateqoriya üçün heç bir provayder tapılmadı: %s: %s",
|
||||
"The provider: %s is not found": "Provayder: %s tapılmadı"
|
||||
},
|
||||
"verification": {
|
||||
"Invalid captcha provider.": "Etibarsız captcha provaydeři.",
|
||||
"Phone number is invalid in your region %s": "Telefon nömrəsi sizin regionunuzda etibarsızdır %s",
|
||||
"The verification code has already been used!": "Doğrulama kodu artıq istifadə edilib!",
|
||||
"The verification code has not been sent yet!": "Doğrulama kodu hələ göndərilməyib!",
|
||||
"Turing test failed.": "Türinq testi uğursuz oldu.",
|
||||
"Unable to get the email modify rule.": "Email dəyişdirmə qaydasını əldə etmək mümkün olmadı.",
|
||||
"Unable to get the phone modify rule.": "Telefon dəyişdirmə qaydasını əldə etmək mümkün olmadı.",
|
||||
"Unknown type": "Naməlum növ",
|
||||
"Wrong verification code!": "Yanlış doğrulama kodu!",
|
||||
"You should verify your code in %d min!": "Kodunuzu %d dəqiqə içində doğrulamalısınız!",
|
||||
"please add a SMS provider to the \\\"Providers\\\" list for the application: %s": "xahiş edirik tətbiq üçün \\\"Provaydeerlər\\\" siyahısına SMS provaydeři əlavə edin: %s",
|
||||
"please add an Email provider to the \\\"Providers\\\" list for the application: %s": "xahiş edirik tətbiq üçün \\\"Provaydeerlər\\\" siyahısına Email provaydeři əlavə edin: %s",
|
||||
"the user does not exist, please sign up first": "istifadəçi mövcud deyil, xahiş edirik əvvəlcə qeydiyyatdan keçin"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "Bu istifadəçi üçün heç bir etimadnamə tapılmadı",
|
||||
"Please call WebAuthnSigninBegin first": "Xahiş edirik əvvəlcə WebAuthnSigninBegin çağırın"
|
||||
}
|
||||
}
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "tato operace není povolena v demo režimu",
|
||||
"this operation requires administrator to perform": "tato operace vyžaduje administrátora k provedení"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server existuje"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "Dieser Vorgang ist im Demo-Modus nicht erlaubt",
|
||||
"this operation requires administrator to perform": "Dieser Vorgang erfordert einen Administrator zur Ausführung"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Es gibt einen LDAP-Server"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
|
||||
"this operation requires administrator to perform": "this operation requires administrator to perform"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "esta operación no está permitida en modo de demostración",
|
||||
"this operation requires administrator to perform": "esta operación requiere que el administrador la realice"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "El servidor LDAP existe"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "این عملیات در حالت دمو مجاز نیست",
|
||||
"this operation requires administrator to perform": "این عملیات نیاز به مدیر برای انجام دارد"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "سرور LDAP وجود دارد"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "tämä toiminto ei ole sallittu demo-tilassa",
|
||||
"this operation requires administrator to perform": "tämä toiminto vaatii ylläpitäjän suorittamista"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP-palvelin on olemassa"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "cette opération n'est pas autorisée en mode démo",
|
||||
"this operation requires administrator to perform": "cette opération nécessite un administrateur pour être effectuée"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Le serveur LDAP existe"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "פעולה זו אינה מותרת במצב הדגמה",
|
||||
"this operation requires administrator to perform": "פעולה זו דורשת מנהל לביצוע"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "שרת LDAP קיים"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "operasi ini tidak diizinkan dalam mode demo",
|
||||
"this operation requires administrator to perform": "operasi ini memerlukan administrator untuk melakukannya"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Server ldap ada"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "questa operazione non è consentita in modalità demo",
|
||||
"this operation requires administrator to perform": "questa operazione richiede un amministratore"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Server LDAP esistente"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "この操作はデモモードでは許可されていません",
|
||||
"this operation requires administrator to perform": "この操作は管理者権限が必要です"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAPサーバーは存在します"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "deze handeling is niet toegestaan in demo-modus",
|
||||
"this operation requires administrator to perform": "deze handeling vereist beheerder"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP-server bestaat al"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "이 작업은 데모 모드에서 허용되지 않습니다",
|
||||
"this operation requires administrator to perform": "이 작업은 관리자 권한이 필요합니다"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP 서버가 존재합니다"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "operasi ini tidak dibenarkan dalam mod demo",
|
||||
"this operation requires administrator to perform": "operasi ini perlukan pentadbir untuk jalankan"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Pelayan LDAP sudah wujud"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "Handeling niet toegestaan in demo-modus",
|
||||
"this operation requires administrator to perform": "Alleen beheerder kan deze handeling uitvoeren"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP-server bestaat al"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "ta operacja nie jest dozwolona w trybie demo",
|
||||
"this operation requires administrator to perform": "ta operacja wymaga administratora do wykonania"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Serwer LDAP istnieje"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "esta operação não é permitida no modo de demonstração",
|
||||
"this operation requires administrator to perform": "esta operação requer um administrador para executar"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Servidor LDAP existe"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "эта операция недоступна в демонстрационном режиме",
|
||||
"this operation requires administrator to perform": "эта операция требует прав администратора"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP-сервер существует"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "táto operácia nie je povolená v demo režime",
|
||||
"this operation requires administrator to perform": "táto operácia vyžaduje vykonanie administrátorom"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP server existuje"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "denna åtgärd är inte tillåten i demoläge",
|
||||
"this operation requires administrator to perform": "denna åtgärd kräver administratör för att genomföras"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP-servern finns redan"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "bu işlem demo modunda izin verilmiyor",
|
||||
"this operation requires administrator to perform": "bu işlem yönetici tarafından gerçekleştirilmelidir"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP sunucusu zaten var"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "ця операція недоступна в демо-режимі",
|
||||
"this operation requires administrator to perform": "ця операція потребує прав адміністратора"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Сервер LDAP існує"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "thao tác này không được phép trong chế độ demo",
|
||||
"this operation requires administrator to perform": "thao tác này yêu cầu quản trị viên thực hiện"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "Invitation %s does not exist"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Máy chủ LDAP tồn tại"
|
||||
},
|
||||
|
@@ -106,6 +106,9 @@
|
||||
"this operation is not allowed in demo mode": "demo模式下不允许该操作",
|
||||
"this operation requires administrator to perform": "只有管理员才能进行此操作"
|
||||
},
|
||||
"invitation": {
|
||||
"Invitation %s does not exist": "邀请%s不存在"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP服务器已存在"
|
||||
},
|
||||
|
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@@ -64,6 +65,25 @@ func (idp *CustomIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
return idp.Config.Exchange(ctx, code)
|
||||
}
|
||||
|
||||
func getNestedValue(data map[string]interface{}, path string) (interface{}, error) {
|
||||
keys := strings.Split(path, ".")
|
||||
var val interface{} = data
|
||||
|
||||
for _, key := range keys {
|
||||
m, ok := val.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("path '%s' is not valid: %s is not a map", path, key)
|
||||
}
|
||||
|
||||
val, ok = m[key]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("key '%s' not found in path '%s'", key, path)
|
||||
}
|
||||
}
|
||||
|
||||
return val, nil
|
||||
}
|
||||
|
||||
type CustomUserInfo struct {
|
||||
Id string `mapstructure:"id"`
|
||||
Username string `mapstructure:"username"`
|
||||
@@ -108,11 +128,11 @@ func (idp *CustomIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
|
||||
// map user info
|
||||
for k, v := range idp.UserMapping {
|
||||
_, ok := dataMap[v]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot find %s in user from custom provider", v)
|
||||
val, err := getNestedValue(dataMap, v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot find %s in user from custom provider: %v", v, err)
|
||||
}
|
||||
dataMap[k] = dataMap[v]
|
||||
dataMap[k] = val
|
||||
}
|
||||
|
||||
// try to parse id to string
|
||||
|
@@ -17,7 +17,6 @@ package idp
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -29,7 +28,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/skip2/go-qrcode"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
@@ -324,10 +322,7 @@ func GetWechatOfficialAccountQRCode(clientId string, clientSecret string, provid
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
var png []byte
|
||||
png, err = qrcode.Encode(data.URL, qrcode.Medium, 256)
|
||||
base64Image := base64.StdEncoding.EncodeToString(png)
|
||||
return base64Image, data.Ticket, nil
|
||||
return data.URL, data.Ticket, nil
|
||||
}
|
||||
|
||||
func VerifyWechatSignature(token string, nonce string, timestamp string, signature string) bool {
|
||||
|
@@ -37,7 +37,8 @@
|
||||
"UA",
|
||||
"KZ",
|
||||
"CZ",
|
||||
"SK"
|
||||
"SK",
|
||||
"AZ"
|
||||
],
|
||||
"defaultAvatar": "",
|
||||
"defaultApplication": "",
|
||||
@@ -66,7 +67,8 @@
|
||||
"kk",
|
||||
"fa",
|
||||
"cs",
|
||||
"sk"
|
||||
"sk",
|
||||
"az"
|
||||
],
|
||||
"masterPassword": "",
|
||||
"defaultPassword": "",
|
||||
|
@@ -67,6 +67,7 @@ type Application struct {
|
||||
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
Logo string `xorm:"varchar(200)" json:"logo"`
|
||||
Order int `json:"order"`
|
||||
HomepageUrl string `xorm:"varchar(100)" json:"homepageUrl"`
|
||||
Description string `xorm:"varchar(100)" json:"description"`
|
||||
Organization string `xorm:"varchar(100)" json:"organization"`
|
||||
|
@@ -30,7 +30,7 @@ func TestSmtpServer(provider *Provider) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func SendEmail(provider *Provider, title string, content string, dest string, sender string) 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)
|
||||
|
||||
fromAddress := provider.ClientId2
|
||||
|
@@ -16,6 +16,7 @@ package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@@ -206,6 +207,13 @@ func GetPolicies(id string) ([]*xormadapter.CasbinRule, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// Filter represents filter criteria with optional policy type
|
||||
type Filter struct {
|
||||
Ptype string `json:"ptype,omitempty"`
|
||||
FieldIndex *int `json:"fieldIndex,omitempty"`
|
||||
FieldValues []string `json:"fieldValues"`
|
||||
}
|
||||
|
||||
func GetFilteredPolicies(id string, ptype string, fieldIndex int, fieldValues ...string) ([]*xormadapter.CasbinRule, error) {
|
||||
enforcer, err := GetInitializedEnforcer(id)
|
||||
if err != nil {
|
||||
@@ -236,6 +244,78 @@ func GetFilteredPolicies(id string, ptype string, fieldIndex int, fieldValues ..
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// GetFilteredPoliciesMulti applies multiple filters to policies
|
||||
// Doing this in our loop is more efficient than using GetFilteredGroupingPolicy / GetFilteredPolicy which
|
||||
// iterates over all policies again and again
|
||||
func GetFilteredPoliciesMulti(id string, filters []Filter) ([]*xormadapter.CasbinRule, error) {
|
||||
// Get all policies first
|
||||
allPolicies, err := GetPolicies(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Filter policies based on multiple criteria
|
||||
var filteredPolicies []*xormadapter.CasbinRule
|
||||
if len(filters) == 0 {
|
||||
// No filters, return all policies
|
||||
return allPolicies, nil
|
||||
} else {
|
||||
for _, policy := range allPolicies {
|
||||
matchesAllFilters := true
|
||||
for _, filter := range filters {
|
||||
// Default policy type if unspecified
|
||||
if filter.Ptype == "" {
|
||||
filter.Ptype = "p"
|
||||
}
|
||||
// Always check policy type
|
||||
if policy.Ptype != filter.Ptype {
|
||||
matchesAllFilters = false
|
||||
break
|
||||
}
|
||||
|
||||
// If FieldIndex is nil, only filter via ptype (skip field-value checks)
|
||||
if filter.FieldIndex == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldIndex := *filter.FieldIndex
|
||||
// If FieldIndex is out of range, also only filter via ptype
|
||||
if fieldIndex < 0 || fieldIndex > 5 {
|
||||
continue
|
||||
}
|
||||
|
||||
var fieldValue string
|
||||
switch fieldIndex {
|
||||
case 0:
|
||||
fieldValue = policy.V0
|
||||
case 1:
|
||||
fieldValue = policy.V1
|
||||
case 2:
|
||||
fieldValue = policy.V2
|
||||
case 3:
|
||||
fieldValue = policy.V3
|
||||
case 4:
|
||||
fieldValue = policy.V4
|
||||
case 5:
|
||||
fieldValue = policy.V5
|
||||
}
|
||||
|
||||
// When FieldIndex is provided and valid, enforce FieldValues (if any)
|
||||
if len(filter.FieldValues) > 0 && !slices.Contains(filter.FieldValues, fieldValue) {
|
||||
matchesAllFilters = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if matchesAllFilters {
|
||||
filteredPolicies = append(filteredPolicies, policy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filteredPolicies, nil
|
||||
}
|
||||
|
||||
func UpdatePolicy(id string, ptype string, oldPolicy []string, newPolicy []string) (bool, error) {
|
||||
enforcer, err := GetInitializedEnforcer(id)
|
||||
if err != nil {
|
||||
|
@@ -235,3 +235,8 @@ func (invitation *Invitation) IsInvitationCodeValid(application *Application, in
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (invitation *Invitation) GetInvitationLink(host string, application string) string {
|
||||
frontEnd, _ := getOriginFromHost(host)
|
||||
return fmt.Sprintf("%s/signup/%s?invitationCode=%s", frontEnd, application, invitation.Code)
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ type Ldap struct {
|
||||
AllowSelfSignedCert bool `xorm:"bool" json:"allowSelfSignedCert"`
|
||||
Username string `xorm:"varchar(100)" json:"username"`
|
||||
Password string `xorm:"varchar(100)" json:"password"`
|
||||
BaseDn string `xorm:"varchar(100)" json:"baseDn"`
|
||||
BaseDn string `xorm:"varchar(500)" json:"baseDn"`
|
||||
Filter string `xorm:"varchar(200)" json:"filter"`
|
||||
FilterFields []string `xorm:"varchar(100)" json:"filterFields"`
|
||||
DefaultGroup string `xorm:"varchar(100)" json:"defaultGroup"`
|
||||
|
@@ -125,10 +125,10 @@ func getPolicies(permission *Permission) [][]string {
|
||||
for _, action := range permission.Actions {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
policies = append(policies, []string{userOrRole, domain, resource, strings.ToLower(action), strings.ToLower(permission.Effect), permissionId})
|
||||
policies = append(policies, []string{userOrRole, domain, resource, action, strings.ToLower(permission.Effect), permissionId})
|
||||
}
|
||||
} else {
|
||||
policies = append(policies, []string{userOrRole, resource, strings.ToLower(action), strings.ToLower(permission.Effect), "", permissionId})
|
||||
policies = append(policies, []string{userOrRole, resource, action, strings.ToLower(permission.Effect), "", permissionId})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,9 +31,11 @@ func GetDirectResources(owner string, user string, provider *Provider, prefix st
|
||||
fullPathPrefix := util.UrlJoin(provider.PathPrefix, prefix)
|
||||
objects, err := storageProvider.List(fullPathPrefix)
|
||||
for _, obj := range objects {
|
||||
name := strings.TrimPrefix(obj.Path, "/")
|
||||
name = strings.TrimPrefix(name, provider.PathPrefix+"/")
|
||||
resource := &Resource{
|
||||
Owner: owner,
|
||||
Name: strings.TrimPrefix(obj.Path, "/"),
|
||||
Name: name,
|
||||
CreatedTime: obj.LastModified.Local().Format(time.RFC3339),
|
||||
User: user,
|
||||
Provider: "",
|
||||
|
@@ -510,6 +510,8 @@ func GetUserByPhone(owner string, phone string) (*User, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
phone = util.GetSeperatedPhone(phone)
|
||||
|
||||
user := User{Owner: owner, Phone: phone}
|
||||
existed, err := ormer.Engine.Get(&user)
|
||||
if err != nil {
|
||||
@@ -528,6 +530,8 @@ func GetUserByPhoneOnly(phone string) (*User, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
phone = util.GetSeperatedPhone(phone)
|
||||
|
||||
user := User{Phone: phone}
|
||||
existed, err := ormer.Engine.Get(&user)
|
||||
if err != nil {
|
||||
|
@@ -80,7 +80,8 @@ func GetUserByFields(organization string, field string) (*User, error) {
|
||||
}
|
||||
|
||||
// check phone
|
||||
user, err = GetUserByField(organization, "phone", field)
|
||||
phone := util.GetSeperatedPhone(field)
|
||||
user, err = GetUserByField(organization, "phone", phone)
|
||||
if user != nil || err != nil {
|
||||
return user, err
|
||||
}
|
||||
|
@@ -129,7 +129,7 @@ func SendVerificationCodeToEmail(organization *Organization, user *User, provide
|
||||
return err
|
||||
}
|
||||
|
||||
err = SendEmail(provider, title, content, dest, sender)
|
||||
err = SendEmail(provider, title, content, []string{dest}, sender)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -91,7 +91,7 @@ func getObject(ctx *context.Context) (string, string, error) {
|
||||
|
||||
return "", "", nil
|
||||
} else {
|
||||
if path == "/api/add-policy" || path == "/api/remove-policy" || path == "/api/update-policy" {
|
||||
if path == "/api/add-policy" || path == "/api/remove-policy" || path == "/api/update-policy" || path == "/api/send-invitation" {
|
||||
id := ctx.Input.Query("id")
|
||||
if id != "" {
|
||||
return util.GetOwnerAndNameFromIdWithError(id)
|
||||
|
@@ -102,7 +102,12 @@ func AutoSigninFilter(ctx *context.Context) {
|
||||
userId = ctx.Input.Query("username")
|
||||
password := ctx.Input.Query("password")
|
||||
if userId != "" && password != "" && ctx.Input.Query("grant_type") == "" {
|
||||
owner, name := util.GetOwnerAndNameFromId(userId)
|
||||
owner, name, err := util.GetOwnerAndNameFromIdWithError(userId)
|
||||
if err != nil {
|
||||
responseError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
_, err = object.CheckUserPassword(owner, name, password, "en")
|
||||
if err != nil {
|
||||
responseError(ctx, err.Error())
|
||||
|
@@ -102,6 +102,7 @@ func initAPI() {
|
||||
beego.Router("/api/add-invitation", &controllers.ApiController{}, "POST:AddInvitation")
|
||||
beego.Router("/api/delete-invitation", &controllers.ApiController{}, "POST:DeleteInvitation")
|
||||
beego.Router("/api/verify-invitation", &controllers.ApiController{}, "GET:VerifyInvitation")
|
||||
beego.Router("/api/send-invitation", &controllers.ApiController{}, "POST:SendInvitation")
|
||||
|
||||
beego.Router("/api/get-applications", &controllers.ApiController{}, "GET:GetApplications")
|
||||
beego.Router("/api/get-application", &controllers.ApiController{}, "GET:GetApplication")
|
||||
@@ -160,7 +161,7 @@ func initAPI() {
|
||||
beego.Router("/api/add-adapter", &controllers.ApiController{}, "POST:AddAdapter")
|
||||
beego.Router("/api/delete-adapter", &controllers.ApiController{}, "POST:DeleteAdapter")
|
||||
beego.Router("/api/get-policies", &controllers.ApiController{}, "GET:GetPolicies")
|
||||
beego.Router("/api/get-filtered-policies", &controllers.ApiController{}, "GET:GetFilteredPolicies")
|
||||
beego.Router("/api/get-filtered-policies", &controllers.ApiController{}, "POST:GetFilteredPolicies")
|
||||
beego.Router("/api/update-policy", &controllers.ApiController{}, "POST:UpdatePolicy")
|
||||
beego.Router("/api/add-policy", &controllers.ApiController{}, "POST:AddPolicy")
|
||||
beego.Router("/api/remove-policy", &controllers.ApiController{}, "POST:RemovePolicy")
|
||||
|
@@ -30,6 +30,7 @@ import (
|
||||
"unicode"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/nyaruka/phonenumbers"
|
||||
)
|
||||
|
||||
func ParseInt(s string) int {
|
||||
@@ -278,6 +279,19 @@ func GetMaskedPhone(phone string) string {
|
||||
return rePhone.ReplaceAllString(phone, "$1****$2")
|
||||
}
|
||||
|
||||
func GetSeperatedPhone(phone string) string {
|
||||
if strings.HasPrefix(phone, "+") {
|
||||
phoneNumberParsed, err := phonenumbers.Parse(phone, "")
|
||||
if err != nil {
|
||||
return phone
|
||||
}
|
||||
|
||||
phone = fmt.Sprintf("%d", phoneNumberParsed.GetNationalNumber())
|
||||
}
|
||||
|
||||
return phone
|
||||
}
|
||||
|
||||
func GetMaskedEmail(email string) string {
|
||||
if email == "" {
|
||||
return ""
|
||||
|
@@ -19,6 +19,7 @@
|
||||
"@web3-onboard/gnosis": "^2.1.10",
|
||||
"@web3-onboard/infinity-wallet": "^2.0.4",
|
||||
"@web3-onboard/injected-wallets": "^2.10.4",
|
||||
"@web3-onboard/phantom": "^2.1.1",
|
||||
"@web3-onboard/react": "^2.8.10",
|
||||
"@web3-onboard/sequence": "^2.0.8",
|
||||
"@web3-onboard/taho": "^2.0.5",
|
||||
|
@@ -468,6 +468,16 @@ class ApplicationEditPage extends React.Component {
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("application:Order"), i18next.t("application:Order - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<InputNumber style={{width: "150px"}} value={this.state.application.order} min={0} step={1} precision={0} addonAfter="" onChange={value => {
|
||||
this.updateApplicationField("order", value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("application:Token expire"), i18next.t("application:Token expire - Tooltip"))} :
|
||||
|
@@ -113,6 +113,34 @@ class ApplicationListPage extends BaseListPage {
|
||||
});
|
||||
}
|
||||
|
||||
copyApplication(i) {
|
||||
const original = this.state.data[i];
|
||||
const randomSuffix = Setting.getRandomName();
|
||||
const newName = `${original.name}_${randomSuffix}`;
|
||||
|
||||
const copiedApplication = {
|
||||
...original,
|
||||
name: newName,
|
||||
createdTime: moment().format(),
|
||||
displayName: "Copy Application - " + newName,
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
};
|
||||
|
||||
ApplicationBackend.addApplication(copiedApplication)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.props.history.push({pathname: `/applications/${copiedApplication.organization}/${newName}`, mode: "add"});
|
||||
Setting.showMessage("success", i18next.t("general:Successfully copied"));
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to copy")}: ${res.msg}`);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
renderTable(applications) {
|
||||
const columns = [
|
||||
{
|
||||
@@ -237,12 +265,13 @@ class ApplicationListPage extends BaseListPage {
|
||||
title: i18next.t("general:Action"),
|
||||
dataIndex: "",
|
||||
key: "op",
|
||||
width: "170px",
|
||||
width: "230px",
|
||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/applications/${record.organization}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} onClick={() => this.copyApplication(index)}>{i18next.t("general:Copy")}</Button>
|
||||
<PopconfirmModal
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteApplication(index)}
|
||||
|
@@ -42,10 +42,11 @@ class BaseListPage extends React.Component {
|
||||
handleOrganizationChange = () => {
|
||||
this.setState({
|
||||
organizationName: this.props.match?.params.organizationName || Setting.getRequestOrganization(this.props.account),
|
||||
},
|
||||
() => {
|
||||
const {pagination} = this.state;
|
||||
this.fetch({pagination});
|
||||
});
|
||||
|
||||
const {pagination} = this.state;
|
||||
this.fetch({pagination});
|
||||
};
|
||||
|
||||
handleTourChange = () => {
|
||||
|
@@ -13,7 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, InputNumber, Row, Select} from "antd";
|
||||
import {Button, Card, Col, Input, InputNumber, Modal, Row, Select, Table} from "antd";
|
||||
import {CopyOutlined} from "@ant-design/icons";
|
||||
import * as InvitationBackend from "./backend/InvitationBackend";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||
@@ -36,6 +37,7 @@ class InvitationEditPage extends React.Component {
|
||||
applications: [],
|
||||
groups: [],
|
||||
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
||||
sendLoading: false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -122,6 +124,35 @@ class InvitationEditPage extends React.Component {
|
||||
Setting.showMessage("success", i18next.t("general:Copied to clipboard successfully"));
|
||||
}
|
||||
|
||||
renderSendEmailModal() {
|
||||
const emailColumns = [
|
||||
{title: "email", dataIndex: "email"},
|
||||
];
|
||||
const emails = this.state.emails?.split("\n")?.filter(email => Setting.isValidEmail(email));
|
||||
const emailData = emails?.map((email) => {return {email: email};});
|
||||
|
||||
return <Modal title={i18next.t("general:Send")}
|
||||
style={{height: "800px"}}
|
||||
open={this.state.showSendModal}
|
||||
closable
|
||||
footer={[
|
||||
<Button key={1} loading={this.state.sendLoading} type="primary"
|
||||
onClick={() => {
|
||||
this.setState({sendLoading: true});
|
||||
InvitationBackend.sendInvitation(this.state.invitation, emails).then(() => {
|
||||
this.setState({sendLoading: false});
|
||||
Setting.showMessage("success", i18next.t("general:Successfully sent"));
|
||||
}).catch(err => Setting.showMessage("success", err.message));
|
||||
}}>{i18next.t("general:Send")}</Button>,
|
||||
]}
|
||||
onCancel={() => {this.setState({showSendModal: false});}}>
|
||||
<div >
|
||||
<p>You will send invitation email to:</p>
|
||||
<Table showHeader={false} columns={emailColumns} dataSource={emailData} size={"small"}></Table>
|
||||
</div>
|
||||
</Modal>;
|
||||
}
|
||||
|
||||
renderInvitation() {
|
||||
const isCreatedByPlan = this.state.invitation.tag === "auto_created_invitation_for_plan";
|
||||
return (
|
||||
@@ -130,9 +161,6 @@ class InvitationEditPage extends React.Component {
|
||||
{this.state.mode === "add" ? i18next.t("invitation:New Invitation") : i18next.t("invitation:Edit Invitation")}
|
||||
<Button onClick={() => this.submitInvitationEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitInvitationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||
<Button style={{marginLeft: "20px"}} onClick={_ => this.copySignupLink()}>
|
||||
{i18next.t("application:Copy signup page URL")}
|
||||
</Button>
|
||||
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteInvitation()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||
</div>
|
||||
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
|
||||
@@ -192,6 +220,26 @@ class InvitationEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Button style={{marginBottom: "10px"}} type="primary" shape="round" icon={<CopyOutlined />} onClick={_ => this.copySignupLink()}>
|
||||
{i18next.t("application:Copy signup page URL")}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{i18next.t("general:Send")}
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input.TextArea autoSize={{minRows: 3, maxRows: 10}} value={this.state.emails} onChange={(value) => {
|
||||
this.setState({emails: value.target.value});
|
||||
}}></Input.TextArea>
|
||||
<Button type="primary" style={{marginTop: "20px"}} onClick={() => this.setState({showSendModal: true})}>{i18next.t("general:Send")}</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("invitation:Quota"), i18next.t("invitation:Quota - Tooltip"))} :
|
||||
@@ -331,15 +379,13 @@ class InvitationEditPage extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{this.state.showSendModal ? this.renderSendEmailModal() : null}
|
||||
{
|
||||
this.state.invitation !== null ? this.renderInvitation() : null
|
||||
}
|
||||
<div style={{marginTop: "20px", marginLeft: "40px"}}>
|
||||
<Button size="large" onClick={() => this.submitInvitationEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||
<Button style={{marginLeft: "20px"}} type="primary" size="large" onClick={() => this.submitInvitationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||
<Button style={{marginLeft: "20px"}} size="large" onClick={_ => this.copySignupLink()}>
|
||||
{i18next.t("application:Copy signup page URL")}
|
||||
</Button>
|
||||
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} size="large" onClick={() => this.deleteInvitation()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -174,7 +174,11 @@ class ProviderEditPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
provider.userMapping[key] = value;
|
||||
if (value === "") {
|
||||
delete provider.userMapping[key];
|
||||
} else {
|
||||
provider.userMapping[key] = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
provider: provider,
|
||||
@@ -593,6 +597,7 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("disableSsl", false);
|
||||
this.updateProviderField("title", "Casdoor Verification Code");
|
||||
this.updateProviderField("content", Setting.getDefaultHtmlEmailContent());
|
||||
this.updateProviderField("metadata", Setting.getDefaultInvitationHtmlEmailContent());
|
||||
this.updateProviderField("receiver", this.props.account.email);
|
||||
} else if (value === "SMS") {
|
||||
this.updateProviderField("type", "Twilio SMS");
|
||||
@@ -1267,6 +1272,42 @@ class ProviderEditPage extends React.Component {
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(`${i18next.t("provider:Email content")}-${i18next.t("general:Invitations")}`, i18next.t("provider:Email content - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Button style={{marginLeft: "10px", marginBottom: "5px"}} onClick={() => this.updateProviderField("metadata", "You have invited to join Casdoor. Here is your invitation code: %s, please enter in 5 minutes. Or click %link to signup")} >
|
||||
{i18next.t("provider:Reset to Default Text")}
|
||||
</Button>
|
||||
<Button style={{marginLeft: "10px", marginBottom: "5px"}} type="primary" onClick={() => this.updateProviderField("metadata", Setting.getDefaultInvitationHtmlEmailContent())} >
|
||||
{i18next.t("provider:Reset to Default HTML")}
|
||||
</Button>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={Setting.isMobile() ? 22 : 11}>
|
||||
<div style={{height: "300px", margin: "10px"}}>
|
||||
<Editor
|
||||
value={this.state.provider.metadata}
|
||||
fillHeight
|
||||
dark
|
||||
lang="html"
|
||||
onChange={value => {
|
||||
this.updateProviderField("metadata", value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={1} />
|
||||
<Col span={Setting.isMobile() ? 22 : 11}>
|
||||
<div style={{margin: "10px"}}>
|
||||
<div dangerouslySetInnerHTML={{__html: this.state.provider.metadata.replace("%code", "123456")}} />
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}}>
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Test Email"), i18next.t("provider:Test Email - Tooltip"))} :
|
||||
|
@@ -60,6 +60,7 @@ export const Countries = [
|
||||
{label: "فارسی", key: "fa", country: "IR", alt: "فارسی"},
|
||||
{label: "Čeština", key: "cs", country: "CZ", alt: "Čeština"},
|
||||
{label: "Slovenčina", key: "sk", country: "SK", alt: "Slovenčina"},
|
||||
{label: "Azərbaycan dili", key: "az", country: "AZ", alt: "Azərbaycan dili"},
|
||||
];
|
||||
|
||||
export function getThemeData(organization, application) {
|
||||
@@ -156,7 +157,7 @@ export const OtherProviderInfo = {
|
||||
url: "https://control.msg91.com/app/",
|
||||
},
|
||||
"OSON SMS": {
|
||||
logo: "https://osonsms.com/images/osonsms-logo.svg",
|
||||
logo: `${StaticBaseUrl}/img/social_osonsms.svg`,
|
||||
url: "https://osonsms.com/",
|
||||
},
|
||||
"Custom HTTP SMS": {
|
||||
@@ -204,7 +205,7 @@ export const OtherProviderInfo = {
|
||||
url: "https://aws.amazon.com/s3",
|
||||
},
|
||||
"MinIO": {
|
||||
logo: "https://min.io/resources/img/logo.svg",
|
||||
logo: `${StaticBaseUrl}/img/social_minio.png`,
|
||||
url: "https://min.io/",
|
||||
},
|
||||
"Aliyun OSS": {
|
||||
@@ -1296,6 +1297,9 @@ export function renderSignupLink(application, text) {
|
||||
} else {
|
||||
if (application.signupUrl === "") {
|
||||
url = `/signup/${application.name}`;
|
||||
if (application.isShared) {
|
||||
url = `/signup/${application.name}-org-${application.organization}`;
|
||||
}
|
||||
} else {
|
||||
url = application.signupUrl;
|
||||
}
|
||||
@@ -1644,6 +1648,48 @@ export function getDefaultHtmlEmailContent() {
|
||||
</html>`;
|
||||
}
|
||||
|
||||
export function getDefaultInvitationHtmlEmailContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Invitation Code Email</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; }
|
||||
.email-container { width: 600px; margin: 0 auto; }
|
||||
.header { text-align: center; }
|
||||
.code { font-size: 24px; margin: 20px 0; text-align: center; }
|
||||
.footer { font-size: 12px; text-align: center; margin-top: 50px; }
|
||||
.footer a { color: #000; text-decoration: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="email-container">
|
||||
<div class="header">
|
||||
<h3>Casbin Organization</h3>
|
||||
<img src="${StaticBaseUrl}/img/casdoor-logo_1185x256.png" alt="Casdoor Logo" width="300">
|
||||
</div>
|
||||
<p>You have been invited into Casdoor</p>
|
||||
<div class="code">
|
||||
%code
|
||||
</div>
|
||||
<reset-link>
|
||||
<div class="link">
|
||||
Or click this <a href="%link">link</a> to signup
|
||||
</div>
|
||||
</reset-link>
|
||||
<p>Thanks</p>
|
||||
<p>Casbin Team</p>
|
||||
<hr>
|
||||
<div class="footer">
|
||||
<p>Casdoor is a brand operated by Casbin organization. For more info please refer to <a href="https://casdoor.org">https://casdoor.org</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
export function getCurrencyText(product) {
|
||||
if (product?.currency === "USD") {
|
||||
return i18next.t("currency:USD");
|
||||
|
@@ -326,7 +326,7 @@ class UserEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} mode="multiple" style={{width: "100%"}} disabled={disabled} value={this.state.user.groups ?? []} onChange={(value => {
|
||||
if (this.state.groups?.filter(group => value.includes(group.name))
|
||||
if (this.state.groups?.filter(group => value.includes(`${group.owner}/${group.name}`))
|
||||
.filter(group => group.type === "Physical").length > 1) {
|
||||
Setting.showMessage("error", i18next.t("general:You can only select one physical group"));
|
||||
return;
|
||||
@@ -1117,6 +1117,32 @@ class UserEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
} else if (accountItem.name === "First name") {
|
||||
return (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:First name"), i18next.t("general:First name - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<Input value={this.state.user.firstName} onChange={e => {
|
||||
this.updateUserField("firstName", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
} else if (accountItem.name === "Last name") {
|
||||
return (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Last name"), i18next.t("general:Last name - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<Input value={this.state.user.lastName} onChange={e => {
|
||||
this.updateUserField("lastName", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -39,12 +39,14 @@ import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
|
||||
import * as ProviderButton from "./ProviderButton";
|
||||
import {createFormAndSubmit, goToLink} from "../Setting";
|
||||
import WeChatLoginPanel from "./WeChatLoginPanel";
|
||||
import {CountryCodeSelect} from "../common/select/CountryCodeSelect";
|
||||
const FaceRecognitionCommonModal = lazy(() => import("../common/modal/FaceRecognitionCommonModal"));
|
||||
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
|
||||
|
||||
class LoginPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.captchaRef = React.createRef();
|
||||
this.state = {
|
||||
classes: props,
|
||||
type: props.type,
|
||||
@@ -465,6 +467,7 @@ class LoginPage extends React.Component {
|
||||
login(values) {
|
||||
// here we are supposed to determine whether Casdoor is working as an OAuth server or CAS server
|
||||
values["language"] = this.state.userLang ?? "";
|
||||
const usedCaptcha = this.state.captchaValues !== undefined;
|
||||
if (this.state.type === "cas") {
|
||||
// CAS
|
||||
const casParams = Util.getCasParameters();
|
||||
@@ -491,6 +494,9 @@ class LoginPage extends React.Component {
|
||||
Setting.checkLoginMfa(res, values, casParams, loginHandler, this);
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`);
|
||||
if (usedCaptcha) {
|
||||
this.captchaRef.current?.loadCaptcha?.();
|
||||
}
|
||||
}
|
||||
}).finally(() => {
|
||||
this.setState({loginLoading: false});
|
||||
@@ -564,6 +570,9 @@ class LoginPage extends React.Component {
|
||||
Setting.checkLoginMfa(res, values, oAuthParams, loginHandler, this);
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`);
|
||||
if (usedCaptcha) {
|
||||
this.captchaRef.current?.loadCaptcha?.();
|
||||
}
|
||||
}
|
||||
}).finally(() => {
|
||||
this.setState({loginLoading: false});
|
||||
@@ -595,6 +604,32 @@ class LoginPage extends React.Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
switchLoginOrganization(name) {
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
|
||||
const clientId = searchParams.get("client_id");
|
||||
if (clientId) {
|
||||
const clientIdSplited = clientId.split("-org-");
|
||||
searchParams.set("client_id", `${clientIdSplited[0]}-org-${name}`);
|
||||
|
||||
Setting.goToLink(`/login/oauth/authorize?${searchParams.toString()}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const application = this.getApplicationObj();
|
||||
if (window.location.pathname.startsWith("/login/saml/authorize")) {
|
||||
Setting.goToLink(`/login/saml/authorize/${name}/${application.name}-org-${name}?${searchParams.toString()}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.location.pathname.startsWith("/cas")) {
|
||||
Setting.goToLink(`/cas/${application.name}-org-${name}/${name}/login?${searchParams.toString()}`);
|
||||
return;
|
||||
}
|
||||
searchParams.set("orgChoiceMode", "None");
|
||||
Setting.goToLink(`/login/${name}?${searchParams.toString()}`);
|
||||
}
|
||||
|
||||
renderFormItem(application, signinItem) {
|
||||
if (!signinItem.visible && signinItem.name !== "Forgot password?") {
|
||||
return null;
|
||||
@@ -648,6 +683,65 @@ class LoginPage extends React.Component {
|
||||
)
|
||||
;
|
||||
} else if (signinItem.name === "Username") {
|
||||
if (this.state.loginMethod === "wechat") {
|
||||
return (<WeChatLoginPanel application={application} loginMethod={this.state.loginMethod} />);
|
||||
}
|
||||
|
||||
if (this.state.loginMethod === "verificationCodePhone") {
|
||||
return <Form.Item className="signin-phone" required={true}>
|
||||
<Input.Group compact>
|
||||
<Form.Item
|
||||
name="countryCode"
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t("signup:Please select your country code!"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<CountryCodeSelect
|
||||
style={{width: "35%"}}
|
||||
countryCodes={this.getApplicationObj().organizationObj.countryCodes}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="username"
|
||||
dependencies={["countryCode"]}
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t("signup:Please input your phone number!"),
|
||||
},
|
||||
({getFieldValue}) => ({
|
||||
validator: (_, value) => {
|
||||
if (!value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (value && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
|
||||
this.setState({validEmailOrPhone: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Phone!"));
|
||||
}
|
||||
|
||||
this.setState({validEmailOrPhone: true});
|
||||
return Promise.resolve();
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
className="signup-phone-input"
|
||||
placeholder={signinItem.placeholder}
|
||||
style={{width: "65%", textAlign: "left"}}
|
||||
onChange={e => this.setState({username: e.target.value})}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Input.Group>
|
||||
</Form.Item>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={resultItemKey}>
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
@@ -750,6 +844,9 @@ class LoginPage extends React.Component {
|
||||
} else if (signinItem.name === "Agreement") {
|
||||
return AgreementModal.isAgreementRequired(application) ? AgreementModal.renderAgreementFormItem(application, true, {}, this) : null;
|
||||
} else if (signinItem.name === "Login button") {
|
||||
if (this.state.loginMethod === "wechat") {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Form.Item key={resultItemKey} className="login-button-box">
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
@@ -848,6 +945,17 @@ class LoginPage extends React.Component {
|
||||
{this.renderFooter(application, signinItem)}
|
||||
</div>
|
||||
);
|
||||
} else if (signinItem.name === "Select organization") {
|
||||
return (
|
||||
<Form.Item>
|
||||
<div key={resultItemKey} style={{width: "100%"}} className="login-organization-select">
|
||||
<OrganizationSelect style={{width: "100%"}} initValue={application.organization}
|
||||
onSelect={(value) => {
|
||||
this.switchLoginOrganization(value);
|
||||
}} />
|
||||
</div>
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,10 +1004,6 @@ class LoginPage extends React.Component {
|
||||
loginWidth += 10;
|
||||
}
|
||||
|
||||
if (this.state.loginMethod === "wechat") {
|
||||
return (<WeChatLoginPanel application={application} renderFormItem={this.renderFormItem.bind(this)} loginMethod={this.state.loginMethod} loginWidth={loginWidth} renderMethodChoiceBox={this.renderMethodChoiceBox.bind(this)} />);
|
||||
}
|
||||
|
||||
return (
|
||||
<Form
|
||||
name="normal_login"
|
||||
@@ -1028,6 +1132,7 @@ class LoginPage extends React.Component {
|
||||
}}
|
||||
onCancel={() => this.setState({openCaptchaModal: false, loginLoading: false})}
|
||||
isCurrentProvider={true}
|
||||
innerRef={this.captchaRef}
|
||||
/>;
|
||||
}
|
||||
|
||||
@@ -1083,11 +1188,13 @@ class LoginPage extends React.Component {
|
||||
{i18next.t("login:Continue with")} :
|
||||
</div>
|
||||
<br />
|
||||
<SelfLoginButton account={this.props.account} onClick={() => {
|
||||
<div onClick={() => {
|
||||
const values = {};
|
||||
values["application"] = application.name;
|
||||
this.login(values);
|
||||
}} />
|
||||
}}>
|
||||
<SelfLoginButton account={this.props.account} />
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<div style={{fontSize: 16, textAlign: "left"}}>
|
||||
@@ -1109,8 +1216,7 @@ class LoginPage extends React.Component {
|
||||
.then(res => res.json())
|
||||
.then((credentialRequestOptions) => {
|
||||
if ("status" in credentialRequestOptions) {
|
||||
Setting.showMessage("error", credentialRequestOptions.msg);
|
||||
throw credentialRequestOptions.status.msg;
|
||||
return Promise.reject(new Error(credentialRequestOptions.msg));
|
||||
}
|
||||
credentialRequestOptions.publicKey.challenge = UserWebauthnBackend.webAuthnBufferDecode(credentialRequestOptions.publicKey.challenge);
|
||||
|
||||
@@ -1169,7 +1275,7 @@ class LoginPage extends React.Component {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}${error}`);
|
||||
});
|
||||
}).catch(error => {
|
||||
Setting.showMessage("error", `${error}`);
|
||||
Setting.showMessage("error", `${error.message}`);
|
||||
}).finally(() => {
|
||||
this.setState({
|
||||
loginLoading: false,
|
||||
@@ -1240,6 +1346,7 @@ class LoginPage extends React.Component {
|
||||
[generateItemKey("WebAuthn", "None"), {label: i18next.t("login:WebAuthn"), key: "webAuthn"}],
|
||||
[generateItemKey("LDAP", "None"), {label: i18next.t("login:LDAP"), key: "ldap"}],
|
||||
[generateItemKey("Face ID", "None"), {label: i18next.t("login:Face ID"), key: "faceId"}],
|
||||
[generateItemKey("WeChat", "Tab"), {label: i18next.t("login:WeChat"), key: "wechat"}],
|
||||
[generateItemKey("WeChat", "None"), {label: i18next.t("login:WeChat"), key: "wechat"}],
|
||||
]);
|
||||
|
||||
@@ -1404,6 +1511,8 @@ class LoginPage extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
const wechatSigninMethods = application.signinMethods?.filter(method => method.name === "WeChat" && method.rule === "Login page");
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<CustomGithubCorner />
|
||||
@@ -1421,6 +1530,15 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
wechatSigninMethods?.length > 0 ? (<div style={{display: "flex", justifyContent: "center", alignItems: "center"}}>
|
||||
<div>
|
||||
<h3 style={{textAlign: "center", width: 320}}>{i18next.t("provider:Please use WeChat to scan the QR code and follow the official account for sign in")}</h3>
|
||||
<WeChatLoginPanel application={application} loginMethod={this.state.loginMethod} />
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
@@ -392,7 +392,11 @@ export function getAuthUrl(application, provider, method, code) {
|
||||
let redirectUri = `${redirectOrigin}/callback`;
|
||||
let scope = authInfo[provider.type].scope;
|
||||
const isShortState = (provider.type === "WeChat" && navigator.userAgent.includes("MicroMessenger")) || (provider.type === "Twitter");
|
||||
const state = Util.getStateFromQueryParams(application.name, provider.name, method, isShortState);
|
||||
let applicationName = application.name;
|
||||
if (application?.isShared) {
|
||||
applicationName = `${application.name}-org-${application.organization}`;
|
||||
}
|
||||
const state = Util.getStateFromQueryParams(applicationName, provider.name, method, isShortState);
|
||||
const codeChallenge = "P3S-a7dr8bgM4bF6vOyiKkKETDl16rcAzao9F8UIL1Y"; // SHA256(Base64-URL-encode("casdoor-verifier"))
|
||||
|
||||
if (provider.type === "AzureAD") {
|
||||
|
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import React, {memo} from "react";
|
||||
import {createButton} from "react-social-login-buttons";
|
||||
|
||||
class SelfLoginButton extends React.Component {
|
||||
@@ -44,4 +44,4 @@ class SelfLoginButton extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default SelfLoginButton;
|
||||
export default memo(SelfLoginButton);
|
||||
|
@@ -364,6 +364,40 @@ class SignupPage extends React.Component {
|
||||
<Input className="signup-name-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "First name" && this.state?.displayNameRule !== "First, last") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="firstName"
|
||||
className="signup-first-name"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("general:First name")}
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please input your first name!"),
|
||||
whitespace: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input className="signup-first-name-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Last name" && this.state?.displayNameRule !== "First, last") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="lastName"
|
||||
className="signup-last-name"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("general:Last name")}
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please input your last name!"),
|
||||
whitespace: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input className="signup-last-name-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Affiliation") {
|
||||
return (
|
||||
<Form.Item
|
||||
@@ -776,6 +810,12 @@ class SignupPage extends React.Component {
|
||||
this.form.current?.setFieldValue("invitationCode", this.state.invitationCode);
|
||||
}
|
||||
}
|
||||
|
||||
const displayNameItem = application.signupItems?.find(item => item.name === "Display name");
|
||||
if (displayNameItem && !this.state.displayNameRule) {
|
||||
this.setState({displayNameRule: displayNameItem.rule});
|
||||
}
|
||||
|
||||
return (
|
||||
<Form
|
||||
{...formItemLayout}
|
||||
|
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Alert, Button, Modal, Result} from "antd";
|
||||
import {Alert, Button, Modal, QRCode, Result} from "antd";
|
||||
import i18next from "i18next";
|
||||
import {getWechatMessageEvent} from "./AuthBackend";
|
||||
import * as Setting from "../Setting";
|
||||
@@ -217,7 +217,7 @@ export async function WechatOfficialAccountModal(application, provider, method)
|
||||
title: i18next.t("provider:Please use WeChat to scan the QR code and follow the official account for sign in"),
|
||||
content: (
|
||||
<div style={{marginRight: "34px"}}>
|
||||
<img src = {"data:image/png;base64," + res.data} alt="Wechat QR code" style={{width: "100%"}} />
|
||||
<QRCode style={{padding: "20px", margin: "auto"}} bordered={false} value={res.data} size={230} />
|
||||
</div>
|
||||
),
|
||||
onOk() {
|
||||
|
@@ -16,13 +16,14 @@ import React from "react";
|
||||
import * as AuthBackend from "./AuthBackend";
|
||||
import i18next from "i18next";
|
||||
import * as Util from "./Util";
|
||||
import {QRCode} from "antd";
|
||||
|
||||
class WeChatLoginPanel extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
qrCode: null,
|
||||
loading: false,
|
||||
status: "loading",
|
||||
ticket: null,
|
||||
};
|
||||
this.pollingTimer = null;
|
||||
@@ -57,47 +58,38 @@ class WeChatLoginPanel extends React.Component {
|
||||
const {application} = this.props;
|
||||
const wechatProviderItem = application?.providers?.find(p => p.provider?.type === "WeChat");
|
||||
if (wechatProviderItem) {
|
||||
this.setState({loading: true, qrCode: null, ticket: null});
|
||||
this.setState({status: "loading", qrCode: null, ticket: null});
|
||||
AuthBackend.getWechatQRCode(`${wechatProviderItem.provider.owner}/${wechatProviderItem.provider.name}`).then(res => {
|
||||
if (res.status === "ok" && res.data) {
|
||||
this.setState({qrCode: res.data, loading: false, ticket: res.data2});
|
||||
this.setState({qrCode: res.data, status: "active", ticket: res.data2});
|
||||
this.clearPolling();
|
||||
this.pollingTimer = setInterval(() => {
|
||||
Util.getEvent(application, wechatProviderItem.provider, res.data2, "signup");
|
||||
}, 1000);
|
||||
} else {
|
||||
this.setState({qrCode: null, loading: false, ticket: null});
|
||||
this.setState({qrCode: null, status: "expired", ticket: null});
|
||||
this.clearPolling();
|
||||
}
|
||||
}).catch(() => {
|
||||
this.setState({qrCode: null, loading: false, ticket: null});
|
||||
this.setState({qrCode: null, status: "expired", ticket: null});
|
||||
this.clearPolling();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {application, loginWidth = 320} = this.props;
|
||||
const {loading, qrCode} = this.state;
|
||||
const {loginWidth = 320} = this.props;
|
||||
const {status, qrCode} = this.state;
|
||||
return (
|
||||
<div style={{width: loginWidth, margin: "0 auto", textAlign: "center", marginTop: 16}}>
|
||||
{application.signinItems?.filter(item => item.name === "Logo").map(signinItem => this.props.renderFormItem(application, signinItem))}
|
||||
{this.props.renderMethodChoiceBox()}
|
||||
{application.signinItems?.filter(item => item.name === "Languages").map(signinItem => this.props.renderFormItem(application, signinItem))}
|
||||
{loading ? (
|
||||
<div style={{marginTop: 16}}>
|
||||
<span>{i18next.t("login:Loading")}</span>
|
||||
<div style={{marginTop: 2}}>
|
||||
<QRCode style={{margin: "auto", marginTop: "20px", marginBottom: "20px"}} bordered={false} status={status} value={qrCode ?? " "} size={230} />
|
||||
<div style={{marginTop: 8}}>
|
||||
<a onClick={e => {e.preventDefault(); this.fetchQrCode();}}>
|
||||
{i18next.t("login:Refresh")}
|
||||
</a>
|
||||
</div>
|
||||
) : qrCode ? (
|
||||
<div style={{marginTop: 2}}>
|
||||
<img src={`data:image/png;base64,${qrCode}`} alt="WeChat QR code" style={{width: 250, height: 250}} />
|
||||
<div style={{marginTop: 8}}>
|
||||
<a onClick={e => {e.preventDefault(); this.fetchQrCode();}}>
|
||||
{i18next.t("login:Refresh")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ import frontierModule from "@web3-onboard/frontier";
|
||||
import tahoModule from "@web3-onboard/taho";
|
||||
import coinbaseModule from "@web3-onboard/coinbase";
|
||||
import gnosisModule from "@web3-onboard/gnosis";
|
||||
import phantomModule from "@web3-onboard/phantom";
|
||||
// import keystoneModule from "@web3-onboard/keystone";
|
||||
// import keepkeyModule from "@web3-onboard/keepkey";
|
||||
// import dcentModule from "@web3-onboard/dcent";
|
||||
@@ -172,6 +173,10 @@ const web3Wallets = {
|
||||
label: "Injected",
|
||||
wallet: injectedModule(),
|
||||
},
|
||||
phantom: {
|
||||
label: "Phantom",
|
||||
wallet: phantomModule(),
|
||||
},
|
||||
// sdk wallets
|
||||
coinbase: {
|
||||
label: "Coinbase",
|
||||
@@ -296,6 +301,12 @@ export function initWeb3Onboard(application, provider) {
|
||||
label: "Arbitrum",
|
||||
rpcUrl: "https://rpc.ankr.com/arbitrum",
|
||||
},
|
||||
{
|
||||
id: "0x1",
|
||||
token: "SOL",
|
||||
label: "Solana Mainnet",
|
||||
rpcUrl: "https://api.mainnet-beta.solana.com",
|
||||
},
|
||||
];
|
||||
|
||||
const appMetadata = {
|
||||
@@ -304,6 +315,7 @@ export function initWeb3Onboard(application, provider) {
|
||||
recommendedInjectedWallets: [
|
||||
{name: "MetaMask", url: "https://metamask.io"},
|
||||
{name: "Coinbase", url: "https://www.coinbase.com/wallet"},
|
||||
{name: "Phantom", url: "https://phantom.app"},
|
||||
],
|
||||
};
|
||||
|
||||
|
@@ -89,3 +89,14 @@ export function verifyInvitation(owner, name) {
|
||||
},
|
||||
}).then(res => res.json());
|
||||
}
|
||||
|
||||
export function sendInvitation(invitation, destinations) {
|
||||
return fetch(`${Setting.ServerUrl}/api/send-invitation?id=${invitation.owner}/${encodeURIComponent(invitation.name)}`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
body: JSON.stringify(destinations),
|
||||
headers: {
|
||||
"Accept-Language": Setting.getAcceptLanguage(),
|
||||
},
|
||||
}).then(res => res.json());
|
||||
}
|
||||
|
@@ -19,13 +19,21 @@ import GridCards from "./GridCards";
|
||||
const AppListPage = (props) => {
|
||||
const [applications, setApplications] = React.useState(null);
|
||||
|
||||
const sort = (applications) => {
|
||||
applications.sort((a, b) => {
|
||||
return a.order - b.order;
|
||||
});
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (props.account === null) {
|
||||
return;
|
||||
}
|
||||
ApplicationBackend.getApplicationsByOrganization("admin", props.account.owner)
|
||||
.then((res) => {
|
||||
setApplications(res.data || []);
|
||||
const applications = res.data || [];
|
||||
sort(applications);
|
||||
setApplications(applications);
|
||||
});
|
||||
}, [props.account]);
|
||||
|
||||
|
@@ -20,7 +20,7 @@ import {CaptchaWidget} from "../CaptchaWidget";
|
||||
import {SafetyOutlined} from "@ant-design/icons";
|
||||
|
||||
export const CaptchaModal = (props) => {
|
||||
const {owner, name, visible, onOk, onUpdateToken, onCancel, isCurrentProvider, noModal} = props;
|
||||
const {owner, name, visible, onOk, onUpdateToken, onCancel, isCurrentProvider, noModal, innerRef} = props;
|
||||
|
||||
const [captchaType, setCaptchaType] = React.useState("none");
|
||||
const [clientId, setClientId] = React.useState("");
|
||||
@@ -59,6 +59,14 @@ export const CaptchaModal = (props) => {
|
||||
onCancel?.();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (innerRef) {
|
||||
innerRef.current = {
|
||||
loadCaptcha: loadCaptcha,
|
||||
};
|
||||
}
|
||||
}, [innerRef]);
|
||||
|
||||
const loadCaptcha = () => {
|
||||
UserBackend.getCaptcha(owner, name, isCurrentProvider).then((res) => {
|
||||
if (res.type === "none") {
|
||||
@@ -83,7 +91,7 @@ export const CaptchaModal = (props) => {
|
||||
const renderDefaultCaptcha = () => {
|
||||
if (noModal) {
|
||||
return (
|
||||
<Row style={{textAlign: "center"}}>
|
||||
<Row style={{textAlign: "center"}} gutter={10}>
|
||||
<Col
|
||||
style={{flex: noModal ? "70%" : "100%"}}>
|
||||
<Input
|
||||
|
@@ -133,6 +133,9 @@ function initLanguage() {
|
||||
case "sk-SK":
|
||||
language = "sk";
|
||||
break;
|
||||
case "az":
|
||||
language = "az";
|
||||
break;
|
||||
default:
|
||||
language = Conf.DefaultLanguage;
|
||||
}
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "لا توجد مصادقة",
|
||||
"Normal": "عادي",
|
||||
"Only signup": "التسجيل فقط",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "وضع اختيار المنظمة",
|
||||
"Org choice mode - Tooltip": "وضع اختيار المنظمة - تلميح",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "يرجى تشغيل \\\"جلسة الدخول\\\" أولاً قبل تشغيل \\\"الدخول التلقائي\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "إغلاق",
|
||||
"Confirm": "تأكيد",
|
||||
"Copied to clipboard successfully": "تم النسخ إلى الحافظة بنجاح",
|
||||
"Copy": "Copy",
|
||||
"Created time": "وقت الإنشاء",
|
||||
"Custom": "مخصص",
|
||||
"Dashboard": "لوحة التحكم",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "المنفذون",
|
||||
"Failed to add": "فشل الإضافة",
|
||||
"Failed to connect to server": "فشل الاتصال بالخادم",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "فشل الحذف",
|
||||
"Failed to enable": "فشل التمكين",
|
||||
"Failed to get TermsOfUse URL": "فشل الحصول على رابط شروط الاستخدام",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "الرمز المفضل",
|
||||
"Favicon - Tooltip": "رابط رمز الموقع المستخدم في جميع صفحات Casdoor الخاصة بالمنظمة",
|
||||
"First name": "الاسم الأول",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "إعادة توجيه الأصل بالقوة - تلميح",
|
||||
"Forget URL": "رابط نسيان كلمة المرور",
|
||||
"Forget URL - Tooltip": "رابط مخصص لصفحة \"نسيان كلمة المرور\". إذا لم يتم تعيينه، ستُستخدم صفحة Casdoor الافتراضية. عند التعيين، ستُعيد توجيه روابط \"نسيان كلمة المرور\" إلى هذا الرابط",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "اللغات",
|
||||
"Languages - Tooltip": "اللغات المتاحة",
|
||||
"Last name": "الاسم الأخير",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "لاحقًا",
|
||||
"Logging & Auditing": "التسجيل والمراجعة",
|
||||
"Login page": "Login page",
|
||||
"Logo": "الشعار",
|
||||
"Logo - Tooltip": "الأيقونات التي يعرضها التطبيق للعالم الخارجي",
|
||||
"Logo dark": "الشعار المظلم",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "نوع المصادقة لاتصال SSH",
|
||||
"Save": "حفظ",
|
||||
"Save & Exit": "حفظ وخروج",
|
||||
"Send": "Send",
|
||||
"Session ID": "معرف الجلسة",
|
||||
"Sessions": "الجلسات",
|
||||
"Shortcuts": "الاختصارات",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "الحالة - تلميح",
|
||||
"Subscriptions": "الاشتراكات",
|
||||
"Successfully added": "تمت الإضافة بنجاح",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "تم الحذف بنجاح",
|
||||
"Successfully removed": "تمت الإزالة بنجاح",
|
||||
"Successfully saved": "تم الحفظ بنجاح",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "مزامنة",
|
||||
"Syncers": "المزامنات",
|
||||
"System Info": "معلومات النظام",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "حدثت مشكلة أثناء تسجيل دخولك..",
|
||||
"This is a read-only demo site!": "هذا موقع تجريبي للقراءة فقط!",
|
||||
"Timestamp": "الطابع الزمني",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "يرجى كتابة منظمة لتسجيل الدخول",
|
||||
"Redirecting, please wait.": "جار إعادة التوجيه، يرجى الانتظار.",
|
||||
"Refresh": "تحديث",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "تسجيل الدخول",
|
||||
"Sign in with Face ID": "تسجيل الدخول باستخدام معرف الوجه",
|
||||
"Sign in with WebAuthn": "تسجيل الدخول باستخدام WebAuthn",
|
||||
|
1334
web/src/locales/az/data.json
Normal file
1334
web/src/locales/az/data.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -92,6 +92,8 @@
|
||||
"No verification": "Žádná verifikace",
|
||||
"Normal": "Normální",
|
||||
"Only signup": "Pouze registrace",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Režim výběru organizace",
|
||||
"Org choice mode - Tooltip": "Režim výběru organizace - popisek",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Nejprve povolte \\\"Přihlašovací relaci\\\" před povolením \\\"Automatického přihlášení\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Zavřít",
|
||||
"Confirm": "Potvrdit",
|
||||
"Copied to clipboard successfully": "Úspěšně zkopírováno do schránky",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Čas vytvoření",
|
||||
"Custom": "Vlastní",
|
||||
"Dashboard": "Hlavní obrazovka",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Vynucovače",
|
||||
"Failed to add": "Nepodařilo se přidat",
|
||||
"Failed to connect to server": "Nepodařilo se připojit k serveru",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Nepodařilo se smazat",
|
||||
"Failed to enable": "Povolení se nezdařilo",
|
||||
"Failed to get TermsOfUse URL": "Nepodařilo se získat URL podmínek použití",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Ikona webu",
|
||||
"Favicon - Tooltip": "URL ikony favicon použité na všech stránkách Casdoor organizace",
|
||||
"First name": "Křestní jméno",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Vynucený původ přesměrování - popisek",
|
||||
"Forget URL": "URL pro zapomenutí",
|
||||
"Forget URL - Tooltip": "Vlastní URL pro stránku \"Zapomenuté heslo\". Pokud není nastaveno, bude použita výchozí stránka Casdoor \"Zapomenuté heslo\". Když je nastaveno, odkaz \"Zapomenuté heslo\" na přihlašovací stránce přesměruje na tuto URL",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Jazyky",
|
||||
"Languages - Tooltip": "Dostupné jazyky",
|
||||
"Last name": "Příjmení",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Později",
|
||||
"Logging & Auditing": "Logování a audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Ikony, které aplikace prezentuje světu",
|
||||
"Logo dark": "Tmavé logo",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Typ ověření SSH připojení",
|
||||
"Save": "Uložit",
|
||||
"Save & Exit": "Uložit & Ukončit",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID relace",
|
||||
"Sessions": "Relace",
|
||||
"Shortcuts": "Zkratky",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Stav",
|
||||
"Subscriptions": "Předplatné",
|
||||
"Successfully added": "Úspěšně přidáno",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Úspěšně smazáno",
|
||||
"Successfully removed": "Úspěšně odstraněno",
|
||||
"Successfully saved": "Úspěšně uloženo",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Synchronizovat",
|
||||
"Syncers": "Synchronizátory",
|
||||
"System Info": "Systémové informace",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Při přihlašování nastal problém..",
|
||||
"This is a read-only demo site!": "Toto je demo stránka pouze pro čtení!",
|
||||
"Timestamp": "Časová značka",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Prosím zadejte organizaci pro přihlášení",
|
||||
"Redirecting, please wait.": "Přesměrování, prosím čekejte.",
|
||||
"Refresh": "Obnovit",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Přihlásit se",
|
||||
"Sign in with Face ID": "Přihlásit se pomocí Face ID",
|
||||
"Sign in with WebAuthn": "Přihlásit se pomocí WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Keine Verifizierung",
|
||||
"Normal": "Normal",
|
||||
"Only signup": "Nur Registrierung",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Organisationsauswahlmodus",
|
||||
"Org choice mode - Tooltip": "Organisationsauswahlmodus – Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Bitte aktivieren Sie zuerst \\\"Anmeldesitzung\\\", bevor Sie \\\"Automatische Anmeldung\\\" aktivieren.",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Schließen",
|
||||
"Confirm": "Bestätigen",
|
||||
"Copied to clipboard successfully": "Erfolgreich in die Zwischenablage kopiert",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Erstellte Zeit",
|
||||
"Custom": "Benutzerdefiniert",
|
||||
"Dashboard": "Dashboard",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Enforcer",
|
||||
"Failed to add": "Fehler beim hinzufügen",
|
||||
"Failed to connect to server": "Die Verbindung zum Server konnte nicht hergestellt werden",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Konnte nicht gelöscht werden",
|
||||
"Failed to enable": "Aktivierung fehlgeschlagen",
|
||||
"Failed to get TermsOfUse URL": "Fehler beim Abrufen der Nutzungsbedingungs-URL",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Favicon",
|
||||
"Favicon - Tooltip": "Favicon-URL, die auf allen Casdoor-Seiten der Organisation verwendet wird",
|
||||
"First name": "Vorname",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Erzwungene Weiterleitung – Ursprung – Tooltip",
|
||||
"Forget URL": "Passwort vergessen URL",
|
||||
"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",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Sprachen",
|
||||
"Languages - Tooltip": "Verfügbare Sprachen",
|
||||
"Last name": "Nachname",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Später",
|
||||
"Logging & Auditing": "Protokollierung & Audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Symbole, die die Anwendung der Außenwelt präsentiert",
|
||||
"Logo dark": "Dunkles Logo",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Der Authentifizierungstyp für SSH-Verbindungen",
|
||||
"Save": "Speichern",
|
||||
"Save & Exit": "Speichern und verlassen",
|
||||
"Send": "Send",
|
||||
"Session ID": "Session-ID",
|
||||
"Sessions": "Sitzungen",
|
||||
"Shortcuts": "Verknüpfungen",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Bundesland",
|
||||
"Subscriptions": "Abonnements",
|
||||
"Successfully added": "Erfolgreich hinzugefügt",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Erfolgreich gelöscht",
|
||||
"Successfully removed": "Erfolgreich entfernt",
|
||||
"Successfully saved": "Erfolgreich gespeichert",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Synchronisieren",
|
||||
"Syncers": "Syncer",
|
||||
"System Info": "Systeminformationen",
|
||||
"Tab": "Tab",
|
||||
"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!",
|
||||
"Timestamp": "Zeitstempel",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Bitte geben Sie eine Organisation zum Anmelden ein.",
|
||||
"Redirecting, please wait.": "Umleitung, bitte warten.",
|
||||
"Refresh": "Aktualisieren",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Anmelden",
|
||||
"Sign in with Face ID": "Mit Face ID anmelden",
|
||||
"Sign in with WebAuthn": "Melden Sie sich mit WebAuthn an",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "No verification",
|
||||
"Normal": "Normal",
|
||||
"Only signup": "Only signup",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "The smaller the value, the higher it ranks in the Apps page",
|
||||
"Org choice mode": "Org choice mode",
|
||||
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Close",
|
||||
"Confirm": "Confirm",
|
||||
"Copied to clipboard successfully": "Copied to clipboard successfully",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Created time",
|
||||
"Custom": "Custom",
|
||||
"Dashboard": "Dashboard",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Enforcers",
|
||||
"Failed to add": "Failed to add",
|
||||
"Failed to connect to server": "Failed to connect to server",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Failed to delete",
|
||||
"Failed to enable": "Failed to enable",
|
||||
"Failed to get TermsOfUse URL": "Failed to get TermsOfUse URL",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Favicon",
|
||||
"Favicon - Tooltip": "Favicon icon URL used in all Casdoor pages of the organization",
|
||||
"First name": "First name",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Forced redirect origin - Tooltip",
|
||||
"Forget URL": "Forget URL",
|
||||
"Forget URL - Tooltip": "Custom URL for the \"Forget password\" page. If not set, the default Casdoor \"Forget password\" page will be used. When set, the \"Forget password\" link on the login page will redirect to this URL",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Languages",
|
||||
"Languages - Tooltip": "Available languages",
|
||||
"Last name": "Last name",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logging & Auditing",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icons that the application presents to the outside world",
|
||||
"Logo dark": "Logo dark",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "The auth type of SSH connection",
|
||||
"Save": "Save",
|
||||
"Save & Exit": "Save & Exit",
|
||||
"Send": "Send",
|
||||
"Session ID": "Session ID",
|
||||
"Sessions": "Sessions",
|
||||
"Shortcuts": "Shortcuts",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "State",
|
||||
"Subscriptions": "Subscriptions",
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully removed": "Successfully removed",
|
||||
"Successfully saved": "Successfully saved",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Syncers",
|
||||
"System Info": "System Info",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "There was a problem signing you in..",
|
||||
"This is a read-only demo site!": "This is a read-only demo site!",
|
||||
"Timestamp": "Timestamp",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Please type an organization to sign in",
|
||||
"Redirecting, please wait.": "Redirecting, please wait.",
|
||||
"Refresh": "Refresh",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Sign In",
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Sin verificación",
|
||||
"Normal": "Normal",
|
||||
"Only signup": "Solo registro",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Modo de selección de organización",
|
||||
"Org choice mode - Tooltip": "Modo de selección de organización - Información adicional",
|
||||
"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\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Cerca",
|
||||
"Confirm": "Confirmar",
|
||||
"Copied to clipboard successfully": "Copiado al portapapeles exitosamente",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Tiempo creado",
|
||||
"Custom": "Personalizado",
|
||||
"Dashboard": "Panel de control",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Aplicadores",
|
||||
"Failed to add": "No se pudo agregar",
|
||||
"Failed to connect to server": "No se pudo conectar al servidor",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "No se pudo eliminar",
|
||||
"Failed to enable": "Error al habilitar",
|
||||
"Failed to get TermsOfUse URL": "Error al obtener la URL de Términos de uso",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Favicon",
|
||||
"Favicon - Tooltip": "URL del icono Favicon utilizado en todas las páginas de Casdoor de la organización",
|
||||
"First name": "Nombre de pila",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Origen de redirección forzada - Información adicional",
|
||||
"Forget URL": "Olvide la URL",
|
||||
"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",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Idiomas",
|
||||
"Languages - Tooltip": "Idiomas disponibles",
|
||||
"Last name": "Apellido",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Más tarde",
|
||||
"Logging & Auditing": "Registro y auditoría",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logotipo",
|
||||
"Logo - Tooltip": "Iconos que la aplicación presenta al mundo exterior",
|
||||
"Logo dark": "Logo oscuro",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "El tipo de autenticación de conexión SSH",
|
||||
"Save": "Guardar",
|
||||
"Save & Exit": "Guardar y salir",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID de sesión",
|
||||
"Sessions": "Sesiones",
|
||||
"Shortcuts": "Accesos directos",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Estado",
|
||||
"Subscriptions": "Suscripciones",
|
||||
"Successfully added": "Éxito al agregar",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Éxito en la eliminación",
|
||||
"Successfully removed": "Eliminado exitosamente",
|
||||
"Successfully saved": "Guardado exitosamente",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Sincronización",
|
||||
"Syncers": "Sincronizadores",
|
||||
"System Info": "Información del Sistema",
|
||||
"Tab": "Tab",
|
||||
"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!",
|
||||
"Timestamp": "Marca de tiempo",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Por favor escribe una organización para iniciar sesión",
|
||||
"Redirecting, please wait.": "Redirigiendo, por favor espera.",
|
||||
"Refresh": "Actualizar",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Iniciar sesión",
|
||||
"Sign in with Face ID": "Iniciar sesión con Face ID",
|
||||
"Sign in with WebAuthn": "Iniciar sesión con WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "بدون تأیید",
|
||||
"Normal": "عادی",
|
||||
"Only signup": "فقط ثبتنام",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "حالت انتخاب سازمان",
|
||||
"Org choice mode - Tooltip": "حالت انتخاب سازمان - راهنمای ابزار",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "لطفاً قبل فعالسازی «ورود خودکار»، ابتدا «جلسه ورود» را فعال کنید",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "بستن",
|
||||
"Confirm": "تأیید",
|
||||
"Copied to clipboard successfully": "با موفقیت در کلیپبورد کپی شد",
|
||||
"Copy": "Copy",
|
||||
"Created time": "زمان ایجاد",
|
||||
"Custom": "سفارشی",
|
||||
"Dashboard": "داشبورد",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Enforcerها",
|
||||
"Failed to add": "عدم موفقیت در افزودن",
|
||||
"Failed to connect to server": "عدم موفقیت در اتصال به سرور",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "عدم موفقیت در حذف",
|
||||
"Failed to enable": "عدم موفقیت در فعالسازی",
|
||||
"Failed to get TermsOfUse URL": "عدم موفقیت در دریافت آدرس شرایط استفاده",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "آیکون وب",
|
||||
"Favicon - Tooltip": "آدرس آیکون Favicon استفاده شده در تمام صفحات Casdoor سازمان",
|
||||
"First name": "نام",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "منبع بازگرداندن اجباری - توصیه",
|
||||
"Forget URL": "آدرس فراموشی",
|
||||
"Forget URL - Tooltip": "آدرس سفارشی برای صفحه \"فراموشی رمز عبور\". اگر تنظیم نشده باشد، صفحه پیشفرض \"فراموشی رمز عبور\" Casdoor استفاده میشود. هنگامی که تنظیم شده باشد، لینک \"فراموشی رمز عبور\" در صفحه ورود به این آدرس هدایت میشود",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "زبانها",
|
||||
"Languages - Tooltip": "زبانهای موجود",
|
||||
"Last name": "نام خانوادگی",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "بعداً",
|
||||
"Logging & Auditing": "ورود و حسابرسی",
|
||||
"Login page": "Login page",
|
||||
"Logo": "لوگو",
|
||||
"Logo - Tooltip": "آیکونهایی که برنامه به بیرون ارائه میدهد",
|
||||
"Logo dark": "لوگوی تیره",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "نوع احراز هویت اتصال SSH",
|
||||
"Save": "ذخیره",
|
||||
"Save & Exit": "ذخیره و خروج",
|
||||
"Send": "Send",
|
||||
"Session ID": "شناسه جلسه",
|
||||
"Sessions": "جلسات",
|
||||
"Shortcuts": "میانبرها",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "وضعیت",
|
||||
"Subscriptions": "اشتراکها",
|
||||
"Successfully added": "با موفقیت اضافه شد",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "با موفقیت حذف شد",
|
||||
"Successfully removed": "با موفقیت حذف شد",
|
||||
"Successfully saved": "با موفقیت ذخیره شد",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "همگامسازی",
|
||||
"Syncers": "همگامسازها",
|
||||
"System Info": "اطلاعات سیستم",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "مشکلی در ورود شما وجود داشت...",
|
||||
"This is a read-only demo site!": "این یک سایت دمو فقط خواندنی است!",
|
||||
"Timestamp": "مهر زمان",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "لطفاً یک سازمان برای ورود تایپ کنید",
|
||||
"Redirecting, please wait.": "در حال هدایت، لطفاً صبر کنید.",
|
||||
"Refresh": "به روزرسانی",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "ورود",
|
||||
"Sign in with Face ID": "ورود با شناسه چهره",
|
||||
"Sign in with WebAuthn": "ورود با WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Ei vahvistusta",
|
||||
"Normal": "Normaali",
|
||||
"Only signup": "Vain rekisteröityminen",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Organisaation valintatila",
|
||||
"Org choice mode - Tooltip": "Organisaation valintatila - työkalupala",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Ota \\\"Kirjautumisession\\\" käyttöön ennen \\\"Automaattisen kirjautumisen\\\" ottamista käyttöön",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Sulje",
|
||||
"Confirm": "Vahvista",
|
||||
"Copied to clipboard successfully": "Kopioitu leikepöydälle onnistuneesti",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Luontiaika",
|
||||
"Custom": "Mukautettu",
|
||||
"Dashboard": "Ohjauspaneeli",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Valvojat",
|
||||
"Failed to add": "Lisääminen epäonnistui",
|
||||
"Failed to connect to server": "Yhteyden muodostaminen palvelimeen epäonnistui",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Poistaminen epäonnistui",
|
||||
"Failed to enable": "Käyttöön ottaminen epäonnistui",
|
||||
"Failed to get TermsOfUse URL": "Käyttöehdot URL:n hakeminen epäonnistui",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Sivuston ikoni",
|
||||
"Favicon - Tooltip": "Favicon-kuvakkeen URL, jota käytetään kaikissa Casdoor-sivuissa organisaatiolle",
|
||||
"First name": "Etunimi",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Pakotettu uudelleenohjaus alkuperä - työkalupala",
|
||||
"Forget URL": "Unohtamisen URL",
|
||||
"Forget URL - Tooltip": "Mukautettu URL \"Unohtunut salasana\" -sivulle. Jos ei aseteta, käytetään oletusarvoista Casdoor \"Unohtunut salasana\" -sivua. Kun asetetaan, \"Unohtunut salasana\" -linkki kirjautumissivulla ohjaa tähän URL-osoitteeseen",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Kielet",
|
||||
"Languages - Tooltip": "Saatavilla olevat kielet",
|
||||
"Last name": "Sukunimi",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Myöhemmin",
|
||||
"Logging & Auditing": "Kirjaaminen ja tarkastus",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Kuvakkeet, joita sovellus esittää ulkopuolelle",
|
||||
"Logo dark": "Tumma logo",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "SSH-yhteyden todennustyyppi",
|
||||
"Save": "Tallenna",
|
||||
"Save & Exit": "Tallenna ja poistu",
|
||||
"Send": "Send",
|
||||
"Session ID": "Istunnon tunniste",
|
||||
"Sessions": "Istunnot",
|
||||
"Shortcuts": "Pikakuvakkeet",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Tila – ohje",
|
||||
"Subscriptions": "Tilaukset",
|
||||
"Successfully added": "Lisätty onnistuneesti",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Poistettu onnistuneesti",
|
||||
"Successfully removed": "Poistettu onnistuneesti",
|
||||
"Successfully saved": "Tallennettu onnistuneesti",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Synkronoi",
|
||||
"Syncers": "Synkronointitoiminnot",
|
||||
"System Info": "Järjestelmätiedot",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Kirjautumisessasi ilmeni ongelma..",
|
||||
"This is a read-only demo site!": "Tämä on vain luku -muotoinen demo-sivusto!",
|
||||
"Timestamp": "Aikaleima",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Kirjoita organisaatio kirjautumista varten",
|
||||
"Redirecting, please wait.": "Ohjataan uudelleen, odota hetki.",
|
||||
"Refresh": "Päivitä",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Kirjaudu sisään",
|
||||
"Sign in with Face ID": "Kirjaudu Face ID:llä",
|
||||
"Sign in with WebAuthn": "Kirjaudu WebAuthn-tunnisteella",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Aucune vérification",
|
||||
"Normal": "Normal",
|
||||
"Only signup": "Inscription uniquement",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Mode de choix d'organisation",
|
||||
"Org choice mode - Tooltip": "Mode de choix d'organisation - Infobulle",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Veuillez activer \\\"Session de connexion\\\" avant d'activer \\\"Connexion automatique\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Fermer",
|
||||
"Confirm": "Confirmer",
|
||||
"Copied to clipboard successfully": "Copié dans le presse-papiers avec succès",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Date de création",
|
||||
"Custom": "Personnalisé",
|
||||
"Dashboard": "Tableau de bord",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Agents",
|
||||
"Failed to add": "Échec d'ajout",
|
||||
"Failed to connect to server": "Échec de la connexion au serveur",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Échec de la suppression",
|
||||
"Failed to enable": "Échec de l'activation",
|
||||
"Failed to get TermsOfUse URL": "Échec de récupération de l'URL des conditions d'utilisation",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Favicon",
|
||||
"Favicon - Tooltip": "L'URL de l'icône « favicon » utilisée dans toutes les pages Casdoor de l'organisation",
|
||||
"First name": "Prénom",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Origine de redirection forcée - Infobulle",
|
||||
"Forget URL": "URL d'oubli",
|
||||
"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",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Langues",
|
||||
"Languages - Tooltip": "Langues disponibles",
|
||||
"Last name": "Nom de famille",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Plus tard",
|
||||
"Logging & Auditing": "Journalisation et audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icônes que l'application présente au monde extérieur",
|
||||
"Logo dark": "Logo sombre",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Type d'authentification de connexion SSH",
|
||||
"Save": "Enregistrer",
|
||||
"Save & Exit": "Enregistrer et quitter",
|
||||
"Send": "Send",
|
||||
"Session ID": "Identifiant de session",
|
||||
"Sessions": "Sessions",
|
||||
"Shortcuts": "Raccourcis",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "État",
|
||||
"Subscriptions": "Abonnements",
|
||||
"Successfully added": "Ajouté avec succès",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Supprimé avec succès",
|
||||
"Successfully removed": "Supprimé avec succès",
|
||||
"Successfully saved": "Enregistré avec succès",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Synchronisation",
|
||||
"Syncers": "Synchroniseurs",
|
||||
"System Info": "Informations système",
|
||||
"Tab": "Tab",
|
||||
"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 !",
|
||||
"Timestamp": "Horodatage",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Veuillez entrer une organisation pour vous connecter",
|
||||
"Redirecting, please wait.": "Redirection en cours, veuillez patienter.",
|
||||
"Refresh": "Actualiser",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Se connecter",
|
||||
"Sign in with Face ID": "Se connecter avec Face ID",
|
||||
"Sign in with WebAuthn": "Connectez-vous avec WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "ללא אימות",
|
||||
"Normal": "רגיל",
|
||||
"Only signup": "הרשמה בלבד",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "מצב בחירת ארגון",
|
||||
"Org choice mode - Tooltip": "מצב בחירת ארגון - תיאור",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "אנא הפעל \\\"פתיחת جلسة כניסה\\\" תחילה לפני הפעלת \\\"כניסה אוטומטית\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "סגור",
|
||||
"Confirm": "אשר",
|
||||
"Copied to clipboard successfully": "הועתק ללוח בהצלחה",
|
||||
"Copy": "Copy",
|
||||
"Created time": "זמן יצירה",
|
||||
"Custom": "מותאם אישית",
|
||||
"Dashboard": "לוח בקרה",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "מפעילים",
|
||||
"Failed to add": "הוספה נכשלה",
|
||||
"Failed to connect to server": "התחברות לשרת נכשלה",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "מחיקה נכשלה",
|
||||
"Failed to enable": "הפעלה נכשלה",
|
||||
"Failed to get TermsOfUse URL": "קבלת כתובת תנאי שימוש נכשלה",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "סמל אתר",
|
||||
"Favicon - Tooltip": "כתובת סמל Favicon המשמש בכל דפי Casdoor של הארגון",
|
||||
"First name": "שם פרטי",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "הפניה כפויה של מקור - תיאור",
|
||||
"Forget URL": "כתובת שחזור סיסמה",
|
||||
"Forget URL - Tooltip": "כתובת מותאמת אישית לדף \"שחזור סיסמה\". אם לא מוגדר, ישמש דף ברירת המחדל של Casdoor. כאשר מוגדר, קישורי \"שחזור סיסמה\" בעמוד הכניסה יופנו לכאן",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "שפות",
|
||||
"Languages - Tooltip": "שפות זמינות",
|
||||
"Last name": "שם משפחה",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "מאוחר יותר",
|
||||
"Logging & Auditing": "רישום וביקורת",
|
||||
"Login page": "Login page",
|
||||
"Logo": "לוגו",
|
||||
"Logo - Tooltip": "סמלים שהיישום מציג לעולם החיצון",
|
||||
"Logo dark": "לוגו כהה",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "סוג האימות של חיבור SSH",
|
||||
"Save": "שמור",
|
||||
"Save & Exit": "שמור וצא",
|
||||
"Send": "Send",
|
||||
"Session ID": "מזהה סשן",
|
||||
"Sessions": "סשנים",
|
||||
"Shortcuts": "קיצורי דרך",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "מצב - תיאור",
|
||||
"Subscriptions": "מנויים",
|
||||
"Successfully added": "נוסף בהצלחה",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "נמחק בהצלחה",
|
||||
"Successfully removed": "הוסר בהצלחה",
|
||||
"Successfully saved": "נשמר בהצלחה",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "סנכרן",
|
||||
"Syncers": "מסנכרנים",
|
||||
"System Info": "מידע מערכת",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "הייתה בעיה בכניסה שלך..",
|
||||
"This is a read-only demo site!": "זהו אתר הדגמה לקריאה בלבד!",
|
||||
"Timestamp": "חותמת זמן",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "אנא הקלד ארגון להתחברות",
|
||||
"Redirecting, please wait.": "מעביר, אנא המתן.",
|
||||
"Refresh": "רענן",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "התחבר",
|
||||
"Sign in with Face ID": "התחבר עם זיהוי פנים",
|
||||
"Sign in with WebAuthn": "התחבר עם WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Tidak ada verifikasi",
|
||||
"Normal": "Normal",
|
||||
"Only signup": "Hanya mendaftar",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Mode pilihan organisasi",
|
||||
"Org choice mode - Tooltip": "Mode pilihan organisasi - Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Harap aktifkan \\\"Sesi masuk\\\" terlebih dahulu sebelum mengaktifkan \\\"Masuk otomatis\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Tutup",
|
||||
"Confirm": "Konfirmasi",
|
||||
"Copied to clipboard successfully": "Berhasil disalin ke papan klip",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Waktu dibuat",
|
||||
"Custom": "Khusus",
|
||||
"Dashboard": "Dasbor",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Penegak",
|
||||
"Failed to add": "Gagal menambahkan",
|
||||
"Failed to connect to server": "Gagal terhubung ke server",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Gagal menghapus",
|
||||
"Failed to enable": "Gagal mengaktifkan",
|
||||
"Failed to get TermsOfUse URL": "Gagal mendapatkan URL Ketentuan Penggunaan",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Favicon",
|
||||
"Favicon - Tooltip": "URL ikon Favicon yang digunakan di semua halaman Casdoor organisasi",
|
||||
"First name": "Nama depan",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Asal pengalihan paksa - Tooltip",
|
||||
"Forget URL": "Lupakan URL",
|
||||
"Forget URL - Tooltip": "URL kustom untuk halaman \"Lupa kata sandi\". Jika tidak diatur, halaman \"Lupa kata sandi\" default Casdoor akan digunakan. Ketika diatur, tautan \"Lupa kata sandi\" pada halaman masuk akan diarahkan ke URL ini",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Bahasa-bahasa",
|
||||
"Languages - Tooltip": "Bahasa yang tersedia",
|
||||
"Last name": "Nama belakang",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Nanti",
|
||||
"Logging & Auditing": "Pencatatan & Audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Ikon-ikon yang disajikan aplikasi ke dunia luar",
|
||||
"Logo dark": "Logo gelap",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Tipe autentikasi koneksi SSH",
|
||||
"Save": "Menyimpan",
|
||||
"Save & Exit": "Simpan & Keluar",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID sesi",
|
||||
"Sessions": "Sesi-sesi",
|
||||
"Shortcuts": "Pintasan",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Negara",
|
||||
"Subscriptions": "Langganan",
|
||||
"Successfully added": "Berhasil ditambahkan",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Berhasil dihapus",
|
||||
"Successfully removed": "Berhasil dihapus",
|
||||
"Successfully saved": "Berhasil disimpan",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Sinkronisasi",
|
||||
"Syncers": "Sinkronisasi",
|
||||
"System Info": "Informasi Sistem",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Ada masalah saat masuk...",
|
||||
"This is a read-only demo site!": "Ini adalah situs demo hanya untuk dibaca saja!",
|
||||
"Timestamp": "Stempel waktu",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Silakan ketik organisasi untuk masuk",
|
||||
"Redirecting, please wait.": "Mengalihkan, harap tunggu.",
|
||||
"Refresh": "Segarkan",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Masuk",
|
||||
"Sign in with Face ID": "Masuk dengan Face ID",
|
||||
"Sign in with WebAuthn": "Masuk dengan WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Nessuna verifica",
|
||||
"Normal": "Normale",
|
||||
"Only signup": "Solo registrazione",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Modalità scelta organizzazione",
|
||||
"Org choice mode - Tooltip": "Modalità scelta organizzazione - Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Abilita prima \\\"Sessione di accesso\\\" prima di abilitare \\\"Accesso automatico\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Chiudi",
|
||||
"Confirm": "Conferma",
|
||||
"Copied to clipboard successfully": "Copiato negli appunti con successo",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Ora creazione",
|
||||
"Custom": "Personalizzato",
|
||||
"Dashboard": "Dashboard",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Enforcers",
|
||||
"Failed to add": "Aggiunta fallita",
|
||||
"Failed to connect to server": "Connessione al server fallita",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Eliminazione fallita",
|
||||
"Failed to enable": "Impossibile abilitare",
|
||||
"Failed to get TermsOfUse URL": "Impossibile ottenere l'URL dei Termini di utilizzo",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Favicon",
|
||||
"Favicon - Tooltip": "Icona favicon utilizzata in tutte le pagine di Casdoor dell'organizzazione",
|
||||
"First name": "Nome",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Origine reindirizzamento forzato - Tooltip",
|
||||
"Forget URL": "URL recupero",
|
||||
"Forget URL - Tooltip": "URL personalizzato per la pagina \"Recupera password\". Se non impostato, verrà utilizzata la pagina predefinita di Casdoor. Quando impostato, il link \"Recupera password\" nella pagina di accesso reindirizzerà a questo URL",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Lingue",
|
||||
"Languages - Tooltip": "Lingue disponibili",
|
||||
"Last name": "Cognome",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Più tardi",
|
||||
"Logging & Auditing": "Registrazione e audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Icone che l'applicazione presenta all'esterno",
|
||||
"Logo dark": "Logo scuro",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Tipo di autenticazione della connessione SSH",
|
||||
"Save": "Salva",
|
||||
"Save & Exit": "Salva e Esci",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID sessione",
|
||||
"Sessions": "Sessioni",
|
||||
"Shortcuts": "Scorciatoie",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Stato",
|
||||
"Subscriptions": "Abbonamenti",
|
||||
"Successfully added": "Aggiunto con successo",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Eliminato con successo",
|
||||
"Successfully removed": "Rimosso con successo",
|
||||
"Successfully saved": "Salvato con successo",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Sincronizza",
|
||||
"Syncers": "Syncers",
|
||||
"System Info": "Informazioni di sistema",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "C'è stato un problema nell'accesso...",
|
||||
"This is a read-only demo site!": "Questo è un sito demo in sola lettura!",
|
||||
"Timestamp": "Timestamp",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Digita un'organizzazione per accedere",
|
||||
"Redirecting, please wait.": "Reindirizzamento in corso, attendi.",
|
||||
"Refresh": "Aggiorna",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Accedi",
|
||||
"Sign in with Face ID": "Accedi con Face ID",
|
||||
"Sign in with WebAuthn": "Accedi con WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "検証なし",
|
||||
"Normal": "通常",
|
||||
"Only signup": "サインアップのみ",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "組織選択モード",
|
||||
"Org choice mode - Tooltip": "組織選択モード - ツールチップ",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "\\\"自動サインイン\\\"を有効にする前に、まず\\\"サインインセッション\\\"を有効にしてください",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "閉じる",
|
||||
"Confirm": "確認",
|
||||
"Copied to clipboard successfully": "クリップボードにコピーしました",
|
||||
"Copy": "Copy",
|
||||
"Created time": "作成された時間",
|
||||
"Custom": "カスタム",
|
||||
"Dashboard": "ダッシュボード",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "エンフォーサー",
|
||||
"Failed to add": "追加できませんでした",
|
||||
"Failed to connect to server": "サーバーに接続できませんでした",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "削除に失敗しました",
|
||||
"Failed to enable": "有効化に失敗しました",
|
||||
"Failed to get TermsOfUse URL": "利用規約URLの取得に失敗しました",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "ファビコン",
|
||||
"Favicon - Tooltip": "組織のすべてのCasdoorページに使用されるFaviconアイコンのURL",
|
||||
"First name": "名前",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "強制リダイレクトオリジン - ツールチップ",
|
||||
"Forget URL": "URLを忘れてください",
|
||||
"Forget URL - Tooltip": "「パスワードをお忘れの場合」ページのカスタムURL。未設定の場合、デフォルトのCasdoor「パスワードをお忘れの場合」ページが使用されます。設定された場合、ログインページの「パスワードをお忘れの場合」リンクはこのURLにリダイレクトされます",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "言語",
|
||||
"Languages - Tooltip": "利用可能な言語",
|
||||
"Last name": "苗字",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "後で",
|
||||
"Logging & Auditing": "ログと監査",
|
||||
"Login page": "Login page",
|
||||
"Logo": "ロゴ",
|
||||
"Logo - Tooltip": "アプリケーションが外部世界に示すアイコン",
|
||||
"Logo dark": "ダークロゴ",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "SSH接続の認証タイプ",
|
||||
"Save": "保存",
|
||||
"Save & Exit": "保存して終了",
|
||||
"Send": "Send",
|
||||
"Session ID": "セッションID",
|
||||
"Sessions": "セッションズ",
|
||||
"Shortcuts": "ショートカット",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "状態",
|
||||
"Subscriptions": "サブスクリプション",
|
||||
"Successfully added": "正常に追加されました",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "正常に削除されました",
|
||||
"Successfully removed": "正常に削除されました",
|
||||
"Successfully saved": "成功的に保存されました",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "同期",
|
||||
"Syncers": "同期ツール",
|
||||
"System Info": "システム情報",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "サインインに問題が発生しました...",
|
||||
"This is a read-only demo site!": "これは読み取り専用のデモサイトです!",
|
||||
"Timestamp": "タイムスタンプ",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "サインインする組織を入力してください",
|
||||
"Redirecting, please wait.": "リダイレクト中、お待ちください。",
|
||||
"Refresh": "更新",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "サインイン",
|
||||
"Sign in with Face ID": "顔IDでサインイン",
|
||||
"Sign in with WebAuthn": "WebAuthnでサインインしてください",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Тексерусіз",
|
||||
"Normal": "Қалыпты",
|
||||
"Only signup": "Тек тіркелу",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Ұйым таңдау режимі",
|
||||
"Org choice mode - Tooltip": "Ұйым таңдау режимі - Қысқаша түсінік",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Автоматты кіруді қосу алдында алдымен \\\"Кіру сессиясын\\\" қосыңыз",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Жабу",
|
||||
"Confirm": "Растау",
|
||||
"Copied to clipboard successfully": "Алмасу буферіне сәтті көшірілді",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Жасалған уақыт",
|
||||
"Custom": "Теңшеу",
|
||||
"Dashboard": "Басқару тақтасы",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Enforcer-лер",
|
||||
"Failed to add": "Қосу сәтсіз аяқталды",
|
||||
"Failed to connect to server": "Серверге қосылу сәтсіз аяқталды",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Жою сәтсіз аяқталды",
|
||||
"Failed to enable": "Қосу сәтсіз аяқталды",
|
||||
"Failed to get TermsOfUse URL": "Қолдану шарттары URL алу сәтсіз аяқталды",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Вэб-сайт иконка",
|
||||
"Favicon - Tooltip": "Ұйымның барлық Casdoor парақтарында қолданылатын favicon белгі URL",
|
||||
"First name": "Аты",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Мәжбүрлі қайта бағыттау бастапқысы - Қысқаша түсінік",
|
||||
"Forget URL": "Парольді ұмыту URL",
|
||||
"Forget URL - Tooltip": "\"Парольді ұмыту\" парағы үшін теңшеу URL. Орнатылмаған жағдайда әдепті Casdoor \"Парольді ұмыту\" парағы қолданылады. Орнатылған кезде кіру парағындағы \"Парольді ұмыту\" сілтемесі осы URL-ге қайта бағыттайды",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Тілдер",
|
||||
"Languages - Tooltip": "Қол жетімді тілдер",
|
||||
"Last name": "Тегі",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Кейінірек",
|
||||
"Logging & Auditing": "Журналдау және аудит",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Логотип",
|
||||
"Logo - Tooltip": "Қолданбаның сыртқы көріністегі белгілері",
|
||||
"Logo dark": "Қараңғы логотип",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "SSH қосылымының растау түрі",
|
||||
"Save": "Сақтау",
|
||||
"Save & Exit": "Сақтау және шығу",
|
||||
"Send": "Send",
|
||||
"Session ID": "Сессия ID",
|
||||
"Sessions": "Сессиялар",
|
||||
"Shortcuts": "Жылдам жолдар",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Күй",
|
||||
"Subscriptions": "Жазылымдар",
|
||||
"Successfully added": "Сәтті қосылды",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Сәтті жойылды",
|
||||
"Successfully removed": "Сәтті жойылды",
|
||||
"Successfully saved": "Сәтті сақталды",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Синхрондау",
|
||||
"Syncers": "Синхрондаушылар",
|
||||
"System Info": "Жүйе ақпараты",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Кіруде қиындық туындады..",
|
||||
"This is a read-only demo site!": "Бұл тек оқуға арналған демо сайт!",
|
||||
"Timestamp": "Уақыт мөрі",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Кіру үшін ұйымды енгізіңіз",
|
||||
"Redirecting, please wait.": "Қайта бағытталуда, күте тұрыңыз.",
|
||||
"Refresh": "Жаңарту",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Кіру",
|
||||
"Sign in with Face ID": "Face ID арқылы кіру",
|
||||
"Sign in with WebAuthn": "WebAuthn арқылы кіру",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "검증 없음",
|
||||
"Normal": "일반",
|
||||
"Only signup": "가입만",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "조직 선택 모드",
|
||||
"Org choice mode - Tooltip": "조직 선택 모드 - 툴팁",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "\\\"자동 로그인\\\"을 활성화하기 전에 \\\"로그인 세션\\\"을 먼저 활성화하세요.",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "닫다",
|
||||
"Confirm": "확인",
|
||||
"Copied to clipboard successfully": "클립보드에 복사되었습니다.",
|
||||
"Copy": "Copy",
|
||||
"Created time": "작성한 시간",
|
||||
"Custom": "사용자 정의",
|
||||
"Dashboard": "대시보드",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "엔포서",
|
||||
"Failed to add": "추가하지 못했습니다",
|
||||
"Failed to connect to server": "서버에 연결하지 못했습니다",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "삭제에 실패했습니다",
|
||||
"Failed to enable": "활성화 실패",
|
||||
"Failed to get TermsOfUse URL": "이용약관 URL을 가져오지 못했습니다.",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "파비콘",
|
||||
"Favicon - Tooltip": "조직의 모든 Casdoor 페이지에서 사용되는 Favicon 아이콘 URL",
|
||||
"First name": "이름",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "강제 리다이렉트 출처 - 툴팁",
|
||||
"Forget URL": "URL을 잊어버려라",
|
||||
"Forget URL - Tooltip": "\"비밀번호를 잊어버렸을 경우\" 페이지에 대한 사용자 정의 URL. 설정되지 않은 경우 기본 Casdoor \"비밀번호를 잊어버렸을 경우\" 페이지가 사용됩니다. 설정된 경우 로그인 페이지의 \"비밀번호를 잊으셨나요?\" 링크는 이 URL로 리디렉션됩니다",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "언어",
|
||||
"Languages - Tooltip": "사용 가능한 언어",
|
||||
"Last name": "성",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "나중에",
|
||||
"Logging & Auditing": "로깅 및 감사",
|
||||
"Login page": "Login page",
|
||||
"Logo": "로고",
|
||||
"Logo - Tooltip": "애플리케이션이 외부 세계에 제시하는 아이콘들",
|
||||
"Logo dark": "다크 로고",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "SSH 연결의 인증 유형",
|
||||
"Save": "저장하다",
|
||||
"Save & Exit": "저장하고 종료하기",
|
||||
"Send": "Send",
|
||||
"Session ID": "세션 ID",
|
||||
"Sessions": "세션들",
|
||||
"Shortcuts": "단축키",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "국가",
|
||||
"Subscriptions": "구독",
|
||||
"Successfully added": "성공적으로 추가되었습니다",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "성공적으로 삭제되었습니다",
|
||||
"Successfully removed": "성공적으로 제거되었습니다.",
|
||||
"Successfully saved": "성공적으로 저장되었습니다",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "싱크",
|
||||
"Syncers": "동기화 도구",
|
||||
"System Info": "시스템 정보",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "로그인하는 데 문제가 발생했습니다.",
|
||||
"This is a read-only demo site!": "이것은 읽기 전용 데모 사이트입니다!",
|
||||
"Timestamp": "타임스탬프",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "로그인할 조직을 입력하세요.",
|
||||
"Redirecting, please wait.": "리디렉팅 중입니다. 잠시 기다려주세요.",
|
||||
"Refresh": "새로 고침",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "로그인",
|
||||
"Sign in with Face ID": "얼굴 ID로 로그인",
|
||||
"Sign in with WebAuthn": "WebAuthn으로 로그인하세요",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Tiada pengesahan",
|
||||
"Normal": "Biasa",
|
||||
"Only signup": "Hanya pendaftaran",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Mod pilihan organisasi",
|
||||
"Org choice mode - Tooltip": "Mod pilihan organisasi - Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Sila dayakan \\\"Sesi log masuk\\\" terlebih dahulu sebelum mendayakan \\\"Log masuk automatik\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Tutup",
|
||||
"Confirm": "Sahkan",
|
||||
"Copied to clipboard successfully": "Berjaya disalin ke papan klip",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Masa dicipta",
|
||||
"Custom": "Tersuai",
|
||||
"Dashboard": "Papan Pemuka",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Penegak",
|
||||
"Failed to add": "Gagal untuk tambah",
|
||||
"Failed to connect to server": "Gagal untuk bersambung ke pelayan",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Gagal untuk padam",
|
||||
"Failed to enable": "Gagal untuk dayakan",
|
||||
"Failed to get TermsOfUse URL": "Gagal untuk dapatkan URL Terma Penggunaan",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Ikon Laman",
|
||||
"Favicon - Tooltip": "URL ikon favicon yang digunakan dalam semua halaman Casdoor organisasi",
|
||||
"First name": "Nama pertama",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Asal laluan paksa - Tooltip",
|
||||
"Forget URL": "URL Lupa",
|
||||
"Forget URL - Tooltip": "URL tersuai untuk halaman \"Lupa kata laluan\". Jika tidak ditetapkan, halaman lalai Casdoor \"Lupa kata laluan\" akan digunakan. Apabila ditetapkan, pautan \"Lupa kata laluan\" pada halaman log masuk akan laluan semula ke URL ini",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Bahasa",
|
||||
"Languages - Tooltip": "Bahasa yang tersedia",
|
||||
"Last name": "Nama terakhir",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Kemudian",
|
||||
"Logging & Auditing": "Log & Audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Ikon yang aplikasi paparkan ke luar",
|
||||
"Logo dark": "Logo gelap",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Jenis auth sambungan SSH",
|
||||
"Save": "Simpan",
|
||||
"Save & Exit": "Simpan & Keluar",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID Sesi",
|
||||
"Sessions": "Sesi",
|
||||
"Shortcuts": "Pintasan",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Negeri",
|
||||
"Subscriptions": "Langganan",
|
||||
"Successfully added": "Berjaya ditambah",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Berjaya dipadam",
|
||||
"Successfully removed": "Berjaya dibuang",
|
||||
"Successfully saved": "Berjaya disimpan",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Segerak",
|
||||
"Syncers": "Penyegerak",
|
||||
"System Info": "Maklumat Sistem",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Terdapat masalah untuk log masuk anda..",
|
||||
"This is a read-only demo site!": "Ini adalah tapak demo baca sahaja!",
|
||||
"Timestamp": "Cap masa",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Sila taip organisasi untuk log masuk",
|
||||
"Redirecting, please wait.": "Mengalihkan, sila tunggu.",
|
||||
"Refresh": "Segarkan",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Log Masuk",
|
||||
"Sign in with Face ID": "Log masuk dengan ID Wajah",
|
||||
"Sign in with WebAuthn": "Log masuk dengan WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Geen verificatie",
|
||||
"Normal": "Normaal",
|
||||
"Only signup": "Alleen registratie",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Organisatiekeuzemodus",
|
||||
"Org choice mode - Tooltip": "Organisatiekeuzemodus - Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Schakel eerst \\\"Aanmeldsessie\\\" in voordat je \\\"Automatische aanmelding\\\" inschakelt",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Sluiten",
|
||||
"Confirm": "Bevestigen",
|
||||
"Copied to clipboard successfully": "Succesvol gekopieerd naar klembord",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Aanmaaktijd",
|
||||
"Custom": "Aangepast",
|
||||
"Dashboard": "Dashboard",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Enforcers",
|
||||
"Failed to add": "Toevoegen mislukt",
|
||||
"Failed to connect to server": "Verbinding met server mislukt",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Verwijderen mislukt",
|
||||
"Failed to enable": "Inschakelen mislukt",
|
||||
"Failed to get TermsOfUse URL": "Ophalen van Gebruiksvoorwaarden-URL mislukt",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Favicon",
|
||||
"Favicon - Tooltip": "Favicon-pictogram-URL die op alle Casdoor-pagina's van de organisatie wordt gebruikt",
|
||||
"First name": "Voornaam",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Geforceerde omleidingsbron - Tooltip",
|
||||
"Forget URL": "Wachtwoordvergeten-URL",
|
||||
"Forget URL - Tooltip": "Aangepaste URL voor de \"Wachtwoord vergeten\"-pagina. Indien niet ingesteld, wordt de standaard Casdoor \"Wachtwoord vergeten\"-pagina gebruikt. Wanneer ingesteld, verwijst de link op de inlogpagina naar deze URL",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Talen",
|
||||
"Languages - Tooltip": "Beschikbare talen",
|
||||
"Last name": "Achternaam",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Later",
|
||||
"Logging & Auditing": "Logboekregistratie & Audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Pictogrammen die de applicatie naar buiten toe presenteert",
|
||||
"Logo dark": "Donker logo",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Het autorisatietype voor SSH-verbinding",
|
||||
"Save": "Opslaan",
|
||||
"Save & Exit": "Opslaan & Afsluiten",
|
||||
"Send": "Send",
|
||||
"Session ID": "Sessie-ID",
|
||||
"Sessions": "Sessies",
|
||||
"Shortcuts": "Snelkoppelingen",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Status",
|
||||
"Subscriptions": "Abonnementen",
|
||||
"Successfully added": "Succesvol toegevoegd",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Succesvol verwijderd",
|
||||
"Successfully removed": "Succesvol verwijderd",
|
||||
"Successfully saved": "Succesvol opgeslagen",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Synchroniseren",
|
||||
"Syncers": "Synchroniseerders",
|
||||
"System Info": "Systeeminfo",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Er was een probleem met het inloggen..",
|
||||
"This is a read-only demo site!": "Dit is een alleen-lezen demo-site!",
|
||||
"Timestamp": "Tijdstempel",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Typ een organisatie om in te loggen",
|
||||
"Redirecting, please wait.": "Doorverwijzen, even geduld...",
|
||||
"Refresh": "Vernieuwen",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Inloggen",
|
||||
"Sign in with Face ID": "Inloggen met gezichtsherkenning",
|
||||
"Sign in with WebAuthn": "Inloggen met WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Brak weryfikacji",
|
||||
"Normal": "Normalny",
|
||||
"Only signup": "Tylko rejestracja",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Tryb wyboru organizacji",
|
||||
"Org choice mode - Tooltip": "Tryb wyboru organizacji - Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Najpierw włącz \\\"sesję logowania\\\", zanim włączysz \\\"automatyczne logowanie\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Zamknij",
|
||||
"Confirm": "Potwierdź",
|
||||
"Copied to clipboard successfully": "Pomyślnie skopiowano do schowka",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Czas utworzenia",
|
||||
"Custom": "Niestandardowy",
|
||||
"Dashboard": "Panel sterowania",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Egzekutory",
|
||||
"Failed to add": "Nie udało się dodać",
|
||||
"Failed to connect to server": "Nie udało się połączyć z serwerem",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Nie udało się usunąć",
|
||||
"Failed to enable": "Nie udało się włączyć",
|
||||
"Failed to get TermsOfUse URL": "Nie udało się pobrać URL regulaminu",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Ikona strony",
|
||||
"Favicon - Tooltip": "URL ikony favicon używanej na wszystkich stronach Casdoor organizacji",
|
||||
"First name": "Imię",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Wymuszone przekierowanie źródła - Tooltip",
|
||||
"Forget URL": "URL odzyskiwania",
|
||||
"Forget URL - Tooltip": "Niestandardowy URL strony \"Odzyskaj hasło\". Jeśli nie ustawiony, zostanie użyta domyślna strona \"Odzyskaj hasło\" Casdoor. Gdy ustawiony, link \"Odzyskaj hasło\" na stronie logowania przekieruje do tego URL-a",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Języki",
|
||||
"Languages - Tooltip": "Dostępne języki",
|
||||
"Last name": "Nazwisko",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Później",
|
||||
"Logging & Auditing": "Logowanie i audyt",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Ikony, które aplikacja prezentuje na zewnątrz",
|
||||
"Logo dark": "Ciemne logo",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Typ uwierzytelniania połączenia SSH",
|
||||
"Save": "Zapisz",
|
||||
"Save & Exit": "Zapisz i wyjdź",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID sesji",
|
||||
"Sessions": "Sesje",
|
||||
"Shortcuts": "Skróty",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Stan",
|
||||
"Subscriptions": "Subskrypcje",
|
||||
"Successfully added": "Pomyślnie dodano",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Pomyślnie usunięto",
|
||||
"Successfully removed": "Pomyślnie usunięto",
|
||||
"Successfully saved": "Pomyślnie zapisano",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Synchronizuj",
|
||||
"Syncers": "Synchronizatory",
|
||||
"System Info": "Informacje o systemie",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Wystąpił problem podczas logowania..",
|
||||
"This is a read-only demo site!": "To jest tylko demonstracyjna strona tylko do odczytu!",
|
||||
"Timestamp": "Znacznik czasu",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Wpisz nazwę organizacji, aby się zalogować",
|
||||
"Redirecting, please wait.": "Przekierowywanie, proszę czekać.",
|
||||
"Refresh": "Odśwież",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Zaloguj się",
|
||||
"Sign in with Face ID": "Zaloguj się za pomocą Face ID",
|
||||
"Sign in with WebAuthn": "Zaloguj się za pomocą WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Sem verificação",
|
||||
"Normal": "Normal",
|
||||
"Only signup": "Apenas cadastro",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Modo de escolha da organização",
|
||||
"Org choice mode - Tooltip": "Dica: modo de escolha da organização",
|
||||
"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\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Fechar",
|
||||
"Confirm": "Confirmar",
|
||||
"Copied to clipboard successfully": "Copiado para a área de transferência com sucesso",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Hora de Criação",
|
||||
"Custom": "Personalizado",
|
||||
"Dashboard": "Painel",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Aplicadores",
|
||||
"Failed to add": "Falha ao adicionar",
|
||||
"Failed to connect to server": "Falha ao conectar ao servidor",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Falha ao excluir",
|
||||
"Failed to enable": "Falha ao ativar",
|
||||
"Failed to get TermsOfUse URL": "Falha ao obter URL dos Termos de Uso",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Ícone do site",
|
||||
"Favicon - Tooltip": "URL do ícone de favicon usado em todas as páginas do Casdoor da organização",
|
||||
"First name": "Nome",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Dica: origem de redirecionamento forçado",
|
||||
"Forget URL": "URL de Esqueci a Senha",
|
||||
"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",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Idiomas",
|
||||
"Languages - Tooltip": "Idiomas disponíveis",
|
||||
"Last name": "Sobrenome",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Depois",
|
||||
"Logging & Auditing": "Registro e Auditoria",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logotipo",
|
||||
"Logo - Tooltip": "Ícones que o aplicativo apresenta para o mundo externo",
|
||||
"Logo dark": "Logo escuro",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Tipo de autenticação para conexão SSH",
|
||||
"Save": "Salvar",
|
||||
"Save & Exit": "Salvar e Sair",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID da sessão",
|
||||
"Sessions": "Sessões",
|
||||
"Shortcuts": "Atalhos",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Estado",
|
||||
"Subscriptions": "Đăng ký",
|
||||
"Successfully added": "Adicionado com sucesso",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Excluído com sucesso",
|
||||
"Successfully removed": "Removido com sucesso",
|
||||
"Successfully saved": "Salvo com sucesso",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Sincronizar",
|
||||
"Syncers": "Sincronizadores",
|
||||
"System Info": "Informações do Sistema",
|
||||
"Tab": "Tab",
|
||||
"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!",
|
||||
"Timestamp": "Carimbo de data/hora",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Por favor, digite uma organização para entrar",
|
||||
"Redirecting, please wait.": "Redirecionando, por favor aguarde.",
|
||||
"Refresh": "Atualizar",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Entrar",
|
||||
"Sign in with Face ID": "Entrar com Face ID",
|
||||
"Sign in with WebAuthn": "Entrar com WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Без проверки",
|
||||
"Normal": "Обычный",
|
||||
"Only signup": "Только регистрация",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Режим выбора организации",
|
||||
"Org choice mode - Tooltip": "Подсказка: режим выбора организации",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Пожалуйста, сначала включите «Сессия входа» перед включением «Автоматического входа»",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Близко",
|
||||
"Confirm": "Подтвердить",
|
||||
"Copied to clipboard successfully": "Успешно скопировано в буфер обмена",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Созданное время",
|
||||
"Custom": "Пользовательский",
|
||||
"Dashboard": "Панель управления",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Обеспечивающие компоненты",
|
||||
"Failed to add": "Не удалось добавить",
|
||||
"Failed to connect to server": "Не удалось подключиться к серверу",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Не удалось удалить",
|
||||
"Failed to enable": "Не удалось включить",
|
||||
"Failed to get TermsOfUse URL": "Не удалось получить URL условий использования",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Фавикон",
|
||||
"Favicon - Tooltip": "URL иконки Favicon, используемый на всех страницах организации Casdoor",
|
||||
"First name": "Имя",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Подсказка: принудительный редирект origin",
|
||||
"Forget URL": "Забудьте URL",
|
||||
"Forget URL - Tooltip": "Настроенный URL для страницы \"Забыли пароль\". Если не установлено, будет использоваться стандартная страница \"Забыли пароль\" Casdoor. При установке, ссылка \"Забыли пароль\" на странице входа будет перенаправляться на этот URL",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Языки",
|
||||
"Languages - Tooltip": "Доступные языки",
|
||||
"Last name": "Фамилия",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Позже",
|
||||
"Logging & Auditing": "Логирование и аудит",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Логотип",
|
||||
"Logo - Tooltip": "Иконки, которые приложение представляет во внешний мир",
|
||||
"Logo dark": "Темный логотип",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Тип аутентификации SSH-подключения",
|
||||
"Save": "Сохранить",
|
||||
"Save & Exit": "Сохранить и выйти",
|
||||
"Send": "Send",
|
||||
"Session ID": "Идентификатор сессии",
|
||||
"Sessions": "Сессии",
|
||||
"Shortcuts": "Ярлыки",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Государство",
|
||||
"Subscriptions": "Подписки",
|
||||
"Successfully added": "Успешно добавлено",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Успешно удалено",
|
||||
"Successfully removed": "Успешно удалено",
|
||||
"Successfully saved": "Успешно сохранено",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Синхронизация",
|
||||
"Syncers": "Синхронизаторы",
|
||||
"System Info": "Системная информация",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Возникла проблема при входе...",
|
||||
"This is a read-only demo site!": "Это демонстрационный сайт только для чтения!",
|
||||
"Timestamp": "Метка времени",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Пожалуйста, введите организацию для входа",
|
||||
"Redirecting, please wait.": "Перенаправление, пожалуйста, подождите.",
|
||||
"Refresh": "Обновить",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Войти",
|
||||
"Sign in with Face ID": "Войти с Face ID",
|
||||
"Sign in with WebAuthn": "Войти с помощью WebAuthn",
|
||||
|
@@ -92,6 +92,8 @@
|
||||
"No verification": "Bez overenia",
|
||||
"Normal": "Normálny",
|
||||
"Only signup": "Len registrácia",
|
||||
"Order": "Order",
|
||||
"Order - Tooltip": "Order - Tooltip",
|
||||
"Org choice mode": "Režim výberu organizácie",
|
||||
"Org choice mode - Tooltip": "Režim výberu organizácie - Tooltip",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Najprv povoľte \\\"Reláciu prihlásenia\\\" pred povolením \\\"Automatického prihlásenia\\\"",
|
||||
@@ -258,6 +260,7 @@
|
||||
"Close": "Zavrieť",
|
||||
"Confirm": "Potvrdiť",
|
||||
"Copied to clipboard successfully": "Úspešne skopírované do schránky",
|
||||
"Copy": "Copy",
|
||||
"Created time": "Čas vytvorenia",
|
||||
"Custom": "Vlastné",
|
||||
"Dashboard": "Hlavná obrazovka",
|
||||
@@ -292,6 +295,7 @@
|
||||
"Enforcers": "Vynútitelia",
|
||||
"Failed to add": "Neúspešne pridané",
|
||||
"Failed to connect to server": "Nepodarilo sa pripojiť na server",
|
||||
"Failed to copy": "Failed to copy",
|
||||
"Failed to delete": "Neúspešne odstránené",
|
||||
"Failed to enable": "Nepodarilo sa povoliť",
|
||||
"Failed to get TermsOfUse URL": "Nepodarilo sa získať URL podmienok použitia",
|
||||
@@ -303,6 +307,7 @@
|
||||
"Favicon": "Ikona webu",
|
||||
"Favicon - Tooltip": "URL ikony favicon používaná na všetkých stránkach Casdoor organizácie",
|
||||
"First name": "Meno",
|
||||
"First name - Tooltip": "The first name of user",
|
||||
"Forced redirect origin - Tooltip": "Vynútený zdroj presmerovania - Nápoveda",
|
||||
"Forget URL": "URL zabudnutia",
|
||||
"Forget URL - Tooltip": "Vlastná URL pre stránku \"Zabudol som heslo\". Ak nie je nastavená, bude použitá predvolená stránka Casdoor \"Zabudol som heslo\". Po nastavení bude odkaz na stránke prihlásenia presmerovaný na túto URL",
|
||||
@@ -329,8 +334,10 @@
|
||||
"Languages": "Jazyky",
|
||||
"Languages - Tooltip": "Dostupné jazyky",
|
||||
"Last name": "Priezvisko",
|
||||
"Last name - Tooltip": "The last name of user",
|
||||
"Later": "Neskôr",
|
||||
"Logging & Auditing": "Zaznamenávanie a audit",
|
||||
"Login page": "Login page",
|
||||
"Logo": "Logo",
|
||||
"Logo - Tooltip": "Ikony, ktoré aplikácia prezentuje vonkajšiemu svetu",
|
||||
"Logo dark": "Tmavé logo",
|
||||
@@ -412,6 +419,7 @@
|
||||
"SSH type - Tooltip": "Typ autentifikácie SSH pripojenia",
|
||||
"Save": "Uložiť",
|
||||
"Save & Exit": "Uložiť a ukončiť",
|
||||
"Send": "Send",
|
||||
"Session ID": "ID relácie",
|
||||
"Sessions": "Relácie",
|
||||
"Shortcuts": "Skratky",
|
||||
@@ -429,6 +437,7 @@
|
||||
"State - Tooltip": "Stav",
|
||||
"Subscriptions": "Predplatné",
|
||||
"Successfully added": "Úspešne pridané",
|
||||
"Successfully copied": "Successfully copied",
|
||||
"Successfully deleted": "Úspešne odstránené",
|
||||
"Successfully removed": "Úspešne odstránené",
|
||||
"Successfully saved": "Úspešne uložené",
|
||||
@@ -443,6 +452,7 @@
|
||||
"Sync": "Synchronizovať",
|
||||
"Syncers": "Synchronizátory",
|
||||
"System Info": "Informácie o systéme",
|
||||
"Tab": "Tab",
|
||||
"There was a problem signing you in..": "Prihlásenie sa nepodarilo..",
|
||||
"This is a read-only demo site!": "Toto je stránka len na čítanie!",
|
||||
"Timestamp": "Časová značka",
|
||||
@@ -575,6 +585,7 @@
|
||||
"Please type an organization to sign in": "Zadajte organizáciu na prihlásenie",
|
||||
"Redirecting, please wait.": "Prebieha presmerovanie, prosím čakajte.",
|
||||
"Refresh": "Obnoviť",
|
||||
"Select organization": "Select organization",
|
||||
"Sign In": "Prihlásiť sa",
|
||||
"Sign in with Face ID": "Prihlásiť sa pomocou Face ID",
|
||||
"Sign in with WebAuthn": "Prihlásiť sa pomocou WebAuthn",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user