mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-14 08:03:23 +08:00
Compare commits
54 Commits
Author | SHA1 | Date | |
---|---|---|---|
3456fc6695 | |||
c302dc7b8e | |||
d24ddd4f1c | |||
572616d390 | |||
2187310dbc | |||
26345bb21b | |||
e0455df504 | |||
1dfbbf0e90 | |||
d43d58dee2 | |||
9eb4b12041 | |||
3a45a4ee77 | |||
43393f034b | |||
bafa80513b | |||
8d08140421 | |||
3d29e27d54 | |||
199f1d4d10 | |||
227e938db6 | |||
739cfd84ed | |||
8dbb041a34 | |||
af2d26daf2 | |||
90d502ab2b | |||
d51af3378e | |||
87e2b97813 | |||
d9e44c1f2d | |||
dfa4503f24 | |||
f7fb32893b | |||
66d0758b13 | |||
46ad0fe0be | |||
6b637e3b2e | |||
3354945119 | |||
19c4416f10 | |||
2077db9091 | |||
800f0ed249 | |||
6161040c67 | |||
1d785e61c6 | |||
0329d24867 | |||
fb6f3623ee | |||
eb448bd043 | |||
ea88839db9 | |||
cb95f6977a | |||
9067df92a7 | |||
bfa2ab63ad | |||
505054b0eb | |||
f95ce13b82 | |||
5315f16a48 | |||
d054f3e001 | |||
b158b840bd | |||
b16f1807b3 | |||
d0cce1bf7a | |||
9892cd20ab | |||
d1f31dd327 | |||
94743246a1 | |||
39ad1bc593 | |||
d97f833d2a |
@ -16,6 +16,7 @@ ARG USER=casdoor
|
||||
|
||||
RUN sed -i 's/https/http/' /etc/apk/repositories
|
||||
RUN apk add --update sudo
|
||||
RUN apk add tzdata
|
||||
RUN apk add curl
|
||||
RUN apk add ca-certificates && update-ca-certificates
|
||||
|
||||
|
@ -15,6 +15,7 @@ socks5Proxy = "127.0.0.1:10808"
|
||||
verificationCodeTimeout = 10
|
||||
initScore = 0
|
||||
logPostOnly = true
|
||||
isUsernameLowered = false
|
||||
origin =
|
||||
originFrontend =
|
||||
staticBaseUrl = "https://cdn.casbin.org"
|
||||
|
@ -44,6 +44,8 @@ type Response struct {
|
||||
}
|
||||
|
||||
type Captcha struct {
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
AppKey string `json:"appKey"`
|
||||
Scene string `json:"scene"`
|
||||
@ -259,19 +261,24 @@ func (c *ApiController) Signup() {
|
||||
c.SetSessionUsername(user.GetId())
|
||||
}
|
||||
|
||||
err = object.DisableVerificationCode(authForm.Email)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
if authForm.Email != "" {
|
||||
err = object.DisableVerificationCode(authForm.Email)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = object.DisableVerificationCode(checkPhone)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
if checkPhone != "" {
|
||||
err = object.DisableVerificationCode(checkPhone)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.Ctx.Input.SetParam("recordUserId", fmt.Sprintf("%s/%s", application.Organization, user.Name))
|
||||
c.Ctx.Input.SetParam("recordUserId", user.GetId())
|
||||
c.Ctx.Input.SetParam("recordSignup", "true")
|
||||
|
||||
userId := user.GetId()
|
||||
util.LogInfo(c.Ctx, "API: [%s] is signed up as new user", userId)
|
||||
@ -529,10 +536,12 @@ func (c *ApiController) GetCaptcha() {
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(Captcha{Type: captchaProvider.Type, CaptchaId: id, CaptchaImage: img})
|
||||
c.ResponseOk(Captcha{Owner: captchaProvider.Owner, Name: captchaProvider.Name, Type: captchaProvider.Type, CaptchaId: id, CaptchaImage: img})
|
||||
return
|
||||
} else if captchaProvider.Type != "" {
|
||||
c.ResponseOk(Captcha{
|
||||
Owner: captchaProvider.Owner,
|
||||
Name: captchaProvider.Name,
|
||||
Type: captchaProvider.Type,
|
||||
SubType: captchaProvider.SubType,
|
||||
ClientId: captchaProvider.ClientId,
|
||||
|
@ -73,7 +73,7 @@ func (c *ApiController) IsAdminOrSelf(user2 *object.User) bool {
|
||||
|
||||
func (c *ApiController) isGlobalAdmin() (bool, *object.User) {
|
||||
username := c.GetSessionUsername()
|
||||
if strings.HasPrefix(username, "app/") {
|
||||
if object.IsAppUser(username) {
|
||||
// e.g., "app/app-casnode"
|
||||
return true, nil
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (c *ApiController) GetCerts() {
|
||||
// GetGlobalCerts
|
||||
// @Title GetGlobalCerts
|
||||
// @Tag Cert API
|
||||
// @Description get globle certs
|
||||
// @Description get global certs
|
||||
// @Success 200 {array} object.Cert The Response object
|
||||
// @router /get-global-certs [get]
|
||||
func (c *ApiController) GetGlobalCerts() {
|
||||
|
@ -141,6 +141,20 @@ func (c *ApiController) GetProvider() {
|
||||
c.ResponseOk(object.GetMaskedProvider(provider, isMaskEnabled))
|
||||
}
|
||||
|
||||
func (c *ApiController) requireProviderPermission(provider *object.Provider) bool {
|
||||
isGlobalAdmin, user := c.isGlobalAdmin()
|
||||
if isGlobalAdmin {
|
||||
return true
|
||||
}
|
||||
|
||||
if provider.Owner == "admin" || user.Owner != provider.Owner {
|
||||
c.ResponseError(c.T("auth:Unauthorized operation"))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// UpdateProvider
|
||||
// @Title UpdateProvider
|
||||
// @Tag Provider API
|
||||
@ -159,6 +173,11 @@ func (c *ApiController) UpdateProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
ok := c.requireProviderPermission(&provider)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateProvider(id, &provider))
|
||||
c.ServeJSON()
|
||||
}
|
||||
@ -184,11 +203,17 @@ func (c *ApiController) AddProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkQuotaForProvider(int(count)); err != nil {
|
||||
err = checkQuotaForProvider(int(count))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ok := c.requireProviderPermission(&provider)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddProvider(&provider))
|
||||
c.ServeJSON()
|
||||
}
|
||||
@ -208,6 +233,11 @@ func (c *ApiController) DeleteProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
ok := c.requireProviderPermission(&provider)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteProvider(&provider))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -113,23 +113,25 @@ func (c *ApiController) SendEmail() {
|
||||
|
||||
content := emailForm.Content
|
||||
if content == "" {
|
||||
code := "123456"
|
||||
content = provider.Content
|
||||
}
|
||||
|
||||
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
|
||||
content = strings.Replace(provider.Content, "%s", code, 1)
|
||||
if !strings.HasPrefix(userId, "app/") {
|
||||
var user *object.User
|
||||
user, err = object.GetUser(userId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if user != nil {
|
||||
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
|
||||
}
|
||||
code := "123456"
|
||||
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
|
||||
content = strings.Replace(content, "%s", code, 1)
|
||||
userString := "Hi"
|
||||
if !object.IsAppUser(userId) {
|
||||
var user *object.User
|
||||
user, err = object.GetUser(userId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if user != nil {
|
||||
userString = user.GetFriendlyName()
|
||||
}
|
||||
}
|
||||
content = strings.Replace(content, "%{user.friendlyName}", userString, 1)
|
||||
|
||||
for _, receiver := range emailForm.Receivers {
|
||||
err = object.SendEmail(provider, emailForm.Title, content, receiver, emailForm.Sender)
|
||||
|
@ -164,6 +164,7 @@ func (c *ApiController) GetOAuthToken() {
|
||||
code := c.Input().Get("code")
|
||||
verifier := c.Input().Get("code_verifier")
|
||||
scope := c.Input().Get("scope")
|
||||
nonce := c.Input().Get("nonce")
|
||||
username := c.Input().Get("username")
|
||||
password := c.Input().Get("password")
|
||||
tag := c.Input().Get("tag")
|
||||
@ -197,6 +198,9 @@ func (c *ApiController) GetOAuthToken() {
|
||||
if scope == "" {
|
||||
scope = tokenRequest.Scope
|
||||
}
|
||||
if nonce == "" {
|
||||
nonce = tokenRequest.Nonce
|
||||
}
|
||||
if username == "" {
|
||||
username = tokenRequest.Username
|
||||
}
|
||||
@ -216,7 +220,7 @@ func (c *ApiController) GetOAuthToken() {
|
||||
}
|
||||
|
||||
host := c.Ctx.Request.Host
|
||||
token, err := object.GetOAuthToken(grantType, clientId, clientSecret, code, verifier, scope, username, password, host, refreshToken, tag, avatar, c.GetAcceptLanguage())
|
||||
token, err := object.GetOAuthToken(grantType, clientId, clientSecret, code, verifier, scope, nonce, username, password, host, refreshToken, tag, avatar, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
@ -21,6 +21,7 @@ type TokenRequest struct {
|
||||
Code string `json:"code"`
|
||||
Verifier string `json:"code_verifier"`
|
||||
Scope string `json:"scope"`
|
||||
Nonce string `json:"nonce"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Tag string `json:"tag"`
|
||||
|
@ -96,7 +96,7 @@ func (c *ApiController) RequireSignedInUser() (*object.User, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if strings.HasPrefix(userId, "app/") {
|
||||
if object.IsAppUser(userId) {
|
||||
tmpUserId := c.Input().Get("userId")
|
||||
if tmpUserId != "" {
|
||||
userId = tmpUserId
|
||||
@ -142,7 +142,7 @@ func (c *ApiController) IsOrgAdmin() (bool, bool) {
|
||||
return false, true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(userId, "app/") {
|
||||
if object.IsAppUser(userId) {
|
||||
return true, true
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,7 @@ func (c *ApiController) SendVerificationCode() {
|
||||
vform.CountryCode = mfaProps.CountryCode
|
||||
}
|
||||
|
||||
provider, err = application.GetSmsProvider(vform.Method)
|
||||
provider, err = application.GetSmsProvider(vform.Method, vform.CountryCode)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
@ -111,46 +111,44 @@ func newEmail(fromAddress string, toAddress string, subject string, content stri
|
||||
Subject: subject,
|
||||
HTML: content,
|
||||
},
|
||||
Importance: importanceNormal,
|
||||
Importance: importanceNormal,
|
||||
Attachments: []Attachment{},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AzureACSEmailProvider) sendEmail(e *Email) error {
|
||||
postBody, err := json.Marshal(e)
|
||||
if err != nil {
|
||||
return fmt.Errorf("email JSON marshall failed: %s", err)
|
||||
}
|
||||
func (a *AzureACSEmailProvider) Send(fromAddress string, fromName string, toAddress string, subject string, content string) error {
|
||||
email := newEmail(fromAddress, toAddress, subject, content)
|
||||
|
||||
bodyBuffer := bytes.NewBuffer(postBody)
|
||||
postBody, err := json.Marshal(email)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
endpoint := strings.TrimSuffix(a.Endpoint, "/")
|
||||
url := fmt.Sprintf("%s/emails:send?api-version=2023-03-31", endpoint)
|
||||
|
||||
bodyBuffer := bytes.NewBuffer(postBody)
|
||||
req, err := http.NewRequest("POST", url, bodyBuffer)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating AzureACS API request: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Sign the request using the AzureACS access key and HMAC-SHA256
|
||||
err = signRequestHMAC(a.AccessKey, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error signing AzureACS API request: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// Some important header
|
||||
req.Header.Set("repeatability-request-id", uuid.New().String())
|
||||
req.Header.Set("repeatability-first-sent", time.Now().UTC().Format(http.TimeFormat))
|
||||
|
||||
// Send request
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error sending AzureACS API request: %s", err)
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Response error Handling
|
||||
if resp.StatusCode == http.StatusBadRequest || resp.StatusCode == http.StatusUnauthorized {
|
||||
commError := ErrorResponse{}
|
||||
|
||||
@ -159,11 +157,11 @@ func (a *AzureACSEmailProvider) sendEmail(e *Email) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("error sending email: %s", commError.Error.Message)
|
||||
return fmt.Errorf("status code: %d, error message: %s", resp.StatusCode, commError.Error.Message)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusAccepted {
|
||||
return fmt.Errorf("error sending email: status: %d", resp.StatusCode)
|
||||
return fmt.Errorf("status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -221,9 +219,3 @@ func GetHmac(content string, key []byte) string {
|
||||
|
||||
return base64.StdEncoding.EncodeToString(hmac.Sum(nil))
|
||||
}
|
||||
|
||||
func (a *AzureACSEmailProvider) Send(fromAddress string, fromName string, toAddress string, subject string, content string) error {
|
||||
e := newEmail(fromAddress, toAddress, subject, content)
|
||||
|
||||
return a.sendEmail(e)
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ func GetEmailProvider(typ string, clientId string, clientSecret string, host str
|
||||
return NewAzureACSEmailProvider(clientSecret, host)
|
||||
} else if typ == "Custom HTTP Email" {
|
||||
return NewHttpEmailProvider(endpoint, method)
|
||||
} else if typ == "SendGrid" {
|
||||
return NewSendgridEmailProvider(clientSecret)
|
||||
} else {
|
||||
return NewSmtpEmailProvider(clientId, clientSecret, host, port, typ, disableSsl)
|
||||
}
|
||||
|
68
email/sendgrid.go
Normal file
68
email/sendgrid.go
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2024 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package email
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/sendgrid/sendgrid-go"
|
||||
"github.com/sendgrid/sendgrid-go/helpers/mail"
|
||||
)
|
||||
|
||||
type SendgridEmailProvider struct {
|
||||
ApiKey string
|
||||
}
|
||||
|
||||
type SendgridResponseBody struct {
|
||||
Errors []struct {
|
||||
Message string `json:"message"`
|
||||
Field interface{} `json:"field"`
|
||||
Help interface{} `json:"help"`
|
||||
} `json:"errors"`
|
||||
}
|
||||
|
||||
func NewSendgridEmailProvider(apiKey string) *SendgridEmailProvider {
|
||||
return &SendgridEmailProvider{ApiKey: apiKey}
|
||||
}
|
||||
|
||||
func (s *SendgridEmailProvider) Send(fromAddress string, fromName, toAddress string, subject string, content string) error {
|
||||
from := mail.NewEmail(fromName, fromAddress)
|
||||
to := mail.NewEmail("", toAddress)
|
||||
message := mail.NewSingleEmail(from, subject, to, "", content)
|
||||
client := sendgrid.NewSendClient(s.ApiKey)
|
||||
response, err := client.Send(message)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if response.StatusCode >= 300 {
|
||||
var responseBody SendgridResponseBody
|
||||
err = json.Unmarshal([]byte(response.Body), &responseBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
messages := []string{}
|
||||
for _, sendgridError := range responseBody.Errors {
|
||||
messages = append(messages, sendgridError.Message)
|
||||
}
|
||||
|
||||
return fmt.Errorf("SendGrid status code: %d, error message: %s", response.StatusCode, strings.Join(messages, " | "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
3
go.mod
3
go.mod
@ -9,7 +9,7 @@ require (
|
||||
github.com/beego/beego v1.12.12
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/casbin/casbin/v2 v2.77.2
|
||||
github.com/casdoor/go-sms-sender v0.20.0
|
||||
github.com/casdoor/go-sms-sender v0.23.0
|
||||
github.com/casdoor/gomail/v2 v2.0.1
|
||||
github.com/casdoor/notify v0.45.0
|
||||
github.com/casdoor/oss v1.6.0
|
||||
@ -45,6 +45,7 @@ require (
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/russellhaering/gosaml2 v0.9.0
|
||||
github.com/russellhaering/goxmldsig v1.2.0
|
||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed
|
||||
|
9
go.sum
9
go.sum
@ -1003,6 +1003,8 @@ github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0I
|
||||
github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
|
||||
github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg=
|
||||
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
|
||||
github.com/apistd/uni-go-sdk v0.0.2 h1:7kqETCOz/rz8AQU55XGzxDFGoFeMgeZL5fGwvxKBZrc=
|
||||
github.com/apistd/uni-go-sdk v0.0.2/go.mod h1:eIqYos4IbHgE/rB75r05ypNLahooEMJCrbjXq322b74=
|
||||
github.com/appleboy/go-fcm v0.1.5/go.mod h1:MSxZ4LqGRsnywOjnlXJXMqbjZrG4vf+0oHitfC9HRH0=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
@ -1083,8 +1085,8 @@ github.com/casbin/casbin/v2 v2.77.2 h1:yQinn/w9x8AswiwqwtrXz93VU48R1aYTXdHEx4RI3
|
||||
github.com/casbin/casbin/v2 v2.77.2/go.mod h1:mzGx0hYW9/ksOSpw3wNjk3NRAroq5VMFYUQ6G43iGPk=
|
||||
github.com/casdoor/go-reddit/v2 v2.1.0 h1:kIbfdJ7AA7H0uTQ8s0q4GGZqSS5V9wVE74RrXyD9XPs=
|
||||
github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc=
|
||||
github.com/casdoor/go-sms-sender v0.20.0 h1:yLbCakV04DzzehhgBklOrSeCFjMwpfKBeemz9b+Y8OM=
|
||||
github.com/casdoor/go-sms-sender v0.20.0/go.mod h1:cQs7qqohMJBgIVZebOCB8ko09naG1vzFJEH59VNIscs=
|
||||
github.com/casdoor/go-sms-sender v0.23.0 h1:N8+By4JNwyilEcx7cp0QGOepafefM88VwV+o3UEFZio=
|
||||
github.com/casdoor/go-sms-sender v0.23.0/go.mod h1:bOm4H8/YfJmEHjBatEVQFOnAf0OOn1B0Wi5B7zDhws0=
|
||||
github.com/casdoor/gomail/v2 v2.0.1 h1:J+FG6x80s9e5lBHUn8Sv0Y56mud34KiWih5YdmudR/w=
|
||||
github.com/casdoor/gomail/v2 v2.0.1/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q=
|
||||
github.com/casdoor/notify v0.45.0 h1:OlaFvcQFjGOgA4mRx07M8AH1gvb5xNo21mcqrVGlLgk=
|
||||
@ -1907,8 +1909,11 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
|
||||
github.com/scim2/filter-parser/v2 v2.2.0 h1:QGadEcsmypxg8gYChRSM2j1edLyE/2j72j+hdmI4BJM=
|
||||
github.com/scim2/filter-parser/v2 v2.2.0/go.mod h1:jWnkDToqX/Y0ugz0P5VvpVEUKcWcyHHj+X+je9ce5JA=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0=
|
||||
github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE=
|
||||
github.com/sendgrid/sendgrid-go v3.13.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
|
||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible h1:KDSasSTktAqMJCYClHVE94Fcif2i7P7wzISv1sU6DUA=
|
||||
github.com/sendgrid/sendgrid-go v3.14.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "Der Benutzer %s existiert nicht",
|
||||
"don't support captchaProvider: ": "Unterstütze captchaProvider nicht:",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Es gibt einen LDAP-Server"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "Der Anbieter: %s wurde nicht gefunden"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Der Code wurde noch nicht versendet!",
|
||||
"Invalid captcha provider.": "Ungültiger Captcha-Anbieter.",
|
||||
"Phone number is invalid in your region %s": "Die Telefonnummer ist in Ihrer Region %s ungültig",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing-Test fehlgeschlagen.",
|
||||
"Unable to get the email modify rule.": "Nicht in der Lage, die E-Mail-Änderungsregel zu erhalten.",
|
||||
"Unable to get the phone modify rule.": "Nicht in der Lage, die Telefon-Änderungsregel zu erhalten.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "El usuario: %s no existe",
|
||||
"don't support captchaProvider: ": "No apoyo a captchaProvider",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "El servidor LDAP existe"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "El proveedor: %s no se encuentra"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "¡El código aún no ha sido enviado!",
|
||||
"Invalid captcha provider.": "Proveedor de captcha no válido.",
|
||||
"Phone number is invalid in your region %s": "El número de teléfono es inválido en tu región %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "El test de Turing falló.",
|
||||
"Unable to get the email modify rule.": "No se puede obtener la regla de modificación de correo electrónico.",
|
||||
"Unable to get the phone modify rule.": "No se pudo obtener la regla de modificación del teléfono.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "L'utilisateur : %s n'existe pas",
|
||||
"don't support captchaProvider: ": "ne prend pas en charge captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "cette opération n’est pas autorisée en mode démo"
|
||||
"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": "this operation requires administrator to perform"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Le serveur LDAP existe"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "Le fournisseur : %s n'a pas été trouvé"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Le code n'a pas encore été envoyé !",
|
||||
"Invalid captcha provider.": "Fournisseur de captcha invalide.",
|
||||
"Phone number is invalid in your region %s": "Le numéro de téléphone n'est pas valide dans votre région %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Le test de Turing a échoué.",
|
||||
"Unable to get the email modify rule.": "Incapable d'obtenir la règle de modification de courriel.",
|
||||
"Unable to get the phone modify rule.": "Impossible d'obtenir la règle de modification de téléphone.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "Pengguna: %s tidak ada",
|
||||
"don't support captchaProvider: ": "Jangan mendukung captchaProvider:",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Server ldap ada"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "Penyedia: %s tidak ditemukan"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Kode belum dikirimkan!",
|
||||
"Invalid captcha provider.": "Penyedia captcha tidak valid.",
|
||||
"Phone number is invalid in your region %s": "Nomor telepon tidak valid di wilayah anda %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Tes Turing gagal.",
|
||||
"Unable to get the email modify rule.": "Tidak dapat memperoleh aturan modifikasi email.",
|
||||
"Unable to get the phone modify rule.": "Tidak dapat memodifikasi aturan telepon.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "そのユーザー:%sは存在しません",
|
||||
"don't support captchaProvider: ": "captchaProviderをサポートしないでください",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAPサーバーは存在します"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "プロバイダー:%sが見つかりません"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "まだコードが送信されていません!",
|
||||
"Invalid captcha provider.": "無効なCAPTCHAプロバイダー。",
|
||||
"Phone number is invalid in your region %s": "電話番号はあなたの地域で無効です %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "チューリングテストは失敗しました。",
|
||||
"Unable to get the email modify rule.": "電子メール変更規則を取得できません。",
|
||||
"Unable to get the phone modify rule.": "電話の変更ルールを取得できません。",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "사용자 %s는 존재하지 않습니다",
|
||||
"don't support captchaProvider: ": "CaptchaProvider를 지원하지 마세요",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP 서버가 존재합니다"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "제공자: %s를 찾을 수 없습니다"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "코드는 아직 전송되지 않았습니다!",
|
||||
"Invalid captcha provider.": "잘못된 captcha 제공자입니다.",
|
||||
"Phone number is invalid in your region %s": "전화 번호가 당신의 지역 %s에서 유효하지 않습니다",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "튜링 테스트 실패.",
|
||||
"Unable to get the email modify rule.": "이메일 수정 규칙을 가져올 수 없습니다.",
|
||||
"Unable to get the phone modify rule.": "전화 수정 규칙을 가져올 수 없습니다.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "Пользователь %s не существует",
|
||||
"don't support captchaProvider: ": "неподдерживаемый captchaProvider: ",
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP-сервер существует"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "Поставщик: %s не найден"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Код еще не был отправлен!",
|
||||
"Invalid captcha provider.": "Недействительный поставщик CAPTCHA.",
|
||||
"Phone number is invalid in your region %s": "Номер телефона недействителен в вашем регионе %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Тест Тьюринга не удался.",
|
||||
"Unable to get the email modify rule.": "Невозможно получить правило изменения электронной почты.",
|
||||
"Unable to get the phone modify rule.": "Невозможно получить правило изменения телефона.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Telefon numaranızın bulunduğu bölgeye hizmet veremiyoruz",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
|
||||
"The user: %s doesn't exist": "Người dùng: %s không tồn tại",
|
||||
"don't support captchaProvider: ": "không hỗ trợ captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
"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"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Máy chủ LDAP tồn tại"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "Nhà cung cấp: %s không được tìm thấy"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Mã chưa được gửi đến!",
|
||||
"Invalid captcha provider.": "Nhà cung cấp captcha không hợp lệ.",
|
||||
"Phone number is invalid in your region %s": "Số điện thoại không hợp lệ trong vùng của bạn %s",
|
||||
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
|
||||
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
|
||||
"Turing test failed.": "Kiểm định Turing thất bại.",
|
||||
"Unable to get the email modify rule.": "Không thể lấy quy tắc sửa đổi email.",
|
||||
"Unable to get the phone modify rule.": "Không thể thay đổi quy tắc trên điện thoại.",
|
||||
|
@ -81,7 +81,8 @@
|
||||
"The organization: %s should have one application at least": "组织: %s 应该拥有至少一个应用",
|
||||
"The user: %s doesn't exist": "用户: %s不存在",
|
||||
"don't support captchaProvider: ": "不支持验证码提供商: ",
|
||||
"this operation is not allowed in demo mode": "demo模式下不允许该操作"
|
||||
"this operation is not allowed in demo mode": "demo模式下不允许该操作",
|
||||
"this operation requires administrator to perform": "只有管理员才能进行此操作"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP服务器已存在"
|
||||
@ -145,9 +146,10 @@
|
||||
"The provider: %s is not found": "未找到提供商: %s"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "验证码还未发送",
|
||||
"Invalid captcha provider.": "非法的验证码提供商",
|
||||
"Phone number is invalid in your region %s": "您所在地区的电话号码无效 %s",
|
||||
"The verification code has not been sent yet!": "验证码未发送!",
|
||||
"The verification code has not been sent yet, or has already been used!": "验证码未发送或已被使用!",
|
||||
"Turing test failed.": "验证码还未发送",
|
||||
"Unable to get the email modify rule.": "无法获取邮箱修改规则",
|
||||
"Unable to get the phone modify rule.": "无法获取手机号修改规则",
|
||||
|
@ -35,6 +35,7 @@ type SignupItem struct {
|
||||
Visible bool `json:"visible"`
|
||||
Required bool `json:"required"`
|
||||
Prompted bool `json:"prompted"`
|
||||
CustomCss string `json:"customCss"`
|
||||
Label string `json:"label"`
|
||||
Placeholder string `json:"placeholder"`
|
||||
Regex string `json:"regex"`
|
||||
@ -208,7 +209,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem := &SigninItem{
|
||||
Name: "Back button",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .back-button {\n top: 65px;\n left: 15px;\n position: absolute;\n }\n</style>\n",
|
||||
Label: ".back-button {\n top: 65px;\n left: 15px;\n position: absolute;\n}\n.back-inner-button{}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -216,7 +217,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Languages",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-languages {\n top: 55px;\n right: 5px;\n position: absolute;\n }\n</style>\n",
|
||||
Label: ".login-languages {\n top: 55px;\n right: 5px;\n position: absolute;\n}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -224,7 +225,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Logo",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-logo-box {\n }\n</style>\n",
|
||||
Label: ".login-logo-box {}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -232,7 +233,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Signin methods",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .signin-methods {\n }\n</style>\n",
|
||||
Label: ".signin-methods {}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -240,7 +241,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Username",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-username {\n }\n</style>\n",
|
||||
Label: ".login-username {}\n.login-username-input{}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -248,7 +249,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Password",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-password {\n }\n</style>\n",
|
||||
Label: ".login-password {}\n.login-password-input{}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -256,7 +257,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Agreement",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-agreement {\n }\n</style>\n",
|
||||
Label: ".login-agreement {}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -264,7 +265,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Forgot password?",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-forget-password {\n display: inline-flex;\n justify-content: space-between;\n width: 320px;\n margin-bottom: 25px;\n }\n</style>\n",
|
||||
Label: ".login-forget-password {\n display: inline-flex;\n justify-content: space-between;\n width: 320px;\n margin-bottom: 25px;\n}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -272,7 +273,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Login button",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-button-box {\n margin-bottom: 5px;\n }\n .login-button {\n width: 100%;\n }\n</style>\n",
|
||||
Label: ".login-button-box {\n margin-bottom: 5px;\n}\n.login-button {\n width: 100%;\n}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -280,7 +281,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Signup link",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .login-signup-link {\n margin-bottom: 24px;\n display: flex;\n justify-content: end;\n}\n</style>\n",
|
||||
Label: ".login-signup-link {\n margin-bottom: 24px;\n display: flex;\n justify-content: end;\n}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -288,7 +289,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
||||
signinItem = &SigninItem{
|
||||
Name: "Providers",
|
||||
Visible: true,
|
||||
Label: "\n<style>\n .provider-img {\n width: 30px;\n margin: 5px;\n }\n .provider-big-img {\n margin-bottom: 10px;\n }\n</style>\n",
|
||||
Label: ".provider-img {\n width: 30px;\n margin: 5px;\n}\n.provider-big-img {\n margin-bottom: 10px;\n}",
|
||||
Placeholder: "",
|
||||
Rule: "None",
|
||||
}
|
||||
@ -404,8 +405,8 @@ func GetApplicationByUser(user *User) (*Application, error) {
|
||||
}
|
||||
|
||||
func GetApplicationByUserId(userId string) (application *Application, err error) {
|
||||
owner, name := util.GetOwnerAndNameFromId(userId)
|
||||
if owner == "app" {
|
||||
_, name := util.GetOwnerAndNameFromId(userId)
|
||||
if IsAppUser(userId) {
|
||||
application, err = getApplication("admin", name)
|
||||
return
|
||||
}
|
||||
@ -669,11 +670,7 @@ func AddApplication(application *Application) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteApplication(application *Application) (bool, error) {
|
||||
if application.Name == "app-built-in" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func deleteApplication(application *Application) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{application.Owner, application.Name}).Delete(&Application{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
@ -682,6 +679,14 @@ func DeleteApplication(application *Application) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteApplication(application *Application) (bool, error) {
|
||||
if application.Name == "app-built-in" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return deleteApplication(application)
|
||||
}
|
||||
|
||||
func (application *Application) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", application.Owner, application.Name)
|
||||
}
|
||||
|
@ -38,7 +38,20 @@ func (application *Application) GetProviderByCategory(category string) (*Provide
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (application *Application) GetProviderByCategoryAndRule(category string, method string) (*Provider, error) {
|
||||
func isProviderItemCountryCodeMatched(providerItem *ProviderItem, countryCode string) bool {
|
||||
if len(providerItem.CountryCodes) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, countryCode2 := range providerItem.CountryCodes {
|
||||
if countryCode2 == "" || countryCode2 == "All" || countryCode2 == "all" || countryCode2 == countryCode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (application *Application) GetProviderByCategoryAndRule(category string, method string, countryCode string) (*Provider, error) {
|
||||
providers, err := GetProviders(application.Organization)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -54,7 +67,13 @@ func (application *Application) GetProviderByCategoryAndRule(category string, me
|
||||
}
|
||||
|
||||
for _, providerItem := range application.Providers {
|
||||
if providerItem.Rule == method || (providerItem.Rule == "all" || providerItem.Rule == "" || providerItem.Rule == "None") {
|
||||
if providerItem.Provider != nil && providerItem.Provider.Category == "SMS" {
|
||||
if !isProviderItemCountryCodeMatched(providerItem, countryCode) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if providerItem.Rule == method || providerItem.Rule == "" || providerItem.Rule == "All" || providerItem.Rule == "all" || providerItem.Rule == "None" {
|
||||
if provider, ok := m[providerItem.Name]; ok {
|
||||
return provider, nil
|
||||
}
|
||||
@ -65,11 +84,11 @@ func (application *Application) GetProviderByCategoryAndRule(category string, me
|
||||
}
|
||||
|
||||
func (application *Application) GetEmailProvider(method string) (*Provider, error) {
|
||||
return application.GetProviderByCategoryAndRule("Email", method)
|
||||
return application.GetProviderByCategoryAndRule("Email", method, "All")
|
||||
}
|
||||
|
||||
func (application *Application) GetSmsProvider(method string) (*Provider, error) {
|
||||
return application.GetProviderByCategoryAndRule("SMS", method)
|
||||
func (application *Application) GetSmsProvider(method string, countryCode string) (*Provider, error) {
|
||||
return application.GetProviderByCategoryAndRule("SMS", method, countryCode)
|
||||
}
|
||||
|
||||
func (application *Application) GetStorageProvider() (*Provider, error) {
|
||||
|
@ -410,7 +410,7 @@ func CheckUserPermission(requestUserId, userId string, strict bool, lang string)
|
||||
}
|
||||
|
||||
hasPermission := false
|
||||
if strings.HasPrefix(requestUserId, "app/") {
|
||||
if IsAppUser(requestUserId) {
|
||||
hasPermission = true
|
||||
} else {
|
||||
requestUser, err := GetUser(requestUserId)
|
||||
|
@ -154,6 +154,15 @@ func AddGroups(groups []*Group) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func deleteGroup(group *Group) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{group.Owner, group.Name}).Delete(&Group{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteGroup(group *Group) (bool, error) {
|
||||
_, err := ormer.Engine.Get(group)
|
||||
if err != nil {
|
||||
@ -172,12 +181,7 @@ func DeleteGroup(group *Group) (bool, error) {
|
||||
return false, errors.New("group has users")
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.ID(core.PK{group.Owner, group.Name}).Delete(&Group{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
return deleteGroup(group)
|
||||
}
|
||||
|
||||
func checkGroupName(name string) error {
|
||||
|
@ -71,7 +71,7 @@ func getBuiltInAccountItems() []*AccountItem {
|
||||
{Name: "Permissions", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"},
|
||||
{Name: "Groups", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
{Name: "3rd-party logins", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Properties", Visible: false, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Properties", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is admin", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is forbidden", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is deleted", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
@ -409,7 +409,7 @@ func initBuiltInPermission() {
|
||||
Groups: []string{},
|
||||
Roles: []string{},
|
||||
Domains: []string{},
|
||||
Model: "model-built-in",
|
||||
Model: "user-model-built-in",
|
||||
Adapter: "",
|
||||
ResourceType: "Application",
|
||||
Resources: []string{"app-built-in"},
|
||||
|
@ -266,7 +266,13 @@ func initDefinedOrganization(organization *Organization) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := deleteOrganization(organization)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete organization")
|
||||
}
|
||||
}
|
||||
organization.CreatedTime = util.GetCurrentTime()
|
||||
organization.AccountItems = getBuiltInAccountItems()
|
||||
@ -284,7 +290,13 @@ func initDefinedApplication(application *Application) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := deleteApplication(application)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete application")
|
||||
}
|
||||
}
|
||||
application.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddApplication(application)
|
||||
@ -299,11 +311,19 @@ func initDefinedUser(user *User) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := deleteUser(user)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete user")
|
||||
}
|
||||
}
|
||||
user.CreatedTime = util.GetCurrentTime()
|
||||
user.Id = util.GenerateId()
|
||||
user.Properties = make(map[string]string)
|
||||
if user.Properties == nil {
|
||||
user.Properties = make(map[string]string)
|
||||
}
|
||||
_, err = AddUser(user)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -317,7 +337,13 @@ func initDefinedCert(cert *Cert) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteCert(cert)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete cert")
|
||||
}
|
||||
}
|
||||
cert.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddCert(cert)
|
||||
@ -333,7 +359,13 @@ func initDefinedLdap(ldap *Ldap) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteLdap(ldap)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete ldap")
|
||||
}
|
||||
}
|
||||
_, err = AddLdap(ldap)
|
||||
if err != nil {
|
||||
@ -348,7 +380,13 @@ func initDefinedProvider(provider *Provider) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteProvider(provider)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete provider")
|
||||
}
|
||||
}
|
||||
_, err = AddProvider(provider)
|
||||
if err != nil {
|
||||
@ -363,7 +401,13 @@ func initDefinedModel(model *Model) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteModel(model)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete provider")
|
||||
}
|
||||
}
|
||||
model.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddModel(model)
|
||||
@ -379,7 +423,13 @@ func initDefinedPermission(permission *Permission) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := deletePermission(permission)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete permission")
|
||||
}
|
||||
}
|
||||
permission.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddPermission(permission)
|
||||
@ -395,7 +445,13 @@ func initDefinedPayment(payment *Payment) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeletePayment(payment)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete payment")
|
||||
}
|
||||
}
|
||||
payment.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddPayment(payment)
|
||||
@ -411,7 +467,13 @@ func initDefinedProduct(product *Product) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteProduct(product)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete product")
|
||||
}
|
||||
}
|
||||
product.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddProduct(product)
|
||||
@ -427,7 +489,13 @@ func initDefinedResource(resource *Resource) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteResource(resource)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete resource")
|
||||
}
|
||||
}
|
||||
resource.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddResource(resource)
|
||||
@ -443,7 +511,13 @@ func initDefinedRole(role *Role) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := deleteRole(role)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete role")
|
||||
}
|
||||
}
|
||||
role.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddRole(role)
|
||||
@ -459,7 +533,13 @@ func initDefinedSyncer(syncer *Syncer) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteSyncer(syncer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete role")
|
||||
}
|
||||
}
|
||||
syncer.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddSyncer(syncer)
|
||||
@ -475,7 +555,13 @@ func initDefinedToken(token *Token) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteToken(token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete token")
|
||||
}
|
||||
}
|
||||
token.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddToken(token)
|
||||
@ -491,7 +577,13 @@ func initDefinedWebhook(webhook *Webhook) {
|
||||
}
|
||||
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteWebhook(webhook)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete webhook")
|
||||
}
|
||||
}
|
||||
webhook.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddWebhook(webhook)
|
||||
@ -506,7 +598,13 @@ func initDefinedGroup(group *Group) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := deleteGroup(group)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete group")
|
||||
}
|
||||
}
|
||||
group.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddGroup(group)
|
||||
@ -521,7 +619,13 @@ func initDefinedAdapter(adapter *Adapter) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteAdapter(adapter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete adapter")
|
||||
}
|
||||
}
|
||||
adapter.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddAdapter(adapter)
|
||||
@ -536,7 +640,13 @@ func initDefinedEnforcer(enforcer *Enforcer) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteEnforcer(enforcer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete enforcer")
|
||||
}
|
||||
}
|
||||
enforcer.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddEnforcer(enforcer)
|
||||
@ -551,7 +661,13 @@ func initDefinedPlan(plan *Plan) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeletePlan(plan)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete plan")
|
||||
}
|
||||
}
|
||||
plan.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddPlan(plan)
|
||||
@ -561,12 +677,18 @@ func initDefinedPlan(plan *Plan) {
|
||||
}
|
||||
|
||||
func initDefinedPricing(pricing *Pricing) {
|
||||
existed, err := getPlan(pricing.Owner, pricing.Name)
|
||||
existed, err := getPricing(pricing.Owner, pricing.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeletePricing(pricing)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete pricing")
|
||||
}
|
||||
}
|
||||
pricing.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddPricing(pricing)
|
||||
@ -581,7 +703,13 @@ func initDefinedInvitation(invitation *Invitation) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteInvitation(invitation)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete invitation")
|
||||
}
|
||||
}
|
||||
invitation.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddInvitation(invitation, "en")
|
||||
@ -591,6 +719,7 @@ func initDefinedInvitation(invitation *Invitation) {
|
||||
}
|
||||
|
||||
func initDefinedRecord(record *casvisorsdk.Record) {
|
||||
record.Id = 0
|
||||
record.CreatedTime = util.GetCurrentTime()
|
||||
_ = AddRecord(record)
|
||||
}
|
||||
@ -609,7 +738,13 @@ func initDefinedSubscription(subscription *Subscription) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteSubscription(subscription)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete subscription")
|
||||
}
|
||||
}
|
||||
subscription.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddSubscription(subscription)
|
||||
@ -624,7 +759,13 @@ func initDefinedTransaction(transaction *Transaction) {
|
||||
panic(err)
|
||||
}
|
||||
if existed != nil {
|
||||
return
|
||||
affected, err := DeleteTransaction(transaction)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !affected {
|
||||
panic("Fail to delete transaction")
|
||||
}
|
||||
}
|
||||
transaction.CreatedTime = util.GetCurrentTime()
|
||||
_, err = AddTransaction(transaction)
|
||||
|
@ -241,11 +241,7 @@ func AddOrganization(organization *Organization) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteOrganization(organization *Organization) (bool, error) {
|
||||
if organization.Name == "built-in" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func deleteOrganization(organization *Organization) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{organization.Owner, organization.Name}).Delete(&Organization{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
@ -254,6 +250,14 @@ func DeleteOrganization(organization *Organization) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteOrganization(organization *Organization) (bool, error) {
|
||||
if organization.Name == "built-in" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return deleteOrganization(organization)
|
||||
}
|
||||
|
||||
func GetOrganizationByUser(user *User) (*Organization, error) {
|
||||
if user == nil {
|
||||
return nil, nil
|
||||
|
@ -286,13 +286,22 @@ func AddPermissionsInBatch(permissions []*Permission) (bool, error) {
|
||||
return affected, nil
|
||||
}
|
||||
|
||||
func DeletePermission(permission *Permission) (bool, error) {
|
||||
func deletePermission(permission *Permission) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{permission.Owner, permission.Name}).Delete(&Permission{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if affected != 0 {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeletePermission(permission *Permission) (bool, error) {
|
||||
affected, err := deletePermission(permission)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if affected {
|
||||
err = removeGroupingPolicies(permission)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@ -314,7 +323,7 @@ func DeletePermission(permission *Permission) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
return affected, nil
|
||||
}
|
||||
|
||||
func getPermissionsByUser(userId string) ([]*Permission, error) {
|
||||
|
@ -133,7 +133,7 @@ func AddPlan(plan *Plan) (bool, error) {
|
||||
}
|
||||
|
||||
func DeletePlan(plan *Plan) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{plan.Owner, plan.Name}).Delete(plan)
|
||||
affected, err := ormer.Engine.ID(core.PK{plan.Owner, plan.Name}).Delete(Plan{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ func AddPricing(pricing *Pricing) (bool, error) {
|
||||
}
|
||||
|
||||
func DeletePricing(pricing *Pricing) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{pricing.Owner, pricing.Name}).Delete(pricing)
|
||||
affected, err := ormer.Engine.ID(core.PK{pricing.Owner, pricing.Name}).Delete(Pricing{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -18,13 +18,14 @@ type ProviderItem struct {
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
|
||||
CanSignUp bool `json:"canSignUp"`
|
||||
CanSignIn bool `json:"canSignIn"`
|
||||
CanUnlink bool `json:"canUnlink"`
|
||||
Prompted bool `json:"prompted"`
|
||||
SignupGroup string `json:"signupGroup"`
|
||||
Rule string `json:"rule"`
|
||||
Provider *Provider `json:"provider"`
|
||||
CanSignUp bool `json:"canSignUp"`
|
||||
CanSignIn bool `json:"canSignIn"`
|
||||
CanUnlink bool `json:"canUnlink"`
|
||||
CountryCodes []string `json:"countryCodes"`
|
||||
Prompted bool `json:"prompted"`
|
||||
SignupGroup string `json:"signupGroup"`
|
||||
Rule string `json:"rule"`
|
||||
Provider *Provider `json:"provider"`
|
||||
}
|
||||
|
||||
func (application *Application) GetProviderItem(providerName string) *ProviderItem {
|
||||
|
@ -17,6 +17,7 @@ package object
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego/context"
|
||||
@ -25,10 +26,14 @@ import (
|
||||
"github.com/casvisor/casvisor-go-sdk/casvisorsdk"
|
||||
)
|
||||
|
||||
var logPostOnly bool
|
||||
var (
|
||||
logPostOnly bool
|
||||
passwordRegex *regexp.Regexp
|
||||
)
|
||||
|
||||
func init() {
|
||||
logPostOnly = conf.GetConfigBool("logPostOnly")
|
||||
passwordRegex = regexp.MustCompile("\"password\":\".+\"")
|
||||
}
|
||||
|
||||
type Record struct {
|
||||
@ -40,6 +45,10 @@ type Response struct {
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
func maskPassword(recordString string) string {
|
||||
return passwordRegex.ReplaceAllString(recordString, "\"password\":\"***\"")
|
||||
}
|
||||
|
||||
func NewRecord(ctx *context.Context) (*casvisorsdk.Record, error) {
|
||||
ip := strings.Replace(util.GetIPFromRequest(ctx.Request), ": ", "", -1)
|
||||
action := strings.Replace(ctx.Request.URL.Path, "/api/", "", -1)
|
||||
@ -51,6 +60,7 @@ func NewRecord(ctx *context.Context) (*casvisorsdk.Record, error) {
|
||||
object := ""
|
||||
if ctx.Input.RequestBody != nil && len(ctx.Input.RequestBody) != 0 {
|
||||
object = string(ctx.Input.RequestBody)
|
||||
object = maskPassword(object)
|
||||
}
|
||||
|
||||
respBytes, err := json.Marshal(ctx.Input.Data()["json"])
|
||||
@ -99,6 +109,8 @@ func AddRecord(record *casvisorsdk.Record) bool {
|
||||
|
||||
record.Owner = record.Organization
|
||||
|
||||
record.Object = maskPassword(record.Object)
|
||||
|
||||
errWebhook := SendWebhooks(record)
|
||||
if errWebhook == nil {
|
||||
record.IsTriggered = true
|
||||
@ -140,6 +152,12 @@ func GetRecords() ([]*casvisorsdk.Record, error) {
|
||||
|
||||
func GetPaginationRecords(offset, limit int, field, value, sortField, sortOrder string, filterRecord *casvisorsdk.Record) ([]*casvisorsdk.Record, error) {
|
||||
records := []*casvisorsdk.Record{}
|
||||
|
||||
if sortField == "" || sortOrder == "" {
|
||||
sortField = "id"
|
||||
sortOrder = "descend"
|
||||
}
|
||||
|
||||
session := GetSession("", offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&records, filterRecord)
|
||||
if err != nil {
|
||||
@ -159,6 +177,25 @@ func GetRecordsByField(record *casvisorsdk.Record) ([]*casvisorsdk.Record, error
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func CopyRecord(record *casvisorsdk.Record) *casvisorsdk.Record {
|
||||
res := &casvisorsdk.Record{
|
||||
Owner: record.Owner,
|
||||
Name: record.Name,
|
||||
CreatedTime: record.CreatedTime,
|
||||
Organization: record.Organization,
|
||||
ClientIp: record.ClientIp,
|
||||
User: record.User,
|
||||
Method: record.Method,
|
||||
RequestUri: record.RequestUri,
|
||||
Action: record.Action,
|
||||
Language: record.Language,
|
||||
Object: record.Object,
|
||||
Response: record.Response,
|
||||
IsTriggered: record.IsTriggered,
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func getFilteredWebhooks(webhooks []*Webhook, organization string, action string) []*Webhook {
|
||||
res := []*Webhook{}
|
||||
for _, webhook := range webhooks {
|
||||
|
@ -238,6 +238,15 @@ func AddRolesInBatch(roles []*Role) bool {
|
||||
return affected
|
||||
}
|
||||
|
||||
func deleteRole(role *Role) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteRole(role *Role) (bool, error) {
|
||||
roleId := role.GetId()
|
||||
permissions, err := GetPermissionsByRole(roleId)
|
||||
@ -253,12 +262,7 @@ func DeleteRole(role *Role) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
return deleteRole(role)
|
||||
}
|
||||
|
||||
func (role *Role) GetId() string {
|
||||
|
@ -48,7 +48,7 @@ func SendSms(provider *Provider, content string, phoneNumbers ...string) error {
|
||||
if provider.AppId != "" {
|
||||
phoneNumbers = append([]string{provider.AppId}, phoneNumbers...)
|
||||
}
|
||||
} else if provider.Type == sender.Aliyun {
|
||||
} else if provider.Type == sender.Aliyun || provider.Type == sender.SendCloud {
|
||||
for i, number := range phoneNumbers {
|
||||
phoneNumbers[i] = strings.TrimPrefix(number, "+86")
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetOAuthToken(grantType string, clientId string, clientSecret string, code string, verifier string, scope string, username string, password string, host string, refreshToken string, tag string, avatar string, lang string) (interface{}, error) {
|
||||
func GetOAuthToken(grantType string, clientId string, clientSecret string, code string, verifier string, scope string, nonce string, username string, password string, host string, refreshToken string, tag string, avatar string, lang string) (interface{}, error) {
|
||||
application, err := GetApplicationByClientId(clientId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -220,6 +220,8 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
||||
token, tokenError, err = GetPasswordToken(application, username, password, scope, host)
|
||||
case "client_credentials": // Client Credentials Grant
|
||||
token, tokenError, err = GetClientCredentialsToken(application, clientSecret, scope, host)
|
||||
case "token", "id_token": // Implicit Grant
|
||||
token, tokenError, err = GetImplicitToken(application, username, scope, nonce, host)
|
||||
case "refresh_token":
|
||||
refreshToken2, err := RefreshToken(grantType, refreshToken, scope, clientId, clientSecret, host)
|
||||
if err != nil {
|
||||
@ -582,6 +584,33 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
|
||||
return token, nil, nil
|
||||
}
|
||||
|
||||
// GetImplicitToken
|
||||
// Implicit flow
|
||||
func GetImplicitToken(application *Application, username string, scope string, nonce string, host string) (*Token, *TokenError, error) {
|
||||
user, err := GetUserByFields(application.Organization, username)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if user == nil {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the user does not exist",
|
||||
}, nil
|
||||
}
|
||||
if user.IsForbidden {
|
||||
return nil, &TokenError{
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the user is forbidden to sign in, please contact the administrator",
|
||||
}, nil
|
||||
}
|
||||
|
||||
token, err := GetTokenByUser(application, user, scope, nonce, host)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return token, nil, nil
|
||||
}
|
||||
|
||||
// GetTokenByUser
|
||||
// Implicit flow
|
||||
func GetTokenByUser(application *Application, user *User, scope string, nonce string, host string) (*Token, error) {
|
||||
|
@ -675,7 +675,7 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
|
||||
"owner", "display_name", "avatar", "first_name", "last_name",
|
||||
"location", "address", "country_code", "region", "language", "affiliation", "title", "id_card_type", "id_card", "homepage", "bio", "tag", "language", "gender", "birthday", "education", "score", "karma", "ranking", "signup_application",
|
||||
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts", "face_ids",
|
||||
"signin_wrong_times", "last_signin_wrong_time", "groups", "access_key", "access_secret",
|
||||
"signin_wrong_times", "last_signin_wrong_time", "groups", "access_key", "access_secret", "mfa_phone_enabled", "mfa_email_enabled",
|
||||
"github", "google", "qq", "wechat", "facebook", "dingtalk", "weibo", "gitee", "linkedin", "wecom", "lark", "gitlab", "adfs",
|
||||
"baidu", "alipay", "casdoor", "infoflow", "apple", "azuread", "azureadb2c", "slack", "steam", "bilibili", "okta", "douyin", "line", "amazon",
|
||||
"auth0", "battlenet", "bitbucket", "box", "cloudfoundry", "dailymotion", "deezer", "digitalocean", "discord", "dropbox",
|
||||
@ -833,6 +833,11 @@ func AddUser(user *User) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
|
||||
if isUsernameLowered {
|
||||
user.Name = strings.ToLower(user.Name)
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.Insert(user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@ -846,6 +851,8 @@ func AddUsers(users []*User) (bool, error) {
|
||||
return false, fmt.Errorf("no users are provided")
|
||||
}
|
||||
|
||||
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
|
||||
|
||||
// organization := GetOrganizationByUser(users[0])
|
||||
for _, user := range users {
|
||||
// this function is only used for syncer or batch upload, so no need to encrypt the password
|
||||
@ -869,6 +876,10 @@ func AddUsers(users []*User) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
if isUsernameLowered {
|
||||
user.Name = strings.ToLower(user.Name)
|
||||
}
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.Insert(users)
|
||||
@ -908,6 +919,15 @@ func AddUsersInBatch(users []*User) (bool, error) {
|
||||
return affected, nil
|
||||
}
|
||||
|
||||
func deleteUser(user *User) (bool, error) {
|
||||
affected, err := ormer.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteUser(user *User) (bool, error) {
|
||||
// Forced offline the user first
|
||||
_, err := DeleteSession(util.GetSessionId(user.Owner, user.Name, CasdoorApplication))
|
||||
@ -915,12 +935,7 @@ func DeleteUser(user *User) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
return deleteUser(user)
|
||||
}
|
||||
|
||||
func GetUserInfo(user *User, scope string, aud string, host string) (*Userinfo, error) {
|
||||
@ -992,7 +1007,7 @@ func (user *User) GetFriendlyName() string {
|
||||
}
|
||||
|
||||
func isUserIdGlobalAdmin(userId string) bool {
|
||||
return strings.HasPrefix(userId, "built-in/") || strings.HasPrefix(userId, "app/")
|
||||
return strings.HasPrefix(userId, "built-in/") || IsAppUser(userId)
|
||||
}
|
||||
|
||||
func ExtendUserWithRolesAndPermissions(user *User) (err error) {
|
||||
|
@ -464,3 +464,10 @@ func (user *User) IsAdminUser() bool {
|
||||
|
||||
return user.IsAdmin || user.IsGlobalAdmin()
|
||||
}
|
||||
|
||||
func IsAppUser(userId string) bool {
|
||||
if strings.HasPrefix(userId, "app/") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -92,9 +92,12 @@ func SendVerificationCodeToEmail(organization *Organization, user *User, provide
|
||||
|
||||
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
|
||||
content := strings.Replace(provider.Content, "%s", code, 1)
|
||||
|
||||
userString := "Hi"
|
||||
if user != nil {
|
||||
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
|
||||
userString = user.GetFriendlyName()
|
||||
}
|
||||
content = strings.Replace(content, "%{user.friendlyName}", userString, 1)
|
||||
|
||||
err := IsAllowSend(user, remoteAddr, provider.Category)
|
||||
if err != nil {
|
||||
@ -187,14 +190,17 @@ func CheckVerificationCode(dest string, code string, lang string) (*VerifyResult
|
||||
return &VerifyResult{noRecordError, i18n.Translate(lang, "verification:The verification code has not been sent yet, or has already been used!")}, nil
|
||||
}
|
||||
|
||||
timeout, err := conf.GetConfigInt64("verificationCodeTimeout")
|
||||
timeoutInMinutes, err := conf.GetConfigInt64("verificationCodeTimeout")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
if now-record.Time > timeout*60 {
|
||||
return &VerifyResult{timeoutError, fmt.Sprintf(i18n.Translate(lang, "verification:You should verify your code in %d min!"), timeout)}, nil
|
||||
if now-record.Time > timeoutInMinutes*60*10 {
|
||||
return &VerifyResult{noRecordError, i18n.Translate(lang, "verification:The verification code has not been sent yet!")}, nil
|
||||
}
|
||||
if now-record.Time > timeoutInMinutes*60 {
|
||||
return &VerifyResult{timeoutError, fmt.Sprintf(i18n.Translate(lang, "verification:You should verify your code in %d min!"), timeoutInMinutes)}, nil
|
||||
}
|
||||
|
||||
if record.Code != code {
|
||||
|
@ -15,9 +15,12 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/casvisor/casvisor-go-sdk/casvisorsdk"
|
||||
)
|
||||
|
||||
func getUser(ctx *context.Context) (username string) {
|
||||
@ -68,6 +71,7 @@ func RecordMessage(ctx *context.Context) {
|
||||
func AfterRecordMessage(ctx *context.Context) {
|
||||
record, err := object.NewRecord(ctx)
|
||||
if err != nil {
|
||||
fmt.Printf("AfterRecordMessage() error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -76,14 +80,32 @@ func AfterRecordMessage(ctx *context.Context) {
|
||||
record.Organization, record.User = util.GetOwnerAndNameFromId(userId)
|
||||
}
|
||||
|
||||
var record2 *casvisorsdk.Record
|
||||
recordSignup := ctx.Input.Params()["recordSignup"]
|
||||
if recordSignup == "true" {
|
||||
record2 := *record
|
||||
record2.Action = "signup"
|
||||
util.SafeGoroutine(func() { object.AddRecord(&record2) })
|
||||
record2 = object.CopyRecord(record)
|
||||
record2.Action = "new-user"
|
||||
|
||||
var user *object.User
|
||||
user, err = object.GetUser(userId)
|
||||
if err != nil {
|
||||
fmt.Printf("AfterRecordMessage() error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
if user == nil {
|
||||
err = fmt.Errorf("the user: %s is not found", userId)
|
||||
fmt.Printf("AfterRecordMessage() error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
record2.Object = util.StructToJson(user)
|
||||
}
|
||||
|
||||
util.SafeGoroutine(func() {
|
||||
object.AddRecord(record)
|
||||
|
||||
if record2 != nil {
|
||||
object.AddRecord(record2)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ func fastAutoSignin(ctx *context.Context) (string, error) {
|
||||
scope := ctx.Input.Query("scope")
|
||||
state := ctx.Input.Query("state")
|
||||
nonce := ""
|
||||
codeChallenge := ""
|
||||
codeChallenge := ctx.Input.Query("code_challenge")
|
||||
if clientId == "" || responseType != "code" || redirectUri == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ func (sp LocalFileSystemProvider) Put(path string, reader io.Reader) (*oss.Objec
|
||||
|
||||
dst, err := os.Create(filepath.Clean(fullPath))
|
||||
if err == nil {
|
||||
defer dst.Close()
|
||||
if seeker, ok := reader.(io.ReadSeeker); ok {
|
||||
seeker.Seek(0, 0)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/cssinjs": "1.16.1",
|
||||
"@ant-design/cssinjs": "^1.10.1",
|
||||
"@ant-design/icons": "^4.7.0",
|
||||
"@craco/craco": "^6.4.5",
|
||||
"@crowdin/cli": "^3.7.10",
|
||||
|
@ -41,6 +41,7 @@ setTwoToneColor("rgb(87,52,211)");
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.setThemeAlgorithm();
|
||||
let storageThemeAlgorithm = [];
|
||||
try {
|
||||
storageThemeAlgorithm = localStorage.getItem("themeAlgorithm") ? JSON.parse(localStorage.getItem("themeAlgorithm")) : ["default"];
|
||||
@ -157,6 +158,15 @@ class App extends Component {
|
||||
return Setting.getLogo(themes);
|
||||
}
|
||||
|
||||
setThemeAlgorithm() {
|
||||
const currentUrl = window.location.href;
|
||||
const url = new URL(currentUrl);
|
||||
const themeType = url.searchParams.get("theme");
|
||||
if (themeType === "dark" || themeType === "default") {
|
||||
localStorage.setItem("themeAlgorithm", JSON.stringify([themeType]));
|
||||
}
|
||||
}
|
||||
|
||||
setLanguage(account) {
|
||||
const language = account?.language;
|
||||
if (language !== null && language !== "" && language !== i18next.language) {
|
||||
@ -364,6 +374,7 @@ class App extends Component {
|
||||
});
|
||||
}}
|
||||
onLoginSuccess={(redirectUrl) => {
|
||||
window.google?.accounts?.id?.cancel();
|
||||
if (redirectUrl) {
|
||||
localStorage.setItem("mfaRedirectUrl", redirectUrl);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||
import i18next from "i18next";
|
||||
import BaseListPage from "./BaseListPage";
|
||||
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||
import {SignupTableDefaultCssMap} from "./table/SignupTable";
|
||||
|
||||
class ApplicationListPage extends BaseListPage {
|
||||
constructor(props) {
|
||||
@ -61,6 +62,8 @@ class ApplicationListPage extends BaseListPage {
|
||||
{name: "Email", visible: true, required: true, rule: "Normal"},
|
||||
{name: "Phone", visible: true, required: true, rule: "None"},
|
||||
{name: "Agreement", visible: true, required: true, rule: "None"},
|
||||
{name: "Signup button", visible: true, required: true, rule: "None"},
|
||||
{name: "Providers", visible: true, required: true, rule: "None", customCss: SignupTableDefaultCssMap["Providers"]},
|
||||
],
|
||||
grantTypes: ["authorization_code", "password", "client_credentials", "token", "id_token", "refresh_token"],
|
||||
cert: "cert-built-in",
|
||||
|
@ -41,7 +41,7 @@ class ProductEditPage extends React.Component {
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getProduct();
|
||||
this.getOrganizations();
|
||||
this.getPaymentProviders();
|
||||
this.getPaymentProviders(this.state.organizationName);
|
||||
}
|
||||
|
||||
getProduct() {
|
||||
@ -67,8 +67,8 @@ class ProductEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getPaymentProviders() {
|
||||
ProviderBackend.getProviders(this.props.account.owner)
|
||||
getPaymentProviders(organizationName) {
|
||||
ProviderBackend.getProviders(organizationName)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
|
@ -209,6 +209,8 @@ class ProviderEditPage extends React.Component {
|
||||
return Setting.getLabel(i18next.t("provider:Public key"), i18next.t("provider:Public key - Tooltip"));
|
||||
} else if (provider.type === "Msg91 SMS" || provider.type === "Infobip SMS" || provider.type === "OSON SMS") {
|
||||
return Setting.getLabel(i18next.t("provider:Sender Id"), i18next.t("provider:Sender Id - Tooltip"));
|
||||
} else if (provider.type === "SendCloud SMS") {
|
||||
return "SMS_USER";
|
||||
} else {
|
||||
return Setting.getLabel(i18next.t("provider:Client ID"), i18next.t("provider:Client ID - Tooltip"));
|
||||
}
|
||||
@ -244,7 +246,7 @@ class ProviderEditPage extends React.Component {
|
||||
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
||||
}
|
||||
case "Email":
|
||||
if (provider.type === "Azure ACS") {
|
||||
if (provider.type === "Azure ACS" || provider.type === "SendGrid") {
|
||||
return Setting.getLabel(i18next.t("provider:Secret key"), i18next.t("provider:Secret key - Tooltip"));
|
||||
} else {
|
||||
return Setting.getLabel(i18next.t("general:Password"), i18next.t("general:Password - Tooltip"));
|
||||
@ -260,6 +262,8 @@ class ProviderEditPage extends React.Component {
|
||||
return Setting.getLabel(i18next.t("provider:Auth Key"), i18next.t("provider:Auth Key - Tooltip"));
|
||||
} else if (provider.type === "Infobip SMS") {
|
||||
return Setting.getLabel(i18next.t("provider:Api Key"), i18next.t("provider:Api Key - Tooltip"));
|
||||
} else if (provider.type === "SendCloud SMS") {
|
||||
return "SMS_KEY";
|
||||
} else {
|
||||
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
||||
}
|
||||
@ -729,7 +733,7 @@ class ProviderEditPage extends React.Component {
|
||||
<React.Fragment>
|
||||
{
|
||||
(this.state.provider.category === "Storage" && this.state.provider.type === "Google Cloud Storage") ||
|
||||
(this.state.provider.category === "Email" && this.state.provider.type === "Azure ACS") ||
|
||||
(this.state.provider.category === "Email" && (this.state.provider.type === "Azure ACS" || this.state.provider.type === "SendGrid")) ||
|
||||
(this.state.provider.category === "Notification" && (this.state.provider.type === "Line" || this.state.provider.type === "Telegram" || this.state.provider.type === "Bark" || this.state.provider.type === "Discord" || this.state.provider.type === "Slack" || this.state.provider.type === "Pushbullet" || this.state.provider.type === "Pushover" || this.state.provider.type === "Lark" || this.state.provider.type === "Microsoft Teams")) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
@ -770,7 +774,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
(this.state.provider.type === "WeChat Pay") || (this.state.provider.category === "Email" && this.state.provider.type === "Azure ACS") ? null : (
|
||||
(this.state.provider.type === "WeChat Pay") || (this.state.provider.category === "Email" && (this.state.provider.type === "Azure ACS" || this.state.provider.type === "SendGrid")) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{this.getClientSecret2Label(this.state.provider)} :
|
||||
@ -985,17 +989,19 @@ class ProviderEditPage extends React.Component {
|
||||
</React.Fragment>
|
||||
) : this.state.provider.category === "Email" ? (
|
||||
<React.Fragment>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.host} onChange={e => {
|
||||
this.updateProviderField("host", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
{["Azure ACS"].includes(this.state.provider.type) ? null : (
|
||||
{["SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input prefix={<LinkOutlined />} value={this.state.provider.host} onChange={e => {
|
||||
this.updateProviderField("host", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Azure ACS", "SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Port"), i18next.t("provider:Port - Tooltip"))} :
|
||||
@ -1007,7 +1013,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Azure ACS"].includes(this.state.provider.type) ? null : (
|
||||
{["Azure ACS", "SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Disable SSL"), i18next.t("provider:Disable SSL - Tooltip"))} :
|
||||
@ -1073,7 +1079,7 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("receiver", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
{["Azure ACS"].includes(this.state.provider.type) ? null : (
|
||||
{["Azure ACS", "SendGrid"].includes(this.state.provider.type) ? null : (
|
||||
<Button style={{marginLeft: "10px", marginBottom: "5px"}} onClick={() => ProviderEditTestEmail.connectSmtpServer(this.state.provider)} >
|
||||
{i18next.t("provider:Test SMTP Connection")}
|
||||
</Button>
|
||||
@ -1087,7 +1093,7 @@ class ProviderEditPage extends React.Component {
|
||||
</React.Fragment>
|
||||
) : this.state.provider.category === "SMS" ? (
|
||||
<React.Fragment>
|
||||
{["Custom HTTP SMS", "Twilio SMS", "Amazon SNS", "Azure ACS", "Msg91 SMS", "Infobip SMS"].includes(this.state.provider.type) ?
|
||||
{["Custom HTTP SMS", "Twilio SMS", "Amazon SNS", "Azure ACS", "Msg91 SMS", "Infobip SMS", "SendCloud SMS"].includes(this.state.provider.type) ?
|
||||
null :
|
||||
(<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
|
@ -187,7 +187,7 @@ class RecordListPage extends BaseListPage {
|
||||
sorter: true,
|
||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||
render: (text, record, index) => {
|
||||
if (!["signup", "login", "logout", "update-user"].includes(record.action)) {
|
||||
if (!["signup", "login", "logout", "update-user", "new-user"].includes(record.action)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,10 @@ export const OtherProviderInfo = {
|
||||
logo: `${StaticBaseUrl}/img/social_twilio.svg`,
|
||||
url: "https://www.twilio.com/messaging",
|
||||
},
|
||||
"SendCloud SMS": {
|
||||
logo: `${StaticBaseUrl}/img/sms_sendcloud.png`,
|
||||
url: "https://www.sendcloud.net/",
|
||||
},
|
||||
"SmsBao SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_smsbao.png`,
|
||||
url: "https://www.smsbao.com/",
|
||||
@ -181,6 +185,10 @@ export const OtherProviderInfo = {
|
||||
logo: `${StaticBaseUrl}/img/social_azure.png`,
|
||||
url: "https://learn.microsoft.com/zh-cn/azure/communication-services",
|
||||
},
|
||||
"SendGrid": {
|
||||
logo: `${StaticBaseUrl}/img/email_sendgrid.png`,
|
||||
url: "https://sendgrid.com/",
|
||||
},
|
||||
"Custom HTTP Email": {
|
||||
logo: `${StaticBaseUrl}/img/social_default.png`,
|
||||
url: "https://casdoor.org/docs/provider/email/overview",
|
||||
@ -1015,6 +1023,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: "SUBMAIL", name: "SUBMAIL"},
|
||||
{id: "Mailtrap", name: "Mailtrap"},
|
||||
{id: "Azure ACS", name: "Azure ACS"},
|
||||
{id: "SendGrid", name: "SendGrid"},
|
||||
{id: "Custom HTTP Email", name: "Custom HTTP Email"},
|
||||
]
|
||||
);
|
||||
@ -1034,6 +1043,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: "Huawei Cloud SMS", name: "Huawei Cloud SMS"},
|
||||
{id: "UCloud SMS", name: "UCloud SMS"},
|
||||
{id: "Twilio SMS", name: "Twilio SMS"},
|
||||
{id: "SendCloud SMS", name: "SendCloud SMS"},
|
||||
{id: "SmsBao SMS", name: "SmsBao SMS"},
|
||||
{id: "SUBMAIL SMS", name: "SUBMAIL SMS"},
|
||||
{id: "Msg91 SMS", name: "Msg91 SMS"},
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Form, Input, InputNumber, List, Result, Row, Select, Space, Spin, Switch, Tag} from "antd";
|
||||
import {Button, Card, Col, Form, Input, InputNumber, List, Result, Row, Select, Space, Spin, Switch, Tag, Tooltip} from "antd";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import {TotpMfaType} from "./auth/MfaSetupPage";
|
||||
import * as GroupBackend from "./backend/GroupBackend";
|
||||
@ -407,7 +407,17 @@ class UserEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:Password"), i18next.t("general:Password - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<PasswordModal user={this.state.user} userName={this.state.userName} organization={this.getUserOrganization()} account={this.props.account} disabled={disabled} />
|
||||
{
|
||||
(this.state.user.name === this.state.userName) ? (
|
||||
<PasswordModal user={this.state.user} userName={this.state.userName} organization={this.getUserOrganization()} account={this.props.account} disabled={disabled} />
|
||||
) : (
|
||||
<Tooltip placement={"topLeft"} title={i18next.t("user:You have changed the username, please save your change first before modifying the password")}>
|
||||
<span>
|
||||
<PasswordModal user={this.state.user} userName={this.state.userName} organization={this.getUserOrganization()} account={this.props.account} disabled={true} />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
@ -19,7 +19,7 @@ import * as VerificationBackend from "./backend/VerificationBackend";
|
||||
import i18next from "i18next";
|
||||
import {Link} from "react-router-dom";
|
||||
import React from "react";
|
||||
import {Table} from "antd";
|
||||
import {Switch, Table} from "antd";
|
||||
|
||||
class VerificationListPage extends BaseListPage {
|
||||
newVerification() {
|
||||
@ -35,26 +35,48 @@ class VerificationListPage extends BaseListPage {
|
||||
renderTable(verifications) {
|
||||
const columns = [
|
||||
{
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
width: "150px",
|
||||
fixed: "left",
|
||||
title: i18next.t("general:Organization"),
|
||||
dataIndex: "owner",
|
||||
key: "owner",
|
||||
width: "120px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
...this.getColumnSearchProps("owner"),
|
||||
render: (text, record, index) => {
|
||||
if (text === "admin") {
|
||||
return `(${i18next.t("general:empty")})`;
|
||||
}
|
||||
|
||||
return (
|
||||
<Link to={`/syncers/${text}`}>
|
||||
<Link to={`/organizations/${text}`}>
|
||||
{text}
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
width: "260px",
|
||||
fixed: "left",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Created time"),
|
||||
dataIndex: "createdTime",
|
||||
key: "createdTime",
|
||||
width: "160px",
|
||||
sorter: true,
|
||||
render: (text, record, index) => {
|
||||
return Setting.getFormattedDate(text);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("provider:Type"),
|
||||
dataIndex: "type",
|
||||
key: "type",
|
||||
width: "120px",
|
||||
width: "90px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("type"),
|
||||
},
|
||||
@ -67,7 +89,7 @@ class VerificationListPage extends BaseListPage {
|
||||
...this.getColumnSearchProps("user"),
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Link to={`/users/${record.owner}/${text}`}>
|
||||
<Link to={`/users/${text}`}>
|
||||
{text}
|
||||
</Link>
|
||||
);
|
||||
@ -88,6 +110,26 @@ class VerificationListPage extends BaseListPage {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Client IP"),
|
||||
dataIndex: "remoteAddr",
|
||||
key: "remoteAddr",
|
||||
width: "100px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("remoteAddr"),
|
||||
render: (text, record, index) => {
|
||||
let clientIp = text;
|
||||
if (clientIp.endsWith(": ")) {
|
||||
clientIp = clientIp.slice(0, -2);
|
||||
}
|
||||
|
||||
return (
|
||||
<a target="_blank" rel="noreferrer" href={`https://db-ip.com/${clientIp}`}>
|
||||
{clientIp}
|
||||
</a>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("verification:Receiver"),
|
||||
dataIndex: "receiver",
|
||||
@ -100,28 +142,20 @@ class VerificationListPage extends BaseListPage {
|
||||
title: i18next.t("login:Verification code"),
|
||||
dataIndex: "code",
|
||||
key: "code",
|
||||
width: "120px",
|
||||
width: "150px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("code"),
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Timestamp"),
|
||||
dataIndex: "time",
|
||||
key: "time",
|
||||
width: "160px",
|
||||
title: i18next.t("verification:Is used"),
|
||||
dataIndex: "isUsed",
|
||||
key: "isUsed",
|
||||
width: "90px",
|
||||
sorter: true,
|
||||
render: (text, record, index) => {
|
||||
return Setting.getFormattedDate(text * 1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Created time"),
|
||||
dataIndex: "createdTime",
|
||||
key: "createdTime",
|
||||
width: "160px",
|
||||
sorter: true,
|
||||
render: (text, record, index) => {
|
||||
return Setting.getFormattedDate(text);
|
||||
return (
|
||||
<Switch disabled checkedChildren="ON" unCheckedChildren="OFF" checked={text} />
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -156,7 +190,7 @@ class VerificationListPage extends BaseListPage {
|
||||
value = params.type;
|
||||
}
|
||||
this.setState({loading: true});
|
||||
VerificationBackend.getVerifications("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||
VerificationBackend.getVerifications("", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
|
@ -275,7 +275,7 @@ class WebhookEditPage extends React.Component {
|
||||
}} >
|
||||
{
|
||||
(
|
||||
["signup", "login", "logout"].concat(this.getApiPaths()).map((option, index) => {
|
||||
["signup", "login", "logout", "new-user"].concat(this.getApiPaths()).map((option, index) => {
|
||||
return (
|
||||
<Option key={option} value={option}>{option}</Option>
|
||||
);
|
||||
|
@ -21,7 +21,7 @@ import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
import {SendCodeInput} from "../common/SendCodeInput";
|
||||
import * as UserBackend from "../backend/UserBackend";
|
||||
import {CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import {ArrowLeftOutlined, CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import CustomGithubCorner from "../common/CustomGithubCorner";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as PasswordChecker from "../common/PasswordChecker";
|
||||
@ -443,6 +443,18 @@ class ForgetPage extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
stepBack() {
|
||||
if (this.state.current > 0) {
|
||||
this.setState({
|
||||
current: this.state.current - 1,
|
||||
});
|
||||
} else if (this.props.history.length > 1) {
|
||||
this.props.history.goBack();
|
||||
} else {
|
||||
Setting.redirectToLoginPage(this.getApplicationObj(), this.props.history);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const application = this.getApplicationObj();
|
||||
if (application === undefined) {
|
||||
@ -456,6 +468,9 @@ class ForgetPage extends React.Component {
|
||||
<React.Fragment>
|
||||
<CustomGithubCorner />
|
||||
<div className="forget-content" style={{padding: Setting.isMobile() ? "0" : null, boxShadow: Setting.isMobile() ? "none" : null}}>
|
||||
<Button type="text" style={{position: "relative", left: Setting.isMobile() ? "10px" : "-90px", top: 0}} size={"large"} onClick={() => {this.stepBack();}}>
|
||||
<ArrowLeftOutlined style={{fontSize: "24px"}} />
|
||||
</Button>
|
||||
<Row>
|
||||
<Col span={24} style={{justifyContent: "center"}}>
|
||||
<Row>
|
||||
|
@ -52,7 +52,7 @@ export function GoogleOneTapLoginVirtualButton(prop) {
|
||||
redirectUri = `${redirectUri}?state=${state}&code=${encodeURIComponent(code)}`;
|
||||
Setting.goToLink(redirectUri);
|
||||
},
|
||||
disableCancelOnUnmount: true,
|
||||
disableCancelOnUnmount: false,
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ class LoginPage extends React.Component {
|
||||
if (signinItem.name === "Logo") {
|
||||
return (
|
||||
<div className="login-logo-box">
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
{
|
||||
Setting.renderHelmet(application)
|
||||
}
|
||||
@ -543,8 +543,8 @@ class LoginPage extends React.Component {
|
||||
);
|
||||
} else if (signinItem.name === "Back button") {
|
||||
return (
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div className="back-button">
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
{
|
||||
this.renderBackButton()
|
||||
}
|
||||
@ -562,24 +562,25 @@ class LoginPage extends React.Component {
|
||||
|
||||
return (
|
||||
<div className="login-languages">
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
<LanguageSelect languages={application.organizationObj.languages} />
|
||||
</div>
|
||||
);
|
||||
} else if (signinItem.name === "Signin methods") {
|
||||
return (
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
{this.renderMethodChoiceBox()}
|
||||
</div>
|
||||
)
|
||||
;
|
||||
} else if (signinItem.name === "Username") {
|
||||
return (
|
||||
<div className="login-username">
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
<Form.Item
|
||||
name="username"
|
||||
className="login-username"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
@ -637,6 +638,7 @@ class LoginPage extends React.Component {
|
||||
|
||||
<Input
|
||||
id="input"
|
||||
className="login-username-input"
|
||||
prefix={<UserOutlined className="site-form-item-icon" />}
|
||||
placeholder={this.getPlaceholder()}
|
||||
onChange={e => {
|
||||
@ -651,14 +653,14 @@ class LoginPage extends React.Component {
|
||||
} else if (signinItem.name === "Password") {
|
||||
return (
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
{this.renderPasswordOrCodeInput()}
|
||||
</div>
|
||||
);
|
||||
} else if (signinItem.name === "Forgot password?") {
|
||||
return (
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
<div className="login-forget-password">
|
||||
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
|
||||
<Checkbox style={{float: "left"}}>
|
||||
@ -676,7 +678,7 @@ class LoginPage extends React.Component {
|
||||
} else if (signinItem.name === "Login button") {
|
||||
return (
|
||||
<Form.Item className="login-button-box">
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
@ -720,7 +722,7 @@ class LoginPage extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
<Form.Item>
|
||||
{
|
||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
||||
@ -740,7 +742,7 @@ class LoginPage extends React.Component {
|
||||
} else if (signinItem.name === "Signup link") {
|
||||
return (
|
||||
<div style={{width: "100%"}} className="login-signup-link">
|
||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||
{this.renderFooter(application)}
|
||||
</div>
|
||||
);
|
||||
@ -838,7 +840,7 @@ class LoginPage extends React.Component {
|
||||
{application.displayName}
|
||||
</span>
|
||||
</a>
|
||||
:
|
||||
:
|
||||
</div>
|
||||
<br />
|
||||
{
|
||||
@ -1025,12 +1027,14 @@ class LoginPage extends React.Component {
|
||||
if (this.state.loginMethod === "password" || this.state.loginMethod === "ldap") {
|
||||
return (
|
||||
<Col span={24}>
|
||||
<div className="login-password">
|
||||
<div>
|
||||
<Form.Item
|
||||
name="password"
|
||||
className="login-password"
|
||||
rules={[{required: true, message: i18next.t("login:Please input your password!")}]}
|
||||
>
|
||||
<Input.Password
|
||||
className="login-password-input"
|
||||
prefix={<LockOutlined className="site-form-item-icon" />}
|
||||
type="password"
|
||||
placeholder={i18next.t("general:Password")}
|
||||
@ -1173,7 +1177,7 @@ class LoginPage extends React.Component {
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{height: 300}}>
|
||||
<div style={{height: 300, minWidth: 320}}>
|
||||
{renderChoiceBox()}
|
||||
</div>
|
||||
);
|
||||
@ -1195,8 +1199,7 @@ class LoginPage extends React.Component {
|
||||
renderBackButton() {
|
||||
if (this.state.orgChoiceMode === "None" || this.props.preview === "auto") {
|
||||
return (
|
||||
<Button type="text" size="large" icon={<ArrowLeftOutlined />}
|
||||
className="back-button"
|
||||
<Button className="back-inner-button" type="text" size="large" icon={<ArrowLeftOutlined />}
|
||||
onClick={() => history.back()}>
|
||||
</Button>
|
||||
);
|
||||
|
@ -172,23 +172,23 @@ export function renderProviderLogo(provider, application, width, margin, size, l
|
||||
const customAStyle = {display: "block", height: "55px", color: "#000"};
|
||||
const customButtonStyle = {display: "flex", alignItems: "center", width: "calc(100% - 10px)", height: "50px", margin: "5px", padding: "0 10px", backgroundColor: "transparent", boxShadow: "0px 1px 3px rgba(0,0,0,0.5)", border: "0px", borderRadius: "3px", cursor: "pointer"};
|
||||
const customImgStyle = {justfyContent: "space-between"};
|
||||
const customSpanStyle = {textAlign: "center", lineHeight: "50px", width: "100%", fontSize: "19px"};
|
||||
const customSpanStyle = {textAlign: "center", width: "100%", fontSize: "19px"};
|
||||
if (provider.category === "OAuth") {
|
||||
return (
|
||||
<a key={provider.displayName} href={Provider.getAuthUrl(application, provider, "signup")} style={customAStyle}>
|
||||
<button style={customButtonStyle}>
|
||||
<div style={customButtonStyle}>
|
||||
<img width={26} src={getProviderLogoURL(provider)} alt={provider.displayName} className="provider-img" style={customImgStyle} />
|
||||
<span style={customSpanStyle}>{text}</span>
|
||||
</button>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
} else if (provider.category === "SAML") {
|
||||
return (
|
||||
<a key={provider.displayName} onClick={() => goToSamlUrl(provider, location)} style={customAStyle}>
|
||||
<button style={customButtonStyle}>
|
||||
<div style={customButtonStyle}>
|
||||
<img width={26} src={getProviderLogoURL(provider)} alt={provider.displayName} className="provider-img" style={customImgStyle} />
|
||||
<span style={customSpanStyle}>{text}</span>
|
||||
</button>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Form, Input, Result} from "antd";
|
||||
import {Button, Form, Input, Radio, Result, Row} from "antd";
|
||||
import * as Setting from "../Setting";
|
||||
import * as AuthBackend from "./AuthBackend";
|
||||
import * as ProviderButton from "./ProviderButton";
|
||||
@ -71,6 +71,7 @@ class SignupPage extends React.Component {
|
||||
applicationName: (props.applicationName ?? props.match?.params?.applicationName) ?? null,
|
||||
email: "",
|
||||
phone: "",
|
||||
emailOrPhoneMode: "",
|
||||
countryCode: "",
|
||||
emailCode: "",
|
||||
phoneCode: "",
|
||||
@ -247,6 +248,7 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="username"
|
||||
className="signup-username"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("signup:Username")}
|
||||
rules={[
|
||||
{
|
||||
@ -256,7 +258,8 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation.username !== ""} />
|
||||
<Input className="signup-username-input" placeholder={signupItem.placeholder}
|
||||
disabled={this.state.invitation !== undefined && this.state.invitation.username !== ""} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Display name") {
|
||||
@ -265,6 +268,7 @@ class SignupPage extends React.Component {
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
name="firstName"
|
||||
className="signup-first-name"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("general:First name")}
|
||||
rules={[
|
||||
{
|
||||
@ -274,10 +278,11 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} />
|
||||
<Input className="signup-first-name-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="lastName"
|
||||
className="signup-last-name"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("general:Last name")}
|
||||
rules={[
|
||||
{
|
||||
@ -287,7 +292,7 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} />
|
||||
<Input className="signup-last-name-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
);
|
||||
@ -296,6 +301,7 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="name"
|
||||
className="signup-name"
|
||||
label={(signupItem.label ? signupItem.label : (signupItem.rule === "Real name" || signupItem.rule === "First, last") ? i18next.t("general:Real name") : i18next.t("general:Display name"))}
|
||||
rules={[
|
||||
{
|
||||
@ -305,13 +311,14 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} />
|
||||
<Input className="signup-name-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Affiliation") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="affiliation"
|
||||
className="signup-affiliation"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("user:Affiliation")}
|
||||
rules={[
|
||||
{
|
||||
@ -321,13 +328,14 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} />
|
||||
<Input className="signup-affiliation-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "ID card") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="idCard"
|
||||
className="signup-idcard"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("user:ID card")}
|
||||
rules={[
|
||||
{
|
||||
@ -342,13 +350,14 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} />
|
||||
<Input className="signup-idcard-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Country/Region") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="country_region"
|
||||
className="signup-country-region"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("user:Country/Region")}
|
||||
rules={[
|
||||
{
|
||||
@ -357,137 +366,190 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<RegionSelect onChange={(value) => {this.setState({region: value});}} />
|
||||
<RegionSelect className="signup-region-select" onChange={(value) => {this.setState({region: value});}} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Email") {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
name="email"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("general:Email")}
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please input your Email!"),
|
||||
},
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (this.state.email !== "" && !Setting.isValidEmail(this.state.email)) {
|
||||
this.setState({validEmail: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Email!"));
|
||||
}
|
||||
|
||||
this.setState({validEmail: true});
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation.email !== ""} onChange={e => this.setState({email: e.target.value})} />
|
||||
</Form.Item>
|
||||
{
|
||||
signupItem.rule !== "No verification" &&
|
||||
} else if (signupItem.name === "Email" || signupItem.name === "Phone" || signupItem.name === "Email or Phone" || signupItem.name === "Phone or Email") {
|
||||
const renderEmailItem = () => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
name="emailCode"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("code:Email code")}
|
||||
rules={[{
|
||||
required: required,
|
||||
message: i18next.t("code:Please input your verification code!"),
|
||||
}]}
|
||||
>
|
||||
<SendCodeInput
|
||||
disabled={!this.state.validEmail}
|
||||
method={"signup"}
|
||||
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationName(application)]}
|
||||
application={application}
|
||||
/>
|
||||
</Form.Item>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
} else if (signupItem.name === "Phone") {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Form.Item label={signupItem.label ? signupItem.label : i18next.t("general:Phone")} required={required}>
|
||||
<Input.Group compact>
|
||||
<Form.Item
|
||||
name="countryCode"
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please select your country code!"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<CountryCodeSelect
|
||||
style={{width: "35%"}}
|
||||
countryCodes={this.getApplicationObj().organizationObj.countryCodes}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="phone"
|
||||
dependencies={["countryCode"]}
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please input your phone number!"),
|
||||
},
|
||||
({getFieldValue}) => ({
|
||||
validator: (_, value) => {
|
||||
if (!required && !value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (value && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
|
||||
this.setState({validPhone: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Phone!"));
|
||||
}
|
||||
|
||||
this.setState({validPhone: true});
|
||||
return Promise.resolve();
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder={signupItem.placeholder}
|
||||
style={{width: "65%"}}
|
||||
disabled={this.state.invitation !== undefined && this.state.invitation.phone !== ""}
|
||||
onChange={e => this.setState({phone: e.target.value})}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
{
|
||||
signupItem.rule !== "No verification" &&
|
||||
<Form.Item
|
||||
name="phoneCode"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("code:Phone code")}
|
||||
name="email"
|
||||
className="signup-email"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("general:Email")}
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("code:Please input your phone verification code!"),
|
||||
message: i18next.t("signup:Please input your Email!"),
|
||||
},
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (this.state.email !== "" && !Setting.isValidEmail(this.state.email)) {
|
||||
this.setState({validEmail: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Email!"));
|
||||
}
|
||||
|
||||
this.setState({validEmail: true});
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
]}
|
||||
>
|
||||
<SendCodeInput
|
||||
disabled={!this.state.validPhone}
|
||||
method={"signup"}
|
||||
onButtonClickArgs={[this.state.phone, "phone", Setting.getApplicationName(application)]}
|
||||
application={application}
|
||||
countryCode={this.form.current?.getFieldValue("countryCode")}
|
||||
/>
|
||||
<Input className="signup-email-input" placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation.email !== ""} onChange={e => this.setState({email: e.target.value})} />
|
||||
</Form.Item>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
{
|
||||
signupItem.rule !== "No verification" &&
|
||||
<Form.Item
|
||||
name="emailCode"
|
||||
className="signup-email-code"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("code:Email code")}
|
||||
rules={[{
|
||||
required: required,
|
||||
message: i18next.t("code:Please input your verification code!"),
|
||||
}]}
|
||||
>
|
||||
<SendCodeInput
|
||||
className="signup-email-code-input"
|
||||
disabled={!this.state.validEmail}
|
||||
method={"signup"}
|
||||
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationName(application)]}
|
||||
application={application}
|
||||
/>
|
||||
</Form.Item>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const renderPhoneItem = () => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Form.Item className="signup-phone" label={signupItem.label ? signupItem.label : i18next.t("general:Phone")} required={required}>
|
||||
<Input.Group compact>
|
||||
<Form.Item
|
||||
name="countryCode"
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please select your country code!"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<CountryCodeSelect
|
||||
style={{width: "35%"}}
|
||||
countryCodes={this.getApplicationObj().organizationObj.countryCodes}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="phone"
|
||||
dependencies={["countryCode"]}
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please input your phone number!"),
|
||||
},
|
||||
({getFieldValue}) => ({
|
||||
validator: (_, value) => {
|
||||
if (!required && !value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (value && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
|
||||
this.setState({validPhone: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Phone!"));
|
||||
}
|
||||
|
||||
this.setState({validPhone: true});
|
||||
return Promise.resolve();
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
className="signup-phone-input"
|
||||
placeholder={signupItem.placeholder}
|
||||
style={{width: "65%"}}
|
||||
disabled={this.state.invitation !== undefined && this.state.invitation.phone !== ""}
|
||||
onChange={e => this.setState({phone: e.target.value})}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Input.Group>
|
||||
</Form.Item>
|
||||
{
|
||||
signupItem.rule !== "No verification" &&
|
||||
<Form.Item
|
||||
name="phoneCode"
|
||||
className="phone-code"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("code:Phone code")}
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("code:Please input your phone verification code!"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<SendCodeInput
|
||||
className="signup-phone-code-input"
|
||||
disabled={!this.state.validPhone}
|
||||
method={"signup"}
|
||||
onButtonClickArgs={[this.state.phone, "phone", Setting.getApplicationName(application)]}
|
||||
application={application}
|
||||
countryCode={this.form.current?.getFieldValue("countryCode")}
|
||||
/>
|
||||
</Form.Item>
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
if (signupItem.name === "Email") {
|
||||
return renderEmailItem();
|
||||
} else if (signupItem.name === "Phone") {
|
||||
return renderPhoneItem();
|
||||
} else if (signupItem.name === "Email or Phone" || signupItem.name === "Phone or Email") {
|
||||
let emailOrPhoneMode = this.state.emailOrPhoneMode;
|
||||
if (emailOrPhoneMode === "") {
|
||||
emailOrPhoneMode = signupItem.name === "Email or Phone" ? "Email" : "Phone";
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Row style={{marginTop: "30px", marginBottom: "20px"}} >
|
||||
<Radio.Group style={{width: "400px"}} buttonStyle="solid" onChange={e => {
|
||||
this.setState({
|
||||
emailOrPhoneMode: e.target.value,
|
||||
});
|
||||
}} value={emailOrPhoneMode}>
|
||||
{
|
||||
signupItem.name === "Email or Phone" ? (
|
||||
<React.Fragment>
|
||||
<Radio.Button value={"Email"}>{i18next.t("general:Email")}</Radio.Button>
|
||||
<Radio.Button value={"Phone"}>{i18next.t("general:Phone")}</Radio.Button>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<Radio.Button value={"Phone"}>{i18next.t("general:Phone")}</Radio.Button>
|
||||
<Radio.Button value={"Email"}>{i18next.t("general:Email")}</Radio.Button>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
</Radio.Group>
|
||||
</Row>
|
||||
{
|
||||
emailOrPhoneMode === "Email" ? renderEmailItem() : renderPhoneItem()
|
||||
}
|
||||
</React.Fragment>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (signupItem.name === "Password") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="password"
|
||||
className="signup-password"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("general:Password")}
|
||||
rules={[
|
||||
{
|
||||
@ -505,13 +567,14 @@ class SignupPage extends React.Component {
|
||||
]}
|
||||
hasFeedback
|
||||
>
|
||||
<Input.Password placeholder={signupItem.placeholder} />
|
||||
<Input.Password className="signup-password-input" placeholder={signupItem.placeholder} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Confirm password") {
|
||||
return (
|
||||
<Form.Item
|
||||
name="confirm"
|
||||
className="signup-confirm"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("signup:Confirm")}
|
||||
dependencies={["password"]}
|
||||
hasFeedback
|
||||
@ -538,6 +601,7 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="invitationCode"
|
||||
className="signup-invitation-code"
|
||||
label={signupItem.label ? signupItem.label : i18next.t("application:Invitation code")}
|
||||
rules={[
|
||||
{
|
||||
@ -546,7 +610,7 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation !== ""} />
|
||||
<Input className="signup-invitation-code-input" placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation !== ""} />
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Agreement") {
|
||||
@ -555,6 +619,37 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<div dangerouslySetInnerHTML={{__html: signupItem.label}} />
|
||||
);
|
||||
} else if (signupItem.name === "Signup button") {
|
||||
return (
|
||||
<Form.Item {...tailFormItemLayout}>
|
||||
<Button type="primary" htmlType="submit" className="signup-button">
|
||||
{i18next.t("account:Sign Up")}
|
||||
</Button>
|
||||
{i18next.t("signup:Have account?")}
|
||||
<a className="signup-link" onClick={() => {
|
||||
const linkInStorage = sessionStorage.getItem("signinUrl");
|
||||
if (linkInStorage !== null && linkInStorage !== "") {
|
||||
Setting.goToLinkSoft(this, linkInStorage);
|
||||
} else {
|
||||
Setting.redirectToLoginPage(application, this.props.history);
|
||||
}
|
||||
}}>
|
||||
{i18next.t("signup:sign in now")}
|
||||
</a>
|
||||
</Form.Item>
|
||||
);
|
||||
} else if (signupItem.name === "Providers") {
|
||||
const showForm = Setting.isPasswordEnabled(application) || Setting.isCodeSigninEnabled(application) || Setting.isWebAuthnEnabled(application) || Setting.isLdapEnabled(application);
|
||||
if (signupItem.rule === "None" || signupItem.rule === "") {
|
||||
signupItem.rule = showForm ? "small" : "big";
|
||||
}
|
||||
return (
|
||||
|
||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, null, null, signupItem.rule, this.props.location);
|
||||
})
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,27 +724,13 @@ class SignupPage extends React.Component {
|
||||
>
|
||||
</Form.Item>
|
||||
{
|
||||
application.signupItems?.map(signupItem => this.renderFormItem(application, signupItem))
|
||||
}
|
||||
<Form.Item {...tailFormItemLayout}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
{i18next.t("account:Sign Up")}
|
||||
</Button>
|
||||
{i18next.t("signup:Have account?")}
|
||||
<a onClick={() => {
|
||||
const linkInStorage = sessionStorage.getItem("signinUrl");
|
||||
if (linkInStorage !== null && linkInStorage !== "") {
|
||||
Setting.goToLinkSoft(this, linkInStorage);
|
||||
} else {
|
||||
Setting.redirectToLoginPage(application, this.props.history);
|
||||
}
|
||||
}}>
|
||||
{i18next.t("signup:sign in now")}
|
||||
</a>
|
||||
</Form.Item>
|
||||
{
|
||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small", this.props.location);
|
||||
application.signupItems?.map((signupItem, idx) => {
|
||||
return (
|
||||
<div key={idx}>
|
||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signupItem.customCss + "</style>")}} />
|
||||
{this.renderFormItem(application, signupItem)}
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</Form>
|
||||
@ -662,6 +743,20 @@ class SignupPage extends React.Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
let existSignupButton = false;
|
||||
application.signupItems?.map(item => {
|
||||
item.name === "Signup button" ? existSignupButton = true : null;
|
||||
});
|
||||
if (!existSignupButton) {
|
||||
application.signupItems?.push({
|
||||
customCss: "",
|
||||
label: "",
|
||||
name: "Signup button",
|
||||
placeholder: "",
|
||||
visible: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (application.signupHtml !== "") {
|
||||
return (
|
||||
<div dangerouslySetInnerHTML={{__html: application.signupHtml}} />
|
||||
|
@ -13,11 +13,14 @@
|
||||
// limitations under the License.
|
||||
|
||||
import {Select} from "antd";
|
||||
import i18next from "i18next";
|
||||
import * as Setting from "../../Setting";
|
||||
import React from "react";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
export const CountryCodeSelect = (props) => {
|
||||
const {onChange, style, disabled, initValue} = props;
|
||||
const {onChange, style, disabled, initValue, mode} = props;
|
||||
const countryCodes = props.countryCodes ?? [];
|
||||
const [value, setValue] = React.useState("");
|
||||
|
||||
@ -42,11 +45,19 @@ export const CountryCodeSelect = (props) => {
|
||||
style={style}
|
||||
disabled={disabled}
|
||||
value={value}
|
||||
mode={mode}
|
||||
dropdownMatchSelectWidth={false}
|
||||
optionLabelProp={"label"}
|
||||
onChange={handleOnChange}
|
||||
filterOption={(input, option) => (option?.text ?? "").toLowerCase().includes(input.toLowerCase())}
|
||||
>
|
||||
{
|
||||
props.hasDefault ? (<Option key={"All"} value={"All"} label={i18next.t("organization:All")} text={"organization:All"} >
|
||||
<div style={{display: "flex", justifyContent: "space-between", marginRight: "10px"}}>
|
||||
{i18next.t("organization:All")}
|
||||
</div>
|
||||
</Option>) : null
|
||||
}
|
||||
{
|
||||
Setting.getCountryCodeData(countryCodes).map((country) => Setting.getCountryCodeOption(country))
|
||||
}
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Bitte geben Sie Ihre Anwendung ein!",
|
||||
"Please input your organization!": "Bitte geben Sie Ihre Organisation ein!",
|
||||
"Please select a HTML file": "Bitte wählen Sie eine HTML-Datei aus",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "E-Mail",
|
||||
"Email - Tooltip": "Gültige E-Mail-Adresse",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Telefon",
|
||||
"Phone - Tooltip": "Telefonnummer",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Pläne",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "Benutzertyp",
|
||||
"User type - Tooltip": "Tags, denen der Benutzer angehört, standardmäßig auf \"normaler Benutzer\" festgelegt",
|
||||
"Users": "Benutzer",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Benutzer unter allen Organisationen",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Laden",
|
||||
"Logging out...": "Ausloggen...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "Kein Konto?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Melden Sie sich mit WebAuthn an",
|
||||
"Sign in with {type}": "Melden Sie sich mit {type} an",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Anmelden...",
|
||||
"Successfully logged in with WebAuthn credentials": "Erfolgreich mit WebAuthn-Anmeldeinformationen angemeldet",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Bitte wählen Sie Ihren Ländercode aus!",
|
||||
"Please select your country/region!": "Bitte wählen Sie Ihr Land/Ihre Region aus!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Nutzungsbedingungen",
|
||||
"Terms of Use - Tooltip": "Nutzungsbedingungen, die Benutzer während der Registrierung lesen und akzeptieren müssen",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Werte",
|
||||
"Verification code sent": "Bestätigungscode gesendet",
|
||||
"WebAuthn credentials": "WebAuthn-Anmeldeinformationen",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "Eingabe des Passworts"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "¡Por favor, ingrese su solicitud!",
|
||||
"Please input your organization!": "¡Por favor, ingrese su organización!",
|
||||
"Please select a HTML file": "Por favor, seleccione un archivo HTML",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Correo electrónico",
|
||||
"Email - Tooltip": "Dirección de correo electrónico válida",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Teléfono",
|
||||
"Phone - Tooltip": "Número de teléfono",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Planes",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "Tipo de usuario",
|
||||
"User type - Tooltip": "Etiquetas a las que el usuario pertenece, con una configuración predeterminada en \"usuario-normal\"",
|
||||
"Users": "Usuarios",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Usuarios bajo todas las organizaciones",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Cargando",
|
||||
"Logging out...": "Cerrando sesión...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "¿No tienes cuenta?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Iniciar sesión con WebAuthn",
|
||||
"Sign in with {type}": "Inicia sesión con {tipo}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Iniciando sesión...",
|
||||
"Successfully logged in with WebAuthn credentials": "Inició sesión correctamente con las credenciales de WebAuthn",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "¡Por favor seleccione su código de país!",
|
||||
"Please select your country/region!": "¡Por favor seleccione su país/región!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Términos de uso",
|
||||
"Terms of Use - Tooltip": "Términos de uso que los usuarios necesitan leer y aceptar durante el registro",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Valores",
|
||||
"Verification code sent": "Código de verificación enviado",
|
||||
"WebAuthn credentials": "Credenciales de WebAuthn",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "Ingresar contraseña"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Inscription uniquement",
|
||||
"Org choice mode": "Choix du mode de l'organisation",
|
||||
"Org choice mode - Tooltip": "Choix du mode de l'organisation - Info-bulle",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
|
||||
"Please input your application!": "Veuillez saisir votre application !",
|
||||
"Please input your organization!": "Veuillez saisir votre organisation !",
|
||||
"Please select a HTML file": "Veuillez sélectionner un fichier HTML",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "E-mail",
|
||||
"Email - Tooltip": "Adresse e-mail valide",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Activer",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Téléphone",
|
||||
"Phone - Tooltip": "Numéro de téléphone",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Offre",
|
||||
"Plan - Tooltip": "Offre - Infobulle",
|
||||
"Plans": "Offres",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "Type de compte",
|
||||
"User type - Tooltip": "Étiquettes associées au compte, avec une valeur par défaut \"normal-user\"",
|
||||
"Users": "Comptes",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Comptes sous toutes les organisations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Crochets web",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Chargement",
|
||||
"Logging out...": "Déconnexion...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "Le plugin MetaMask n'a pas été détecté",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "Pas de compte ?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Connectez-vous avec WebAuthn",
|
||||
"Sign in with {type}": "Connectez-vous avec {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Connexion en cours...",
|
||||
"Successfully logged in with WebAuthn credentials": "Connexion avec les identifiants WebAuthn réussie",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Sélectionnez votre code de pays, s'il vous plaît !",
|
||||
"Please select your country/region!": "Veuillez sélectionner votre pays/région !",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Conditions d'utilisation",
|
||||
"Terms of Use - Tooltip": "Conditions d'utilisation qui doivent être lus acceptés lors de l'enregistrement du compte",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Valeurs",
|
||||
"Verification code sent": "Code de vérification envoyé",
|
||||
"WebAuthn credentials": "Identifiants WebAuthn",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "saisir le mot de passe"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Silakan masukkan aplikasi Anda!",
|
||||
"Please input your organization!": "Silakan masukkan organisasi Anda!",
|
||||
"Please select a HTML file": "Silahkan pilih file HTML",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Alamat email yang valid",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Telepon",
|
||||
"Phone - Tooltip": "Nomor telepon",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Rencana",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "Jenis pengguna",
|
||||
"User type - Tooltip": "Tag yang dimiliki oleh pengguna, defaultnya adalah \"normal-user\"",
|
||||
"Users": "Pengguna-pengguna",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Pengguna di bawah semua organisasi",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Memuat",
|
||||
"Logging out...": "Keluar...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "Tidak memiliki akun?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Masuk dengan WebAuthn",
|
||||
"Sign in with {type}": "Masuk dengan {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Masuk...",
|
||||
"Successfully logged in with WebAuthn credentials": "Berhasil masuk dengan kredensial WebAuthn",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Tolong pilih kode negara Anda!",
|
||||
"Please select your country/region!": "Silakan pilih negara/region Anda!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Syarat Penggunaan",
|
||||
"Terms of Use - Tooltip": "Syarat penggunaan yang harus dibaca dan disetujui oleh pengguna selama proses registrasi",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Nilai-nilai",
|
||||
"Verification code sent": "Kode verifikasi telah dikirim",
|
||||
"WebAuthn credentials": "Kredensial WebAuthn",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "masukkan kata sandi"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "あなたの申請を入力してください!",
|
||||
"Please input your organization!": "あなたの組織を入力してください!",
|
||||
"Please select a HTML file": "HTMLファイルを選択してください",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "電子メール",
|
||||
"Email - Tooltip": "有効な電子メールアドレス",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "電話",
|
||||
"Phone - Tooltip": "電話番号",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "プラン",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "ユーザータイプ",
|
||||
"User type - Tooltip": "ユーザーが属するタグは、デフォルトでは「通常ユーザー」となります",
|
||||
"Users": "ユーザー",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "すべての組織のユーザー",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "ローディング",
|
||||
"Logging out...": "ログアウト中...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "アカウントがありませんか?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "WebAuthnでサインインしてください",
|
||||
"Sign in with {type}": "{type}でサインインしてください",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "サインイン中...",
|
||||
"Successfully logged in with WebAuthn credentials": "WebAuthnの認証情報で正常にログインしました",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "あなたの国コードを選択してください!",
|
||||
"Please select your country/region!": "あなたの国/地域を選択してください!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "利用規約",
|
||||
"Terms of Use - Tooltip": "ユーザーが登録する際に読んで同意する必要がある利用規約",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "価値観",
|
||||
"Verification code sent": "確認コードを送信しました",
|
||||
"WebAuthn credentials": "WebAuthnの資格情報",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "パスワードを入力してください"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "당신의 신청서를 입력해주세요!",
|
||||
"Please input your organization!": "귀하의 조직을 입력해 주세요!",
|
||||
"Please select a HTML file": "HTML 파일을 선택해 주세요",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "이메일",
|
||||
"Email - Tooltip": "유효한 이메일 주소",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "전화기",
|
||||
"Phone - Tooltip": "전화 번호",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "플랜",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "사용자 유형",
|
||||
"User type - Tooltip": "사용자가 속한 태그는 기본적으로 \"보통 사용자\"로 설정됩니다",
|
||||
"Users": "사용자",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "모든 조직의 사용자",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "로딩 중입니다",
|
||||
"Logging out...": "로그아웃 중...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "계정이 없나요?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "WebAuthn으로 로그인하세요",
|
||||
"Sign in with {type}": "{type}로 로그인하세요",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "로그인 중...",
|
||||
"Successfully logged in with WebAuthn credentials": "WebAuthn 자격 증명으로 로그인 성공적으로 수행했습니다",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "국가 코드를 선택해 주세요!",
|
||||
"Please select your country/region!": "국가 / 지역을 선택해주세요!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "사용 약관",
|
||||
"Terms of Use - Tooltip": "등록 중 사용자가 읽어야 하고 동의해야하는 이용 약관",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "가치들",
|
||||
"Verification code sent": "인증 코드가 전송되었습니다",
|
||||
"WebAuthn credentials": "웹 인증 자격증명",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "비밀번호를 입력해주세요"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Apenas registro",
|
||||
"Org choice mode": "Modo de escolha Org",
|
||||
"Org choice mode - Tooltip": "Modo de escolha Org - Dica",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
|
||||
"Please input your application!": "Por favor, insira o nome da sua aplicação!",
|
||||
"Please input your organization!": "Por favor, insira o nome da sua organização!",
|
||||
"Please select a HTML file": "Por favor, selecione um arquivo HTML",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "E-mail",
|
||||
"Email - Tooltip": "Endereço de e-mail válido",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Habilitar",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Telefone",
|
||||
"Phone - Tooltip": "Número de telefone",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Kế hoạch",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "Tipo de Usuário",
|
||||
"User type - Tooltip": "Tags às quais o usuário pertence, com valor padrão de \"usuário-normal\"",
|
||||
"Users": "Usuários",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Usuários em todas as organizações",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Carregando",
|
||||
"Logging out...": "Saindo...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "Não possui uma conta?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Entrar com WebAuthn",
|
||||
"Sign in with {type}": "Entrar com {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Entrando...",
|
||||
"Successfully logged in with WebAuthn credentials": "Logado com sucesso usando credenciais WebAuthn",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Por favor, selecione o código do seu país!",
|
||||
"Please select your country/region!": "Por favor, selecione seu país/região!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Termos de Uso",
|
||||
"Terms of Use - Tooltip": "Termos de uso que os usuários precisam ler e concordar durante o registro",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Valores",
|
||||
"Verification code sent": "Código de verificação enviado",
|
||||
"WebAuthn credentials": "Credenciais WebAuthn",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "Digite a senha"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Только при регистрации",
|
||||
"Org choice mode": "Режим выбора организации",
|
||||
"Org choice mode - Tooltip": "Выбор режима выбора организации пользователем",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
|
||||
"Please input your application!": "Пожалуйста, введите свою заявку!",
|
||||
"Please input your organization!": "Пожалуйста, введите название вашей организации!",
|
||||
"Please select a HTML file": "Пожалуйста, выберите файл HTML",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Электронная почта",
|
||||
"Email - Tooltip": "Действительный адрес электронной почты",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Включить",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Телефон",
|
||||
"Phone - Tooltip": "Номер телефона",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "План",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Планы",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "Тип пользователя",
|
||||
"User type - Tooltip": "Теги, к которым принадлежит пользователь, по умолчанию \"обычный пользователь\"",
|
||||
"Users": "Пользователи",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Пользователи всех организаций",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Вебхуки",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Загрузка",
|
||||
"Logging out...": "Выход...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "Нет аккаунта?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Войти с помощью WebAuthn",
|
||||
"Sign in with {type}": "Войти с помощью {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Вход в систему...",
|
||||
"Successfully logged in with WebAuthn credentials": "Успешный вход с учетными данными WebAuthn",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Пожалуйста, выберите код своей страны!",
|
||||
"Please select your country/region!": "Пожалуйста, выберите свою страну / регион!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Условия использования",
|
||||
"Terms of Use - Tooltip": "Условия использования, которые пользователи должны прочитать и согласиться с ними при регистрации",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Значения",
|
||||
"Verification code sent": "Код подтверждения отправлен",
|
||||
"WebAuthn credentials": "WebAuthn удостоверения",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "введите пароль"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email",
|
||||
"Email - Tooltip": "Valid email address",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Phone",
|
||||
"Phone - Tooltip": "Phone number",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Users",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "No account?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "input password"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "Only signup",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Please input your application!",
|
||||
"Please input your organization!": "Please input your organization!",
|
||||
"Please select a HTML file": "Please select a HTML file",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "E-Posta",
|
||||
"Email - Tooltip": "Geçerli e-posta adresi",
|
||||
"Email only": "Sadece eposta",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Etkinleştir",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Telefon",
|
||||
"Phone - Tooltip": "Telefon numarası",
|
||||
"Phone only": "Sadece telefon",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Plans",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "User type",
|
||||
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
|
||||
"Users": "Kullanıcılar",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Users under all organizations",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Yükleniyor",
|
||||
"Logging out...": "Çıkış yapılıyor...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "Metamask plugin-in bulunamadı",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "Hesabınız yok mu?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with {type}": "{type} ile giriş yap",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Signing in...",
|
||||
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Kullanım Koşulları",
|
||||
"Terms of Use - Tooltip": "Kayıt olabilmek için kullanım koşullarını okuyup, kabul etmelisiniz",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "şifreyi girin"
|
||||
},
|
||||
"verification": {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -80,6 +80,7 @@
|
||||
"Only signup": "Chỉ đăng ký",
|
||||
"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\\\"",
|
||||
"Please input your application!": "Vui lòng nhập ứng dụng của bạn!",
|
||||
"Please input your organization!": "Vui lòng nhập tổ chức của bạn!",
|
||||
"Please select a HTML file": "Vui lòng chọn tệp HTML",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "Email: Thư điện tử",
|
||||
"Email - Tooltip": "Địa chỉ email hợp lệ",
|
||||
"Email only": "Email only",
|
||||
"Email or Phone": "Email or Phone",
|
||||
"Enable": "Enable",
|
||||
"Enable dark logo": "Enable dark logo",
|
||||
"Enable dark logo - Tooltip": "Enable dark logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "Điện thoại",
|
||||
"Phone - Tooltip": "Số điện thoại",
|
||||
"Phone only": "Phone only",
|
||||
"Phone or Email": "Phone or Email",
|
||||
"Plan": "Plan",
|
||||
"Plan - Tooltip": "Plan - Tooltip",
|
||||
"Plans": "Kế hoạch",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "Loại người dùng",
|
||||
"User type - Tooltip": "Các thẻ mà người dùng thuộc vào, mặc định là \"người dùng bình thường\"",
|
||||
"Users": "Người dùng",
|
||||
"Users - Tooltip": "Users - Tooltip",
|
||||
"Users under all organizations": "Người dùng trong tất cả các tổ chức",
|
||||
"Verifications": "Verifications",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Đang tải",
|
||||
"Logging out...": "Đăng xuất ...",
|
||||
"Login button": "Login button",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
"Model loading failure": "Model loading failure",
|
||||
"No account?": "Không có tài khoản?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "Sign in with Face ID",
|
||||
"Sign in with WebAuthn": "Đăng nhập với WebAuthn",
|
||||
"Sign in with {type}": "Đăng nhập bằng {type}",
|
||||
"Signin button": "Signin button",
|
||||
"Signing in...": "Đăng nhập...",
|
||||
"Successfully logged in with WebAuthn credentials": "Đã đăng nhập thành công với thông tin WebAuthn",
|
||||
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "Vui lòng chọn mã quốc gia của bạn!",
|
||||
"Please select your country/region!": "Vui lòng chọn quốc gia/vùng của bạn!",
|
||||
"Regex": "Regex",
|
||||
"Signup button": "Signup button",
|
||||
"Terms of Use": "Điều khoản sử dụng",
|
||||
"Terms of Use - Tooltip": "Điều khoản sử dụng mà người dùng cần đọc và đồng ý trong quá trình đăng ký",
|
||||
"Text 1": "Text 1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "Giá trị",
|
||||
"Verification code sent": "Mã xác minh đã được gửi",
|
||||
"WebAuthn credentials": "Chứng chỉ WebAuthn",
|
||||
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
|
||||
"input password": "Nhập mật khẩu"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -80,6 +80,7 @@
|
||||
"Only signup": "仅注册",
|
||||
"Org choice mode": "组织选择模式",
|
||||
"Org choice mode - Tooltip": "采用什么方式选择要登录的组织",
|
||||
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "开启 \\\"保持登录会话\\\" 后才能开启 \\\"自动登录\\\"",
|
||||
"Please input your application!": "请输入你的应用",
|
||||
"Please input your organization!": "请输入你的组织",
|
||||
"Please select a HTML file": "请选择一个HTML文件",
|
||||
@ -229,6 +230,7 @@
|
||||
"Email": "电子邮箱",
|
||||
"Email - Tooltip": "合法的电子邮件地址",
|
||||
"Email only": "仅支持邮件",
|
||||
"Email or Phone": "电子邮件或手机",
|
||||
"Enable": "启用",
|
||||
"Enable dark logo": "开启暗黑Logo",
|
||||
"Enable dark logo - Tooltip": "开启暗黑Logo",
|
||||
@ -311,6 +313,7 @@
|
||||
"Phone": "手机号",
|
||||
"Phone - Tooltip": "手机号",
|
||||
"Phone only": "仅支持手机号",
|
||||
"Phone or Email": "手机或电子邮件",
|
||||
"Plan": "计划",
|
||||
"Plan - Tooltip": "订阅里的计划",
|
||||
"Plans": "计划",
|
||||
@ -391,6 +394,7 @@
|
||||
"User type": "用户类型",
|
||||
"User type - Tooltip": "用户所属的标签,默认为\"normal-user\"",
|
||||
"Users": "用户",
|
||||
"Users - Tooltip": "用户 - Tooltip",
|
||||
"Users under all organizations": "所有组织里的用户",
|
||||
"Verifications": "验证",
|
||||
"Webhooks": "Webhooks",
|
||||
@ -473,7 +477,6 @@
|
||||
"LDAP username, Email or phone": "LDAP用户名, Email或手机号",
|
||||
"Loading": "加载中",
|
||||
"Logging out...": "正在退出登录...",
|
||||
"Login button": "登录按钮",
|
||||
"MetaMask plugin not detected": "未检测到MetaMask插件",
|
||||
"Model loading failure": "人脸识别模型加载失败",
|
||||
"No account?": "没有账号?",
|
||||
@ -498,6 +501,7 @@
|
||||
"Sign in with Face ID": "人脸登录",
|
||||
"Sign in with WebAuthn": "WebAuthn登录",
|
||||
"Sign in with {type}": "{type}登录",
|
||||
"Signin button": "登录按钮",
|
||||
"Signing in...": "正在登录...",
|
||||
"Successfully logged in with WebAuthn credentials": "成功使用WebAuthn证书登录",
|
||||
"The camera is currently in use by another webpage": "摄像头被占用,无法使用",
|
||||
@ -941,6 +945,7 @@
|
||||
"Please select your country code!": "请选择国家代码!",
|
||||
"Please select your country/region!": "请选择您的国家或地区",
|
||||
"Regex": "正则表达式",
|
||||
"Signup button": "注册按钮",
|
||||
"Terms of Use": "《用户协议》",
|
||||
"Terms of Use - Tooltip": "用户注册时需要阅读并同意的使用条款",
|
||||
"Text 1": "文本1",
|
||||
@ -1162,6 +1167,7 @@
|
||||
"Values": "值",
|
||||
"Verification code sent": "验证码已发送",
|
||||
"WebAuthn credentials": "WebAuthn凭据",
|
||||
"You have changed the username, please save your change first before modifying the password": "你已经更改了你的用户名,请你再更改密码前保存更改",
|
||||
"input password": "输入密码"
|
||||
},
|
||||
"verification": {
|
||||
|
@ -15,6 +15,7 @@
|
||||
import React from "react";
|
||||
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
|
||||
import {Button, Col, Input, Row, Select, Switch, Table, Tooltip} from "antd";
|
||||
import {CountryCodeSelect} from "../common/select/CountryCodeSelect";
|
||||
import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
import * as Provider from "../auth/Provider";
|
||||
@ -29,6 +30,10 @@ class ProviderTable extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
getUserOrganization() {
|
||||
return this.props.application?.organizationObj;
|
||||
}
|
||||
|
||||
updateTable(table) {
|
||||
this.props.onUpdateTable(table);
|
||||
}
|
||||
@ -79,7 +84,7 @@ class ProviderTable extends React.Component {
|
||||
|
||||
// If the provider is email or SMS, set the rule to "all" instead of the default "None"
|
||||
if (provider.category === "Email" || provider.category === "SMS") {
|
||||
this.updateField(table, index, "rule", "all");
|
||||
this.updateField(table, index, "rule", "All");
|
||||
}
|
||||
}} >
|
||||
{
|
||||
@ -109,6 +114,30 @@ class ProviderTable extends React.Component {
|
||||
return Provider.getProviderLogoWidget(provider);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("user:Country/Region"),
|
||||
dataIndex: "countryCodes",
|
||||
key: "countryCodes",
|
||||
width: "140px",
|
||||
render: (text, record, index) => {
|
||||
if (record.provider?.category !== "SMS") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<CountryCodeSelect
|
||||
style={{width: "100%"}}
|
||||
hasDefault={true}
|
||||
mode={"multiple"}
|
||||
initValue={text ? text : ["All"]}
|
||||
onChange={(value) => {
|
||||
this.updateField(table, index, "countryCodes", value);
|
||||
}}
|
||||
countryCodes={this.getUserOrganization()?.countryCodes}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("provider:Can signup"),
|
||||
dataIndex: "canSignUp",
|
||||
@ -198,7 +227,7 @@ class ProviderTable extends React.Component {
|
||||
title: i18next.t("application:Rule"),
|
||||
dataIndex: "rule",
|
||||
key: "rule",
|
||||
width: "120px",
|
||||
width: "160px",
|
||||
render: (text, record, index) => {
|
||||
if (record.provider?.type === "Google") {
|
||||
if (text === "None") {
|
||||
@ -230,12 +259,12 @@ class ProviderTable extends React.Component {
|
||||
);
|
||||
} else if (record.provider?.category === "SMS" || record.provider?.category === "Email") {
|
||||
if (text === "None") {
|
||||
text = "all";
|
||||
text = "All";
|
||||
}
|
||||
return (
|
||||
<Select virtual={false} style={{width: "100%"}}
|
||||
value={text}
|
||||
defaultValue="all"
|
||||
defaultValue="All"
|
||||
onChange={value => {
|
||||
this.updateField(table, index, "rule", value);
|
||||
}}>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user