Compare commits

...

15 Commits

Author SHA1 Message Date
b867872da4 fix: return right after error response on GetUserInfo (#707) 2022-04-26 14:32:04 +08:00
305867f49a Add checkError() to payment. 2022-04-25 21:39:46 +08:00
3f90c18a19 Add invoiceType to payment. 2022-04-25 20:58:53 +08:00
9e5a64c021 Add new payment fields 2022-04-25 20:40:50 +08:00
4263af6f2c Fix frontend warnings. 2022-04-25 20:00:57 +08:00
3e92d761b9 Fix i18n translations. 2022-04-25 19:46:45 +08:00
0e41568f62 Add apps to homepage. 2022-04-25 13:51:46 +08:00
fb7e2729c6 fix: support Microsoft AD user search (#704) 2022-04-25 12:20:59 +08:00
28b9154d7e fix: fix #693 token error (#695) 2022-04-23 01:12:06 +08:00
b0b3eb0805 fix: fix failure of introspection (#682)
* fix: fix failure of introspection

* Update token.go

Co-authored-by: Yang Luo <hsluoyz@qq.com>
2022-04-22 22:45:52 +08:00
73bd9dd517 bugfix #664 Casdoor fails to start when there is already a database (#681)
Signed-off-by: niko7g <niko7.g@gmail.com>
2022-04-22 22:17:03 +08:00
0bc8c2d15f fix: recover when goroutine panic that will kill main program (#692)
* fix #684

recover when goroutine panic that will kill main program

* Update util.go

Co-authored-by: Yang Luo <hsluoyz@qq.com>
2022-04-22 21:59:06 +08:00
7b78e60265 fix: close the resp in time (#689) 2022-04-21 23:22:50 +08:00
7464f9a8ad fix: when req error, read body(nil) will panic (#690) 2022-04-21 22:14:01 +08:00
d3a7a062d3 fix #687 (#688)
fix the display bug on the personal binding information page
2022-04-21 21:52:34 +08:00
36 changed files with 751 additions and 171 deletions

View File

@ -80,10 +80,9 @@ p, *, *, GET, /api/get-app-login, *, *
p, *, *, POST, /api/logout, *, *
p, *, *, GET, /api/get-account, *, *
p, *, *, GET, /api/userinfo, *, *
p, *, *, POST, /api/login/oauth/access_token, *, *
p, *, *, POST, /api/login/oauth/refresh_token, *, *
p, *, *, GET, /api/login/oauth/logout, *, *
p, *, *, *, /api/login/oauth, *, *
p, *, *, GET, /api/get-application, *, *
p, *, *, GET, /api/get-applications, *, *
p, *, *, GET, /api/get-user, *, *
p, *, *, GET, /api/get-user-application, *, *
p, *, *, GET, /api/get-resources, *, *

View File

@ -210,7 +210,7 @@ func (c *ApiController) Signup() {
record := object.NewRecord(c.Ctx)
record.Organization = application.Organization
record.User = user.Name
go object.AddRecord(record)
util.SafeGoroutine(func() { object.AddRecord(record) })
userId := fmt.Sprintf("%s/%s", user.Owner, user.Name)
util.LogInfo(c.Ctx, "API: [%s] is signed up as new user", userId)
@ -285,6 +285,7 @@ func (c *ApiController) GetUserinfo() {
resp, err := object.GetUserInfo(userId, scope, aud, host)
if err != nil {
c.ResponseError(err.Error())
return
}
c.Data["json"] = resp
c.ServeJSON()

View File

@ -248,7 +248,7 @@ func (c *ApiController) Login() {
record := object.NewRecord(c.Ctx)
record.Organization = application.Organization
record.User = user.Name
go object.AddRecord(record)
util.SafeGoroutine(func() {object.AddRecord(record)})
}
} else if form.Provider != "" {
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
@ -341,7 +341,7 @@ func (c *ApiController) Login() {
record := object.NewRecord(c.Ctx)
record.Organization = application.Organization
record.User = user.Name
go object.AddRecord(record)
util.SafeGoroutine(func() {object.AddRecord(record)})
} else if provider.Category == "OAuth" {
// Sign up via OAuth
if !application.EnableSignUp {
@ -390,7 +390,7 @@ func (c *ApiController) Login() {
record := object.NewRecord(c.Ctx)
record.Organization = application.Organization
record.User = user.Name
go object.AddRecord(record)
util.SafeGoroutine(func() {object.AddRecord(record)})
} else if provider.Category == "SAML" {
resp = &Response{Status: "error", Msg: "The account does not exist"}
}

View File

@ -230,7 +230,7 @@ func (c *ApiController) RefreshToken() {
clientSecret = tokenRequest.ClientSecret
grantType = tokenRequest.GrantType
scope = tokenRequest.Scope
refreshToken = tokenRequest.RefreshToken
}
}
@ -275,21 +275,20 @@ func (c *ApiController) IntrospectToken() {
tokenValue := c.Input().Get("token")
clientId, clientSecret, ok := c.Ctx.Request.BasicAuth()
if !ok {
util.LogWarning(c.Ctx, "Basic Authorization parses failed")
c.Data["json"] = Response{Status: "error", Msg: "Unauthorized operation"}
c.ServeJSON()
return
clientId = c.Input().Get("client_id")
clientSecret = c.Input().Get("client_secret")
if clientId == "" || clientSecret == "" {
c.ResponseError("empty clientId or clientSecret")
return
}
}
application := object.GetApplicationByClientId(clientId)
if application == nil || application.ClientSecret != clientSecret {
util.LogWarning(c.Ctx, "Basic Authorization failed")
c.Data["json"] = Response{Status: "error", Msg: "Unauthorized operation"}
c.ServeJSON()
c.ResponseError("invalid application or wrong clientSecret")
return
}
token := object.GetTokenByTokenAndApplication(tokenValue, application.Name)
if token == nil {
util.LogWarning(c.Ctx, "application: %s can not find token", application.Name)
c.Data["json"] = &object.IntrospectionResponse{Active: false}
c.ServeJSON()
return
@ -299,7 +298,6 @@ func (c *ApiController) IntrospectToken() {
// and token revoked case. but we not implement
// TODO: 2022-03-03 add token revoked check, when we implemented the Token Revocation(rfc7009) Specs.
// refs: https://tools.ietf.org/html/rfc7009
util.LogWarning(c.Ctx, "token invalid")
c.Data["json"] = &object.IntrospectionResponse{Active: false}
c.ServeJSON()
return

View File

@ -25,4 +25,5 @@ type TokenRequest struct {
Password string `json:"password"`
Tag string `json:"tag"`
Avatar string `json:"avatar"`
RefreshToken string `json:"refresh_token"`
}

2
go.mod
View File

@ -44,5 +44,5 @@ require (
gopkg.in/square/go-jose.v2 v2.6.0
gopkg.in/yaml.v2 v2.3.0 // indirect
xorm.io/core v0.7.2
xorm.io/xorm v1.0.3
xorm.io/xorm v1.0.4
)

5
go.sum
View File

@ -258,8 +258,6 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/ma314smith/signedxml v0.0.0-20210628192057-abc5b481ae1c h1:UPJygtyk491bJJ/DnRJFuzcq9Dl9NSeFrJ7VdiRzMxc=
github.com/ma314smith/signedxml v0.0.0-20210628192057-abc5b481ae1c/go.mod h1:KEgVcb43+f5KFUH/x6Vd3NROG0AIL2CuKMrIqYsmx6E=
github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0=
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911 h1:erppMjjp69Rertg1zlgRbLJH1u+eCmRPxKjMZ5I8/Ro=
@ -696,5 +694,6 @@ xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
xorm.io/xorm v1.0.3 h1:3dALAohvINu2mfEix5a5x5ZmSVGSljinoSGgvGbaZp0=
xorm.io/xorm v1.0.3/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
xorm.io/xorm v1.0.4 h1:UBXA4I3NhiyjXfPqxXUkS2t5hMta9SSPATeMMaZg9oA=
xorm.io/xorm v1.0.4/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=

View File

@ -131,6 +131,7 @@ func (idp *CasdoorIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {

View File

@ -82,6 +82,7 @@ func (idp *CustomIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {

View File

@ -143,6 +143,7 @@ func (idp *DingTalkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {

View File

@ -169,8 +169,11 @@ func (idp *LarkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
req.Header.Set("Authorization", "Bearer "+token.AccessToken)
resp, err := idp.Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err = ioutil.ReadAll(resp.Body)
err = resp.Body.Close()
if err != nil {
return nil, err
}

View File

@ -27,6 +27,7 @@ import (
"github.com/casdoor/casdoor/proxy"
"github.com/casdoor/casdoor/routers"
_ "github.com/casdoor/casdoor/routers"
"github.com/casdoor/casdoor/util"
)
func main() {
@ -40,7 +41,7 @@ func main() {
proxy.InitHttpClient()
authz.InitAuthz()
go object.RunSyncUsersJob()
util.SafeGoroutine(func() {object.RunSyncUsersJob()})
//beego.DelStaticPath("/static")
beego.SetStaticPath("/static", "web/build/static")

View File

@ -42,6 +42,7 @@ type Ldap struct {
type ldapConn struct {
Conn *goldap.Conn
IsAD bool
}
//type ldapGroup struct {
@ -78,6 +79,13 @@ type LdapRespUser struct {
Address string `json:"address"`
}
type ldapServerType struct {
Vendorname string
Vendorversion string
IsGlobalCatalogReady string
ForestFunctionality string
}
func LdapUsersToLdapRespUsers(users []ldapUser) []LdapRespUser {
returnAnyNotEmpty := func(strs ...string) string {
for _, str := range strs {
@ -104,6 +112,45 @@ func LdapUsersToLdapRespUsers(users []ldapUser) []LdapRespUser {
return res
}
func isMicrosoftAD(Conn *goldap.Conn) (bool, error) {
SearchFilter := "(objectclass=*)"
SearchAttributes := []string{"vendorname", "vendorversion", "isGlobalCatalogReady", "forestFunctionality"}
searchReq := goldap.NewSearchRequest("",
goldap.ScopeBaseObject, goldap.NeverDerefAliases, 0, 0, false,
SearchFilter, SearchAttributes, nil)
searchResult, err := Conn.Search(searchReq)
if err != nil {
return false, err
}
if len(searchResult.Entries) == 0 {
return false, errors.New("no result")
}
isMicrosoft := false
var ldapServerType ldapServerType
for _, entry := range searchResult.Entries {
for _, attribute := range entry.Attributes {
switch attribute.Name {
case "vendorname":
ldapServerType.Vendorname = attribute.Values[0]
case "vendorversion":
ldapServerType.Vendorversion = attribute.Values[0]
case "isGlobalCatalogReady":
ldapServerType.IsGlobalCatalogReady = attribute.Values[0]
case "forestFunctionality":
ldapServerType.ForestFunctionality = attribute.Values[0]
}
}
}
if ldapServerType.Vendorname == "" &&
ldapServerType.Vendorversion == "" &&
ldapServerType.IsGlobalCatalogReady == "TRUE" &&
ldapServerType.ForestFunctionality != "" {
isMicrosoft = true
}
return isMicrosoft, err
}
func GetLdapConn(host string, port int, adminUser string, adminPasswd string) (*ldapConn, error) {
conn, err := goldap.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
if err != nil {
@ -115,7 +162,11 @@ func GetLdapConn(host string, port int, adminUser string, adminPasswd string) (*
return nil, fmt.Errorf("fail to login Ldap server with [%s]", adminUser)
}
return &ldapConn{Conn: conn}, nil
isAD, err := isMicrosoftAD(conn)
if err != nil {
return nil, fmt.Errorf("fail to get Ldap server type [%s]", adminUser)
}
return &ldapConn{Conn: conn, IsAD: isAD}, nil
}
//FIXME: The Base DN does not necessarily contain the Group
@ -158,10 +209,19 @@ func (l *ldapConn) GetLdapUsers(baseDn string) ([]ldapUser, error) {
SearchFilter := "(objectClass=posixAccount)"
SearchAttributes := []string{"uidNumber", "uid", "cn", "gidNumber", "entryUUID", "mail", "email",
"emailAddress", "telephoneNumber", "mobile", "mobileTelephoneNumber", "registeredAddress", "postalAddress"}
searchReq := goldap.NewSearchRequest(baseDn,
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
SearchFilter, SearchAttributes, nil)
SearchFilterMsAD := "(objectClass=user)"
SearchAttributesMsAD := []string{"uidNumber", "sAMAccountName", "cn", "gidNumber", "entryUUID", "mail", "email",
"emailAddress", "telephoneNumber", "mobile", "mobileTelephoneNumber", "registeredAddress", "postalAddress"}
var searchReq *goldap.SearchRequest
if l.IsAD {
searchReq = goldap.NewSearchRequest(baseDn,
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
SearchFilterMsAD, SearchAttributesMsAD, nil)
} else {
searchReq = goldap.NewSearchRequest(baseDn,
goldap.ScopeWholeSubtree, goldap.NeverDerefAliases, 0, 0, false,
SearchFilter, SearchAttributes, nil)
}
searchResult, err := l.Conn.SearchWithPaging(searchReq, 100)
if err != nil {
return nil, err
@ -180,12 +240,14 @@ func (l *ldapConn) GetLdapUsers(baseDn string) ([]ldapUser, error) {
case "uidNumber":
ldapUserItem.UidNumber = attribute.Values[0]
case "uid":
case "sAMAccountName":
ldapUserItem.Uid = attribute.Values[0]
case "cn":
ldapUserItem.Cn = attribute.Values[0]
case "gidNumber":
ldapUserItem.GidNumber = attribute.Values[0]
case "entryUUID":
case "objectGUID":
ldapUserItem.Uuid = attribute.Values[0]
case "mail":
ldapUserItem.Mail = attribute.Values[0]

View File

@ -6,6 +6,7 @@ import (
"time"
"github.com/astaxie/beego/logs"
"github.com/casdoor/casdoor/util"
)
type LdapAutoSynchronizer struct {
@ -47,7 +48,7 @@ func (l *LdapAutoSynchronizer) StartAutoSync(ldapId string) error {
stopChan := make(chan struct{})
l.ldapIdToStopChan[ldapId] = stopChan
logs.Info(fmt.Sprintf("autoSync started for %s", ldap.Id))
go l.syncRoutine(ldap, stopChan)
util.SafeGoroutine(func() {l.syncRoutine(ldap, stopChan)})
return nil
}

View File

@ -44,6 +44,15 @@ type Payment struct {
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
State string `xorm:"varchar(100)" json:"state"`
Message string `xorm:"varchar(1000)" json:"message"`
PersonName string `xorm:"varchar(100)" json:"personName"`
PersonIdCard string `xorm:"varchar(100)" json:"personIdCard"`
PersonEmail string `xorm:"varchar(100)" json:"personEmail"`
PersonPhone string `xorm:"varchar(100)" json:"personPhone"`
InvoiceType string `xorm:"varchar(100)" json:"invoiceType"`
InvoiceTitle string `xorm:"varchar(100)" json:"invoiceTitle"`
InvoiceTaxId string `xorm:"varchar(100)" json:"invoiceTaxId"`
InvoiceRemark string `xorm:"varchar(100)" json:"invoiceRemark"`
}
func GetPaymentCount(owner, field, value string) int {

View File

@ -104,6 +104,11 @@ func getUrlPath(urlPath string) string {
if strings.HasPrefix(urlPath, "/cas") && (strings.HasSuffix(urlPath, "/serviceValidate") || strings.HasSuffix(urlPath, "/proxy") || strings.HasSuffix(urlPath, "/proxyValidate") || strings.HasSuffix(urlPath, "/validate") || strings.HasSuffix(urlPath, "/p3/serviceValidate") || strings.HasSuffix(urlPath, "/p3/proxyValidate") || strings.HasSuffix(urlPath, "/samlValidate")) {
return "/cas"
}
if strings.HasPrefix(urlPath, "/api/login/oauth") {
return "/api/login/oauth"
}
return urlPath
}

View File

@ -65,5 +65,5 @@ func RecordMessage(ctx *context.Context) {
record.Organization, record.User = util.GetOwnerAndNameFromId(userId)
}
go object.AddRecord(record)
util.SafeGoroutine(func() {object.AddRecord(record)})
}

38
util/util.go Normal file
View File

@ -0,0 +1,38 @@
// Copyright 2022 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 util
import (
"fmt"
"github.com/astaxie/beego/logs"
)
func SafeGoroutine(fn func()) {
var err error
go func() {
defer func() {
if r := recover(); r != nil {
var ok bool
err, ok = r.(error)
if !ok {
err = fmt.Errorf("%v", r)
}
logs.Error("goroutine panic: %v", err)
}
}()
fn()
}()
}

View File

@ -27,7 +27,6 @@ export const CropperDiv = (props) => {
const [confirmLoading, setConfirmLoading] = React.useState(false);
const {title} = props;
const {user} = props;
const {account} = props;
const {buttonText} = props;
let uploadButton;

View File

@ -13,11 +13,13 @@
// limitations under the License.
import React from "react";
import {Button, Card, Col, Input, Row} from 'antd';
import {Button, Card, Col, Input, Row, Select} from 'antd';
import * as PaymentBackend from "./backend/PaymentBackend";
import * as Setting from "./Setting";
import i18next from "i18next";
const { Option } = Select;
class PaymentEditPage extends React.Component {
constructor(props) {
super(props);
@ -75,7 +77,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.organization} onChange={e => {
<Input disabled={true} value={this.state.payment.organization} onChange={e => {
// this.updatePaymentField('organization', e.target.value);
}} />
</Col>
@ -85,7 +87,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.name} onChange={e => {
<Input disabled={true} value={this.state.payment.name} onChange={e => {
// this.updatePaymentField('name', e.target.value);
}} />
</Col>
@ -95,7 +97,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Display name"), i18next.t("general:Display name - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.displayName} onChange={e => {
<Input disabled={true} value={this.state.payment.displayName} onChange={e => {
this.updatePaymentField('displayName', e.target.value);
}} />
</Col>
@ -105,7 +107,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Provider"), i18next.t("general:Provider - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.provider} onChange={e => {
<Input disabled={true} value={this.state.payment.provider} onChange={e => {
// this.updatePaymentField('provider', e.target.value);
}} />
</Col>
@ -115,7 +117,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("payment:Type"), i18next.t("payment:Type - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.type} onChange={e => {
<Input disabled={true} value={this.state.payment.type} onChange={e => {
// this.updatePaymentField('type', e.target.value);
}} />
</Col>
@ -125,7 +127,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("payment:Product"), i18next.t("payment:Product - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.productName} onChange={e => {
<Input disabled={true} value={this.state.payment.productName} onChange={e => {
// this.updatePaymentField('productName', e.target.value);
}} />
</Col>
@ -135,7 +137,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("payment:Price"), i18next.t("payment:Price - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.price} onChange={e => {
<Input disabled={true} value={this.state.payment.price} onChange={e => {
// this.updatePaymentField('amount', e.target.value);
}} />
</Col>
@ -145,7 +147,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("payment:Currency"), i18next.t("payment:Currency - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.currency} onChange={e => {
<Input disabled={true} value={this.state.payment.currency} onChange={e => {
// this.updatePaymentField('currency', e.target.value);
}} />
</Col>
@ -155,7 +157,7 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("payment:State"), i18next.t("payment:State - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.state} onChange={e => {
<Input disabled={true} value={this.state.payment.state} onChange={e => {
// this.updatePaymentField('state', e.target.value);
}} />
</Col>
@ -165,18 +167,161 @@ class PaymentEditPage extends React.Component {
{Setting.getLabel(i18next.t("payment:Message"), i18next.t("payment:Message - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.message} onChange={e => {
<Input disabled={true} value={this.state.payment.message} onChange={e => {
// this.updatePaymentField('message', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Person name"), i18next.t("payment:Person name - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.personName} onChange={e => {
this.updatePaymentField('personName', e.target.value);
if (this.state.payment.invoiceType === "Individual") {
this.updatePaymentField('invoiceTitle', e.target.value);
this.updatePaymentField('invoiceTaxId', "");
}
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Person ID card"), i18next.t("payment:Person ID card - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.personIdCard} onChange={e => {
this.updatePaymentField('personIdCard', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Person Email"), i18next.t("payment:Person Email - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.personEmail} onChange={e => {
this.updatePaymentField('personEmail', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Person phone"), i18next.t("payment:Person phone - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.personPhone} onChange={e => {
this.updatePaymentField('personPhone', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Invoice type"), i18next.t("payment:Invoice type - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: '100%'}} value={this.state.payment.invoiceType} onChange={(value => {
this.updatePaymentField('invoiceType', value);
if (value === "Individual") {
this.updatePaymentField('invoiceTitle', this.state.payment.personName);
this.updatePaymentField('invoiceTaxId', "");
}
})}>
{
[
{id: 'Individual', name: i18next.t("payment:Individual")},
{id: 'Organization', name: i18next.t("payment:Organization")},
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Invoice title"), i18next.t("payment:Invoice title - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={this.state.payment.invoiceType === "Individual"} value={this.state.payment.invoiceTitle} onChange={e => {
this.updatePaymentField('invoiceTitle', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Invoice Tax ID"), i18next.t("payment:Invoice Tax ID - Tooltip"))} :
</Col>
<Col span={22} >
<Input disabled={this.state.payment.invoiceType === "Individual"} value={this.state.payment.invoiceTaxId} onChange={e => {
this.updatePaymentField('invoiceTaxId', e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: '20px'}} >
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("payment:Invoice remark"), i18next.t("payment:Invoice remark - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.payment.invoiceRemark} onChange={e => {
this.updatePaymentField('invoiceRemark', e.target.value);
}} />
</Col>
</Row>
</Card>
)
}
checkError() {
if (!Setting.isValidPersonName(this.state.payment.personName)) {
return i18next.t("signup:Please input your real name!");
}
if (!Setting.isValidIdCard(this.state.payment.personIdCard)) {
return i18next.t("signup:Please input the correct ID card number!");
}
if (!Setting.isValidEmail(this.state.payment.personEmail)) {
return i18next.t("signup:The input is not valid Email!");
}
if (!Setting.isValidPhone(this.state.payment.personPhone)) {
return i18next.t("signup:The input is not valid Phone!");
}
if (!Setting.isValidPhone(this.state.payment.personPhone)) {
return i18next.t("signup:The input is not valid Phone!");
}
if (this.state.payment.invoiceType === "Individual") {
if (this.state.payment.invoiceTitle !== "") {
return i18next.t("signup:The input is not invoice title!");
}
if (this.state.payment.invoiceTaxId !== "") {
return i18next.t("signup:The input is not invoice Tax ID!");
}
} else {
if (!Setting.isValidInvoiceTitle(this.state.payment.invoiceTitle)) {
return i18next.t("signup:The input is not invoice title!");
}
if (!Setting.isValidTaxId(this.state.payment.invoiceTaxId)) {
return i18next.t("signup:The input is not invoice Tax ID!");
}
}
return "";
}
submitPaymentEdit(willExist) {
const errorText = this.checkError();
if (errorText !== "") {
Setting.showMessage("error", errorText);
return;
}
let payment = Setting.deepCopy(this.state.payment);
PaymentBackend.updatePayment(this.state.organizationName, this.state.paymentName, payment)
PaymentBackend.updatePayment(this.state.payment.owner, this.state.paymentName, payment)
.then((res) => {
if (res.msg === "") {
Setting.showMessage("success", `Successfully saved`);

View File

@ -148,7 +148,7 @@ class ProductBuyPage extends React.Component {
return (
<Button style={{height: "50px", borderWidth: "2px"}} shape="round" icon={
<img style={{marginRight: "10px"}} width={36} height={36} src={Provider.getProviderLogo(provider)} alt={provider.displayName} />
<img style={{marginRight: "10px"}} width={36} height={36} src={Setting.getProviderLogoURL(provider)} alt={provider.displayName} />
} size={"large"} >
{
text

View File

@ -32,6 +32,79 @@ export const StaticBaseUrl = "https://cdn.casbin.org";
// https://catamphetamine.gitlab.io/country-flag-icons/3x2/index.html
export const CountryRegionData = getCountryRegionData();
export const OtherProviderInfo = {
SMS: {
"Aliyun SMS": {
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
url: "https://aliyun.com/product/sms",
},
"Tencent Cloud SMS": {
logo: `${StaticBaseUrl}/img/social_tencent_cloud.jpg`,
url: "https://cloud.tencent.com/product/sms",
},
"Volc Engine SMS": {
logo: `${StaticBaseUrl}/img/social_volc_engine.jpg`,
url: "https://www.volcengine.com/products/cloud-sms",
},
"Huawei Cloud SMS": {
logo: `${StaticBaseUrl}/img/social_huawei.png`,
url: "https://www.huaweicloud.com/product/msgsms.html",
},
},
Email: {
"Default": {
logo: `${StaticBaseUrl}/img/social_default.png`,
url: "",
},
},
Storage: {
"Local File System": {
logo: `${StaticBaseUrl}/img/social_file.png`,
url: "",
},
"AWS S3": {
logo: `${StaticBaseUrl}/img/social_aws.png`,
url: "https://aws.amazon.com/s3",
},
"Aliyun OSS": {
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
url: "https://aliyun.com/product/oss",
},
"Tencent Cloud COS": {
logo: `${StaticBaseUrl}/img/social_tencent_cloud.jpg`,
url: "https://cloud.tencent.com/product/cos",
},
},
SAML: {
"Aliyun IDaaS": {
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
url: "https://aliyun.com/product/idaas"
},
"Keycloak": {
logo: `${StaticBaseUrl}/img/social_keycloak.png`,
url: "https://www.keycloak.org/"
},
},
Payment: {
"Alipay": {
logo: `${StaticBaseUrl}/img/payment_alipay.png`,
url: "https://www.alipay.com/"
},
"WeChat Pay": {
logo: `${StaticBaseUrl}/img/payment_wechat_pay.png`,
url: "https://pay.weixin.qq.com/"
},
"PayPal": {
logo: `${StaticBaseUrl}/img/payment_paypal.png`,
url: "https://www.paypal.com/"
},
"GC": {
logo: `${StaticBaseUrl}/img/payment_gc.png`,
url: "https://gc.org"
},
},
};
export function getCountryRegionData() {
let language = i18next.language;
if (language === null || language === "null") {
@ -115,6 +188,17 @@ export function getSignupItem(application, itemName) {
return signupItems[0];
}
export function isValidPersonName(personName) {
// https://blog.css8.cn/post/14210975.html
const personNameRegex = /^[\u4e00-\u9fa5]{2,6}$/;
return personNameRegex.test(personName);
}
export function isValidIdCard(idCard) {
const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9X]$/;
return idCardRegex.test(idCard);
}
export function isValidEmail(email) {
// https://github.com/yiminghe/async-validator/blob/057b0b047f88fac65457bae691d6cb7c6fe48ce1/src/rule/type.ts#L9
const emailRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
@ -127,6 +211,23 @@ export function isValidPhone(phone) {
return phoneRegex.test(phone);
}
export function isValidInvoiceTitle(invoiceTitle) {
// https://blog.css8.cn/post/14210975.html
const invoiceTitleRegex = /^[\(\)\\\u4e00-\u9fa5]{0,50}$/;
return invoiceTitleRegex.test(invoiceTitle);
}
export function isValidTaxId(taxId) {
// https://www.codetd.com/article/8592083
const regArr = [/^[\da-z]{10,15}$/i, /^\d{6}[\da-z]{10,12}$/i, /^[a-z]\d{6}[\da-z]{9,11}$/i, /^[a-z]{2}\d{6}[\da-z]{8,10}$/i, /^\d{14}[\dx][\da-z]{4,5}$/i, /^\d{17}[\dx][\da-z]{1,2}$/i, /^[a-z]\d{14}[\dx][\da-z]{3,4}$/i, /^[a-z]\d{17}[\dx][\da-z]{0,1}$/i, /^[\d]{6}[\da-z]{13,14}$/i];
for (let i = 0; i < regArr.length; i++) {
if (regArr[i].test(taxId)) {
return true;
}
}
return false;
}
export function isAffiliationPrompted(application) {
const signupItem = getSignupItem(application, "Affiliation");
if (signupItem === null) {
@ -204,6 +305,11 @@ export function goToLink(link) {
}
export function goToLinkSoft(ths, link) {
if (link.startsWith("http")) {
openLink(link);
return;
}
ths.props.history.push(link);
}
@ -380,9 +486,20 @@ export function getClickable(text) {
)
}
export function getProviderLogoURL(provider) {
if (provider.category === "OAuth") {
if (provider.type === "Custom") {
return provider.customLogo;
}
return `${StaticBaseUrl}/img/social_${provider.type.toLowerCase()}.png`;
} else {
return OtherProviderInfo[provider.category][provider.type].logo;
}
}
export function getProviderLogo(provider) {
const idp = provider.type.toLowerCase().trim().split(' ')[0];
const url = `${StaticBaseUrl}/img/social_${idp}.png`;
const url = getProviderLogoURL(provider);
return (
<img width={30} height={30} src={url} alt={idp} />
)

View File

@ -19,7 +19,6 @@ import moment from "moment";
import * as Setting from "./Setting";
import * as TokenBackend from "./backend/TokenBackend";
import i18next from "i18next";
import * as ResourceBackend from "./backend/ResourceBackend";
import BaseListPage from "./BaseListPage";
class TokenListPage extends BaseListPage {

View File

@ -21,7 +21,6 @@ import * as Setting from "./Setting";
import * as UserBackend from "./backend/UserBackend";
import i18next from "i18next";
import BaseListPage from "./BaseListPage";
import * as path from "path";
class UserListPage extends BaseListPage {
constructor(props) {

View File

@ -149,7 +149,7 @@ class LoginPage extends React.Component {
AuthBackend.loginCas(values, casParams).then((res) => {
if (res.status === 'ok') {
let msg = "Logged in successfully. "
if (casParams.service == "") {
if (casParams.service === "") {
//If service was not specified, CAS MUST display a message notifying the client that it has successfully initiated a single sign-on session.
msg += "Now you can visit apps protected by casdoor."
}
@ -305,13 +305,13 @@ class LoginPage extends React.Component {
if (provider.category === "OAuth") {
return (
<a key={provider.displayName} href={Provider.getAuthUrl(application, provider, "signup")}>
<img width={width} height={width} src={Provider.getProviderLogo(provider)} alt={provider.displayName} style={{margin: margin}} />
<img width={width} height={width} src={Setting.getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
</a>
)
} else if (provider.category === "SAML") {
return (
<a key={provider.displayName} onClick={this.getSamlUrl.bind(this, provider)}>
<img width={width} height={width} src={Provider.getProviderLogo(provider)} alt={provider.displayName} style={{margin: margin}} />
<img width={width} height={width} src={Setting.getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
</a>
)
}
@ -593,6 +593,9 @@ class LoginPage extends React.Component {
return (
<div>
{/*{*/}
{/* JSON.stringify(silentSignin)*/}
{/*}*/}
<div style={{fontSize: 16, textAlign: "left"}}>
{i18next.t("login:Continue with")}&nbsp;:
</div>

View File

@ -112,90 +112,6 @@ const authInfo = {
},
};
const otherProviderInfo = {
SMS: {
"Aliyun SMS": {
logo: `${Setting.StaticBaseUrl}/img/social_aliyun.png`,
url: "https://aliyun.com/product/sms",
},
"Tencent Cloud SMS": {
logo: `${Setting.StaticBaseUrl}/img/social_tencent_cloud.jpg`,
url: "https://cloud.tencent.com/product/sms",
},
"Volc Engine SMS": {
logo: `${Setting.StaticBaseUrl}/img/social_volc_engine.jpg`,
url: "https://www.volcengine.com/products/cloud-sms",
},
"Huawei Cloud SMS": {
logo: `${Setting.StaticBaseUrl}/img/social_huawei.png`,
url: "https://www.huaweicloud.com/product/msgsms.html",
},
},
Email: {
"Default": {
logo: `${Setting.StaticBaseUrl}/img/social_default.png`,
url: "",
},
},
Storage: {
"Local File System": {
logo: `${Setting.StaticBaseUrl}/img/social_file.png`,
url: "",
},
"AWS S3": {
logo: `${Setting.StaticBaseUrl}/img/social_aws.png`,
url: "https://aws.amazon.com/s3",
},
"Aliyun OSS": {
logo: `${Setting.StaticBaseUrl}/img/social_aliyun.png`,
url: "https://aliyun.com/product/oss",
},
"Tencent Cloud COS": {
logo: `${Setting.StaticBaseUrl}/img/social_tencent_cloud.jpg`,
url: "https://cloud.tencent.com/product/cos",
},
},
SAML: {
"Aliyun IDaaS": {
logo: `${Setting.StaticBaseUrl}/img/social_aliyun.png`,
url: "https://aliyun.com/product/idaas"
},
"Keycloak": {
logo: `${Setting.StaticBaseUrl}/img/social_keycloak.png`,
url: "https://www.keycloak.org/"
},
},
Payment: {
"Alipay": {
logo: `${Setting.StaticBaseUrl}/img/payment_alipay.png`,
url: "https://www.alipay.com/"
},
"WeChat Pay": {
logo: `${Setting.StaticBaseUrl}/img/payment_wechat_pay.png`,
url: "https://pay.weixin.qq.com/"
},
"PayPal": {
logo: `${Setting.StaticBaseUrl}/img/payment_paypal.png`,
url: "https://www.paypal.com/"
},
"GC": {
logo: `${Setting.StaticBaseUrl}/img/payment_gc.png`,
url: "https://gc.org"
},
},
};
export function getProviderLogo(provider) {
if (provider.category === "OAuth") {
if (provider.type === "Custom") {
return provider.customLogo;
}
return `${Setting.StaticBaseUrl}/img/social_${provider.type.toLowerCase()}.png`;
} else {
return otherProviderInfo[provider.category][provider.type].logo;
}
}
export function getProviderUrl(provider) {
if (provider.category === "OAuth") {
const endpoint = authInfo[provider.type].endpoint;
@ -210,7 +126,7 @@ export function getProviderUrl(provider) {
return `${urlObj.protocol}//${host}`;
} else {
return otherProviderInfo[provider.category][provider.type].url;
return Setting.OtherProviderInfo[provider.category][provider.type].url;
}
}
@ -224,14 +140,14 @@ export function getProviderLogoWidget(provider) {
return (
<Tooltip title={provider.type}>
<a target="_blank" rel="noreferrer" href={getProviderUrl(provider)}>
<img width={36} height={36} src={getProviderLogo(provider)} alt={provider.displayName} />
<img width={36} height={36} src={Setting.getProviderLogoURL(provider)} alt={provider.displayName} />
</a>
</Tooltip>
)
} else {
return (
<Tooltip title={provider.type}>
<img width={36} height={36} src={getProviderLogo(provider)} alt={provider.displayName} />
<img width={36} height={36} src={Setting.getProviderLogoURL(provider)} alt={provider.displayName} />
</Tooltip>
)
}

View File

@ -14,6 +14,7 @@
import React from "react";
import {Card, Col, Row} from "antd";
import * as ApplicationBackend from "../backend/ApplicationBackend";
import * as Setting from "../Setting";
import SingleCard from "./SingleCard";
import i18next from "i18next";
@ -23,9 +24,23 @@ class HomePage extends React.Component {
super(props);
this.state = {
classes: props,
applications: null,
};
}
UNSAFE_componentWillMount() {
this.getApplicationsByOrganization(this.props.account.owner);
}
getApplicationsByOrganization(organizationName) {
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
.then((res) => {
this.setState({
applications: (res.msg === undefined) ? res : [],
});
});
}
getItems() {
let items = [];
if (Setting.isAdminUser(this.props.account)) {
@ -35,25 +50,32 @@ class HomePage extends React.Component {
{link: "/providers", name: i18next.t("general:Providers"), organizer: i18next.t("general:OAuth providers")},
{link: "/applications", name: i18next.t("general:Applications"), organizer: i18next.t("general:Applications that require authentication")},
];
} else {
items = [
{link: "/account", name: i18next.t("account:My Account"), organizer: i18next.t("account:Settings for your account")},
];
}
for (let i = 0; i < items.length; i ++) {
let filename = items[i].link;
if (filename === "/account") {
filename = "/users";
for (let i = 0; i < items.length; i ++) {
let filename = items[i].link;
if (filename === "/account") {
filename = "/users";
}
items[i].logo = `https://cdn.casbin.com/static/img${filename}.png`;
items[i].createdTime = "";
}
items[i].logo = `https://cdn.casbin.com/static/img${filename}.png`;
items[i].createdTime = "";
} else {
this.state.applications.forEach(application => {
console.log(application)
items.push({
link: application.homepageUrl, name: application.displayName, organizer: application.description, logo: application.logo, createdTime: "",
});
});
}
return items
}
renderCards() {
if (this.state.applications === null) {
return null;
}
const items = this.getItems();
if (Setting.isMobile()) {

View File

@ -51,10 +51,10 @@ class SingleCard extends React.Component {
<Card
hoverable
cover={
<img alt="logo" src={logo} width={"100%"} height={"100%"} />
<img alt="logo" src={logo} style={{width: "100%", height: "210px", objectFit: "scale-down"}} />
}
onClick={() => Setting.goToLinkSoft(this, link)}
style={isSingle ? {width: "320px"} : null}
style={isSingle ? {width: "320px"} : {width: "100%"}}
>
<Meta title={title} description={desc} />
<br/>

View File

@ -18,8 +18,6 @@ import * as Setting from "../Setting";
import i18next from "i18next";
import * as UserBackend from "../backend/UserBackend";
import {SafetyOutlined} from "@ant-design/icons";
import * as Util from "../auth/Util";
import {isValidEmail, isValidPhone} from "../Setting";
const { Search } = Input;

View File

@ -3,7 +3,6 @@
"Login": "Anmelden",
"Logout": "Abmelden",
"My Account": "Mein Konto",
"Settings for your account": "Einstellungen für Ihr Konto",
"Sign Up": "Registrieren"
},
"application": {
@ -171,9 +170,11 @@
"Signup application": "Signup application",
"Signup application - Tooltip": "Signup application - Tooltip",
"Sorry, the page you visited does not exist.": "Die von Ihnen besuchte Seite existiert leider nicht.",
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",
"Timestamp": "Zeitstempel",
"Tokens": "Token",
@ -223,7 +224,7 @@
"Continue with": "Weiter mit",
"Email or phone": "E-Mail oder Telefon",
"Forgot password?": "Passwort vergessen?",
"Invalid Email or phone": "Ungültige E-Mail oder Telefon",
"Logging out...": "Logging out...",
"No account?": "Kein Konto?",
"Or sign in with another account": "Oder melden Sie sich mit einem anderen Konto an",
"Password": "Passwort",
@ -246,6 +247,8 @@
"Default avatar": "Standard Avatar",
"Edit Organization": "Organisation bearbeiten",
"Favicon": "Févicon",
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "Is profile public - Tooltip",
"New Organization": "New Organization",
"Soft deletion": "Weiche Löschung",
"Soft deletion - Tooltip": "Weiche Löschung - Tooltip",
@ -258,7 +261,27 @@
"Currency": "Currency",
"Currency - Tooltip": "Currency - Tooltip",
"Edit Payment": "Edit Payment",
"Individual": "Individual",
"Invoice Tax ID": "Invoice Tax ID",
"Invoice Tax ID - Tooltip": "Invoice Tax ID - Tooltip",
"Invoice remark": "Invoice remark",
"Invoice remark - Tooltip": "Invoice remark - Tooltip",
"Invoice title": "Invoice title",
"Invoice title - Tooltip": "Invoice title - Tooltip",
"Invoice type": "Invoice type",
"Invoice type - Tooltip": "Invoice type - Tooltip",
"Message": "Message",
"Message - Tooltip": "Message - Tooltip",
"New Payment": "New Payment",
"Organization": "Organization",
"Person Email": "Person Email",
"Person Email - Tooltip": "Person Email - Tooltip",
"Person ID card": "Person ID card",
"Person ID card - Tooltip": "Person ID card - Tooltip",
"Person name": "Person name",
"Person name - Tooltip": "Person name - Tooltip",
"Person phone": "Person phone",
"Person phone - Tooltip": "Person phone - Tooltip",
"Please click the below button to return to the original website": "Please click the below button to return to the original website",
"Price": "Price",
"Price - Tooltip": "Price - Tooltip",
@ -330,11 +353,19 @@
"Agent ID - Tooltip": "Agent ID - Tooltip",
"App ID": "App ID",
"App ID - Tooltip": "App ID - Tooltip",
"App key": "App key",
"App key - Tooltip": "App key - Tooltip",
"App secret": "App secret",
"AppSecret - Tooltip": "AppSecret - Tooltip",
"Auth URL": "Auth URL",
"Auth URL - Tooltip": "Auth URL - Tooltip",
"Bucket": "Eimer",
"Bucket - Tooltip": "Storage bucket name",
"Can not parse Metadata": "Metadaten können nicht analysiert werden",
"Category": "Kategorie",
"Category - Tooltip": "Unique string-style identifier",
"Channel No.": "Channel No.",
"Channel No. - Tooltip": "Channel No. - Tooltip",
"Client ID": "Kunden-ID",
"Client ID - Tooltip": "Unique string-style identifier",
"Client ID 2": "Client ID 2",
@ -382,6 +413,8 @@
"SP ACS URL": "SP-ACS-URL",
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
"SP Entity ID": "SP Entity ID",
"Scope": "Scope",
"Scope - Tooltip": "Scope - Tooltip",
"Secret access key": "Geheimer Zugangsschlüssel",
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
"Sign Name": "Schild Name",
@ -400,8 +433,12 @@
"Template Code - Tooltip": "Unique string-style identifier",
"Terms of Use": "Nutzungsbedingungen",
"Terms of Use - Tooltip": "Nutzungsbedingungen - Tooltip",
"Token URL": "Token URL",
"Token URL - Tooltip": "Token URL - Tooltip",
"Type": "Typ",
"Type - Tooltip": "Unique string-style identifier",
"UserInfo URL": "UserInfo URL",
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
"alertType": "alarmtyp",
"canSignIn": "canSignIn",
"canSignUp": "canSignUp",
@ -455,6 +492,8 @@
"Please input your real name!": "Bitte geben Sie Ihren persönlichen Namen ein!",
"Please select your country/region!": "Bitte wählen Sie Ihr Land/Ihre Region!",
"Terms of Use": "Nutzungsbedingungen",
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
"The input is not invoice title!": "The input is not invoice title!",
"The input is not valid Email!": "Die Eingabe ist ungültig!",
"The input is not valid Phone!": "Die Eingabe ist nicht gültig!",
"Unknown Check Type": "Unbekannter Schecktyp",

View File

@ -3,7 +3,6 @@
"Login": "Login",
"Logout": "Logout",
"My Account": "My Account",
"Settings for your account": "Settings for your account",
"Sign Up": "Sign Up"
},
"application": {
@ -171,9 +170,11 @@
"Signup application": "Signup application",
"Signup application - Tooltip": "Signup application - Tooltip",
"Sorry, the page you visited does not exist.": "Sorry, the page you visited does not exist.",
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
@ -223,7 +224,7 @@
"Continue with": "Continue with",
"Email or phone": "Email or phone",
"Forgot password?": "Forgot password?",
"Invalid Email or phone": "Invalid Email or phone",
"Logging out...": "Logging out...",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Password": "Password",
@ -246,6 +247,8 @@
"Default avatar": "Default avatar",
"Edit Organization": "Edit Organization",
"Favicon": "Favicon",
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "Is profile public - Tooltip",
"New Organization": "New Organization",
"Soft deletion": "Soft deletion",
"Soft deletion - Tooltip": "Soft deletion - Tooltip",
@ -258,7 +261,27 @@
"Currency": "Currency",
"Currency - Tooltip": "Currency - Tooltip",
"Edit Payment": "Edit Payment",
"Individual": "Individual",
"Invoice Tax ID": "Invoice Tax ID",
"Invoice Tax ID - Tooltip": "Invoice Tax ID - Tooltip",
"Invoice remark": "Invoice remark",
"Invoice remark - Tooltip": "Invoice remark - Tooltip",
"Invoice title": "Invoice title",
"Invoice title - Tooltip": "Invoice title - Tooltip",
"Invoice type": "Invoice type",
"Invoice type - Tooltip": "Invoice type - Tooltip",
"Message": "Message",
"Message - Tooltip": "Message - Tooltip",
"New Payment": "New Payment",
"Organization": "Organization",
"Person Email": "Person Email",
"Person Email - Tooltip": "Person Email - Tooltip",
"Person ID card": "Person ID card",
"Person ID card - Tooltip": "Person ID card - Tooltip",
"Person name": "Person name",
"Person name - Tooltip": "Person name - Tooltip",
"Person phone": "Person phone",
"Person phone - Tooltip": "Person phone - Tooltip",
"Please click the below button to return to the original website": "Please click the below button to return to the original website",
"Price": "Price",
"Price - Tooltip": "Price - Tooltip",
@ -330,11 +353,19 @@
"Agent ID - Tooltip": "Agent ID - Tooltip",
"App ID": "App ID",
"App ID - Tooltip": "App ID - Tooltip",
"App key": "App key",
"App key - Tooltip": "App key - Tooltip",
"App secret": "App secret",
"AppSecret - Tooltip": "AppSecret - Tooltip",
"Auth URL": "Auth URL",
"Auth URL - Tooltip": "Auth URL - Tooltip",
"Bucket": "Bucket",
"Bucket - Tooltip": "Bucket - Tooltip",
"Can not parse Metadata": "Can not parse Metadata",
"Category": "Category",
"Category - Tooltip": "Category - Tooltip",
"Channel No.": "Channel No.",
"Channel No. - Tooltip": "Channel No. - Tooltip",
"Client ID": "Client ID",
"Client ID - Tooltip": "Client ID - Tooltip",
"Client ID 2": "Client ID 2",
@ -382,6 +413,8 @@
"SP ACS URL": "SP ACS URL",
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
"SP Entity ID": "SP Entity ID",
"Scope": "Scope",
"Scope - Tooltip": "Scope - Tooltip",
"Secret access key": "Secret access key",
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
"Sign Name": "Sign Name",
@ -400,8 +433,12 @@
"Template Code - Tooltip": "Template Code - Tooltip",
"Terms of Use": "Terms of Use",
"Terms of Use - Tooltip": "Terms of Use - Tooltip",
"Token URL": "Token URL",
"Token URL - Tooltip": "Token URL - Tooltip",
"Type": "Type",
"Type - Tooltip": "Type - Tooltip",
"UserInfo URL": "UserInfo URL",
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
"alertType": "alertType",
"canSignIn": "canSignIn",
"canSignUp": "canSignUp",
@ -455,6 +492,8 @@
"Please input your real name!": "Please input your real name!",
"Please select your country/region!": "Please select your country/region!",
"Terms of Use": "Terms of Use",
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
"The input is not invoice title!": "The input is not invoice title!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid Phone!": "The input is not valid Phone!",
"Unknown Check Type": "Unknown Check Type",

View File

@ -3,7 +3,6 @@
"Login": "Se connecter",
"Logout": "Déconnexion",
"My Account": "Mon Compte",
"Settings for your account": "Paramètres de votre compte",
"Sign Up": "S'inscrire"
},
"application": {
@ -171,9 +170,11 @@
"Signup application": "Signup application",
"Signup application - Tooltip": "Signup application - Tooltip",
"Sorry, the page you visited does not exist.": "Désolé, la page que vous avez visitée n'existe pas.",
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Synchronisateurs",
"Timestamp": "Horodatage",
"Tokens": "Jetons",
@ -223,7 +224,7 @@
"Continue with": "Continuer avec",
"Email or phone": "Courriel ou téléphone",
"Forgot password?": "Mot de passe oublié ?",
"Invalid Email or phone": "E-mail ou téléphone invalide",
"Logging out...": "Logging out...",
"No account?": "Pas de compte ?",
"Or sign in with another account": "Ou connectez-vous avec un autre compte",
"Password": "Mot de passe",
@ -246,6 +247,8 @@
"Default avatar": "Avatar par défaut",
"Edit Organization": "Modifier l'organisation",
"Favicon": "Favicon",
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "Is profile public - Tooltip",
"New Organization": "New Organization",
"Soft deletion": "Suppression du logiciel",
"Soft deletion - Tooltip": "Suppression de soft - infobulle",
@ -258,7 +261,27 @@
"Currency": "Currency",
"Currency - Tooltip": "Currency - Tooltip",
"Edit Payment": "Edit Payment",
"Individual": "Individual",
"Invoice Tax ID": "Invoice Tax ID",
"Invoice Tax ID - Tooltip": "Invoice Tax ID - Tooltip",
"Invoice remark": "Invoice remark",
"Invoice remark - Tooltip": "Invoice remark - Tooltip",
"Invoice title": "Invoice title",
"Invoice title - Tooltip": "Invoice title - Tooltip",
"Invoice type": "Invoice type",
"Invoice type - Tooltip": "Invoice type - Tooltip",
"Message": "Message",
"Message - Tooltip": "Message - Tooltip",
"New Payment": "New Payment",
"Organization": "Organization",
"Person Email": "Person Email",
"Person Email - Tooltip": "Person Email - Tooltip",
"Person ID card": "Person ID card",
"Person ID card - Tooltip": "Person ID card - Tooltip",
"Person name": "Person name",
"Person name - Tooltip": "Person name - Tooltip",
"Person phone": "Person phone",
"Person phone - Tooltip": "Person phone - Tooltip",
"Please click the below button to return to the original website": "Please click the below button to return to the original website",
"Price": "Price",
"Price - Tooltip": "Price - Tooltip",
@ -330,11 +353,19 @@
"Agent ID - Tooltip": "Agent ID - Tooltip",
"App ID": "App ID",
"App ID - Tooltip": "App ID - Tooltip",
"App key": "App key",
"App key - Tooltip": "App key - Tooltip",
"App secret": "App secret",
"AppSecret - Tooltip": "AppSecret - Tooltip",
"Auth URL": "Auth URL",
"Auth URL - Tooltip": "Auth URL - Tooltip",
"Bucket": "Seau",
"Bucket - Tooltip": "Storage bucket name",
"Can not parse Metadata": "Impossible d'analyser les métadonnées",
"Category": "Catégorie",
"Category - Tooltip": "Unique string-style identifier",
"Channel No.": "Channel No.",
"Channel No. - Tooltip": "Channel No. - Tooltip",
"Client ID": "ID du client",
"Client ID - Tooltip": "Unique string-style identifier",
"Client ID 2": "ID client 2",
@ -382,6 +413,8 @@
"SP ACS URL": "URL du SP ACS",
"SP ACS URL - Tooltip": "URL SP ACS - infobulle",
"SP Entity ID": "ID de l'entité SP",
"Scope": "Scope",
"Scope - Tooltip": "Scope - Tooltip",
"Secret access key": "Clé d'accès secrète",
"SecretAccessKey - Tooltip": "SecretAccessKey - Infobulle",
"Sign Name": "Nom du panneau",
@ -400,8 +433,12 @@
"Template Code - Tooltip": "Unique string-style identifier",
"Terms of Use": "Conditions d'utilisation",
"Terms of Use - Tooltip": "Conditions d'utilisation - Info-bulle",
"Token URL": "Token URL",
"Token URL - Tooltip": "Token URL - Tooltip",
"Type": "Type de texte",
"Type - Tooltip": "Unique string-style identifier",
"UserInfo URL": "UserInfo URL",
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
"alertType": "Type d'alerte",
"canSignIn": "canSignIn",
"canSignUp": "canSignUp",
@ -455,6 +492,8 @@
"Please input your real name!": "Veuillez entrer votre nom personnel !",
"Please select your country/region!": "Veuillez sélectionner votre pays/région!",
"Terms of Use": "Conditions d'utilisation",
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
"The input is not invoice title!": "The input is not invoice title!",
"The input is not valid Email!": "L'entrée n'est pas un email valide !",
"The input is not valid Phone!": "L'entrée n'est pas un téléphone valide !",
"Unknown Check Type": "Type de vérification inconnu",

View File

@ -3,7 +3,6 @@
"Login": "ログイン",
"Logout": "ログアウト",
"My Account": "マイアカウント",
"Settings for your account": "アカウントの設定",
"Sign Up": "新規登録"
},
"application": {
@ -171,9 +170,11 @@
"Signup application": "Signup application",
"Signup application - Tooltip": "Signup application - Tooltip",
"Sorry, the page you visited does not exist.": "申し訳ありませんが、訪問したページは存在しません。",
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",
"Timestamp": "タイムスタンプ",
"Tokens": "トークン",
@ -223,7 +224,7 @@
"Continue with": "次で続ける",
"Email or phone": "Eメールまたは電話番号",
"Forgot password?": "パスワードを忘れましたか?",
"Invalid Email or phone": "メールアドレスまたは電話番号が正しくありません",
"Logging out...": "Logging out...",
"No account?": "アカウントがありませんか?",
"Or sign in with another account": "または別のアカウントでサインイン",
"Password": "パスワード",
@ -246,6 +247,8 @@
"Default avatar": "デフォルトのアバター",
"Edit Organization": "組織を編集",
"Favicon": "ファビコン",
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "Is profile public - Tooltip",
"New Organization": "New Organization",
"Soft deletion": "ソフト削除",
"Soft deletion - Tooltip": "ソフト削除 - ツールチップ",
@ -258,7 +261,27 @@
"Currency": "Currency",
"Currency - Tooltip": "Currency - Tooltip",
"Edit Payment": "Edit Payment",
"Individual": "Individual",
"Invoice Tax ID": "Invoice Tax ID",
"Invoice Tax ID - Tooltip": "Invoice Tax ID - Tooltip",
"Invoice remark": "Invoice remark",
"Invoice remark - Tooltip": "Invoice remark - Tooltip",
"Invoice title": "Invoice title",
"Invoice title - Tooltip": "Invoice title - Tooltip",
"Invoice type": "Invoice type",
"Invoice type - Tooltip": "Invoice type - Tooltip",
"Message": "Message",
"Message - Tooltip": "Message - Tooltip",
"New Payment": "New Payment",
"Organization": "Organization",
"Person Email": "Person Email",
"Person Email - Tooltip": "Person Email - Tooltip",
"Person ID card": "Person ID card",
"Person ID card - Tooltip": "Person ID card - Tooltip",
"Person name": "Person name",
"Person name - Tooltip": "Person name - Tooltip",
"Person phone": "Person phone",
"Person phone - Tooltip": "Person phone - Tooltip",
"Please click the below button to return to the original website": "Please click the below button to return to the original website",
"Price": "Price",
"Price - Tooltip": "Price - Tooltip",
@ -330,11 +353,19 @@
"Agent ID - Tooltip": "Agent ID - Tooltip",
"App ID": "App ID",
"App ID - Tooltip": "App ID - Tooltip",
"App key": "App key",
"App key - Tooltip": "App key - Tooltip",
"App secret": "App secret",
"AppSecret - Tooltip": "AppSecret - Tooltip",
"Auth URL": "Auth URL",
"Auth URL - Tooltip": "Auth URL - Tooltip",
"Bucket": "バケツ入りバケツ",
"Bucket - Tooltip": "Storage bucket name",
"Can not parse Metadata": "メタデータをパースできません",
"Category": "カテゴリ",
"Category - Tooltip": "Unique string-style identifier",
"Channel No.": "Channel No.",
"Channel No. - Tooltip": "Channel No. - Tooltip",
"Client ID": "クライアント ID",
"Client ID - Tooltip": "Unique string-style identifier",
"Client ID 2": "クライアント ID 2",
@ -382,6 +413,8 @@
"SP ACS URL": "SP ACS URL",
"SP ACS URL - Tooltip": "SP ACS URL - ツールチップ",
"SP Entity ID": "SP ID",
"Scope": "Scope",
"Scope - Tooltip": "Scope - Tooltip",
"Secret access key": "シークレットアクセスキー",
"SecretAccessKey - Tooltip": "シークレットアクセスキー - ツールチップ",
"Sign Name": "署名名",
@ -400,8 +433,12 @@
"Template Code - Tooltip": "Unique string-style identifier",
"Terms of Use": "利用規約",
"Terms of Use - Tooltip": "利用規約 - ツールチップ",
"Token URL": "Token URL",
"Token URL - Tooltip": "Token URL - Tooltip",
"Type": "タイプ",
"Type - Tooltip": "Unique string-style identifier",
"UserInfo URL": "UserInfo URL",
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
"alertType": "alertType",
"canSignIn": "canSignIn",
"canSignUp": "canSignUp",
@ -455,6 +492,8 @@
"Please input your real name!": "個人名を入力してください!",
"Please select your country/region!": "あなたの国/地域を選択してください!",
"Terms of Use": "利用規約",
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
"The input is not invoice title!": "The input is not invoice title!",
"The input is not valid Email!": "入力されたメールアドレスが無効です!",
"The input is not valid Phone!": "入力された電話番号が正しくありません!",
"Unknown Check Type": "不明なチェックタイプ",

View File

@ -3,7 +3,6 @@
"Login": "Login",
"Logout": "Logout",
"My Account": "My Account",
"Settings for your account": "Settings for your account",
"Sign Up": "Sign Up"
},
"application": {
@ -171,9 +170,11 @@
"Signup application": "Signup application",
"Signup application - Tooltip": "Signup application - Tooltip",
"Sorry, the page you visited does not exist.": "Sorry, the page you visited does not exist.",
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Syncers",
"Timestamp": "Timestamp",
"Tokens": "Tokens",
@ -223,7 +224,7 @@
"Continue with": "Continue with",
"Email or phone": "Email or phone",
"Forgot password?": "Forgot password?",
"Invalid Email or phone": "Invalid Email or phone",
"Logging out...": "Logging out...",
"No account?": "No account?",
"Or sign in with another account": "Or sign in with another account",
"Password": "Password",
@ -246,6 +247,8 @@
"Default avatar": "Default avatar",
"Edit Organization": "Edit Organization",
"Favicon": "Favicon",
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "Is profile public - Tooltip",
"New Organization": "New Organization",
"Soft deletion": "Soft deletion",
"Soft deletion - Tooltip": "Soft deletion - Tooltip",
@ -258,7 +261,27 @@
"Currency": "Currency",
"Currency - Tooltip": "Currency - Tooltip",
"Edit Payment": "Edit Payment",
"Individual": "Individual",
"Invoice Tax ID": "Invoice Tax ID",
"Invoice Tax ID - Tooltip": "Invoice Tax ID - Tooltip",
"Invoice remark": "Invoice remark",
"Invoice remark - Tooltip": "Invoice remark - Tooltip",
"Invoice title": "Invoice title",
"Invoice title - Tooltip": "Invoice title - Tooltip",
"Invoice type": "Invoice type",
"Invoice type - Tooltip": "Invoice type - Tooltip",
"Message": "Message",
"Message - Tooltip": "Message - Tooltip",
"New Payment": "New Payment",
"Organization": "Organization",
"Person Email": "Person Email",
"Person Email - Tooltip": "Person Email - Tooltip",
"Person ID card": "Person ID card",
"Person ID card - Tooltip": "Person ID card - Tooltip",
"Person name": "Person name",
"Person name - Tooltip": "Person name - Tooltip",
"Person phone": "Person phone",
"Person phone - Tooltip": "Person phone - Tooltip",
"Please click the below button to return to the original website": "Please click the below button to return to the original website",
"Price": "Price",
"Price - Tooltip": "Price - Tooltip",
@ -330,11 +353,19 @@
"Agent ID - Tooltip": "Agent ID - Tooltip",
"App ID": "App ID",
"App ID - Tooltip": "App ID - Tooltip",
"App key": "App key",
"App key - Tooltip": "App key - Tooltip",
"App secret": "App secret",
"AppSecret - Tooltip": "AppSecret - Tooltip",
"Auth URL": "Auth URL",
"Auth URL - Tooltip": "Auth URL - Tooltip",
"Bucket": "Bucket",
"Bucket - Tooltip": "Storage bucket name",
"Can not parse Metadata": "Can not parse Metadata",
"Category": "Category",
"Category - Tooltip": "Unique string-style identifier",
"Channel No.": "Channel No.",
"Channel No. - Tooltip": "Channel No. - Tooltip",
"Client ID": "Client ID",
"Client ID - Tooltip": "Unique string-style identifier",
"Client ID 2": "Client ID 2",
@ -382,6 +413,8 @@
"SP ACS URL": "SP ACS URL",
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
"SP Entity ID": "SP Entity ID",
"Scope": "Scope",
"Scope - Tooltip": "Scope - Tooltip",
"Secret access key": "Secret access key",
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
"Sign Name": "Sign Name",
@ -400,8 +433,12 @@
"Template Code - Tooltip": "Unique string-style identifier",
"Terms of Use": "Terms of Use",
"Terms of Use - Tooltip": "Terms of Use - Tooltip",
"Token URL": "Token URL",
"Token URL - Tooltip": "Token URL - Tooltip",
"Type": "Type",
"Type - Tooltip": "Unique string-style identifier",
"UserInfo URL": "UserInfo URL",
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
"alertType": "alertType",
"canSignIn": "canSignIn",
"canSignUp": "canSignUp",
@ -455,6 +492,8 @@
"Please input your real name!": "Please input your real name!",
"Please select your country/region!": "Please select your country/region!",
"Terms of Use": "Terms of Use",
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
"The input is not invoice title!": "The input is not invoice title!",
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid Phone!": "The input is not valid Phone!",
"Unknown Check Type": "Unknown Check Type",

View File

@ -3,7 +3,6 @@
"Login": "Логин",
"Logout": "Выйти",
"My Account": "Мой аккаунт",
"Settings for your account": "Настройки учетной записи",
"Sign Up": "Регистрация"
},
"application": {
@ -171,9 +170,11 @@
"Signup application": "Signup application",
"Signup application - Tooltip": "Signup application - Tooltip",
"Sorry, the page you visited does not exist.": "Извините, посещенная вами страница не существует.",
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
"State": "State",
"State - Tooltip": "State - Tooltip",
"Swagger": "Swagger",
"Sync": "Sync",
"Syncers": "Синхронизаторы",
"Timestamp": "Отметка времени",
"Tokens": "Жетоны",
@ -223,7 +224,7 @@
"Continue with": "Продолжить с",
"Email or phone": "Электронная почта или телефон",
"Forgot password?": "Забыли пароль?",
"Invalid Email or phone": "Неверный адрес электронной почты или телефон",
"Logging out...": "Logging out...",
"No account?": "Нет учетной записи?",
"Or sign in with another account": "Или войти с помощью другой учетной записи",
"Password": "Пароль",
@ -246,6 +247,8 @@
"Default avatar": "Аватар по умолчанию",
"Edit Organization": "Изменить организацию",
"Favicon": "Иконка",
"Is profile public": "Is profile public",
"Is profile public - Tooltip": "Is profile public - Tooltip",
"New Organization": "New Organization",
"Soft deletion": "Мягкое удаление",
"Soft deletion - Tooltip": "Мягкое удаление - Подсказка",
@ -258,7 +261,27 @@
"Currency": "Currency",
"Currency - Tooltip": "Currency - Tooltip",
"Edit Payment": "Edit Payment",
"Individual": "Individual",
"Invoice Tax ID": "Invoice Tax ID",
"Invoice Tax ID - Tooltip": "Invoice Tax ID - Tooltip",
"Invoice remark": "Invoice remark",
"Invoice remark - Tooltip": "Invoice remark - Tooltip",
"Invoice title": "Invoice title",
"Invoice title - Tooltip": "Invoice title - Tooltip",
"Invoice type": "Invoice type",
"Invoice type - Tooltip": "Invoice type - Tooltip",
"Message": "Message",
"Message - Tooltip": "Message - Tooltip",
"New Payment": "New Payment",
"Organization": "Organization",
"Person Email": "Person Email",
"Person Email - Tooltip": "Person Email - Tooltip",
"Person ID card": "Person ID card",
"Person ID card - Tooltip": "Person ID card - Tooltip",
"Person name": "Person name",
"Person name - Tooltip": "Person name - Tooltip",
"Person phone": "Person phone",
"Person phone - Tooltip": "Person phone - Tooltip",
"Please click the below button to return to the original website": "Please click the below button to return to the original website",
"Price": "Price",
"Price - Tooltip": "Price - Tooltip",
@ -330,11 +353,19 @@
"Agent ID - Tooltip": "Agent ID - Tooltip",
"App ID": "App ID",
"App ID - Tooltip": "App ID - Tooltip",
"App key": "App key",
"App key - Tooltip": "App key - Tooltip",
"App secret": "App secret",
"AppSecret - Tooltip": "AppSecret - Tooltip",
"Auth URL": "Auth URL",
"Auth URL - Tooltip": "Auth URL - Tooltip",
"Bucket": "Ведро",
"Bucket - Tooltip": "Storage bucket name",
"Can not parse Metadata": "Невозможно разобрать метаданные",
"Category": "Категория",
"Category - Tooltip": "Unique string-style identifier",
"Channel No.": "Channel No.",
"Channel No. - Tooltip": "Channel No. - Tooltip",
"Client ID": "ID клиента",
"Client ID - Tooltip": "Unique string-style identifier",
"Client ID 2": "ID клиента 2",
@ -382,6 +413,8 @@
"SP ACS URL": "SP ACS URL",
"SP ACS URL - Tooltip": "SP ACS URL - Подсказка",
"SP Entity ID": "Идентификатор сущности SP",
"Scope": "Scope",
"Scope - Tooltip": "Scope - Tooltip",
"Secret access key": "Секретный ключ доступа",
"SecretAccessKey - Tooltip": "SecretAccessKey - Подсказка",
"Sign Name": "Имя подписи",
@ -400,8 +433,12 @@
"Template Code - Tooltip": "Unique string-style identifier",
"Terms of Use": "Условия использования",
"Terms of Use - Tooltip": "Условия использования - Tooltip",
"Token URL": "Token URL",
"Token URL - Tooltip": "Token URL - Tooltip",
"Type": "Тип",
"Type - Tooltip": "Unique string-style identifier",
"UserInfo URL": "UserInfo URL",
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
"alertType": "тип оповещения",
"canSignIn": "canSignIn",
"canSignUp": "canSignUp",
@ -455,6 +492,8 @@
"Please input your real name!": "Пожалуйста, введите ваше личное имя!",
"Please select your country/region!": "Пожалуйста, выберите вашу страну/регион!",
"Terms of Use": "Условия использования",
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
"The input is not invoice title!": "The input is not invoice title!",
"The input is not valid Email!": "Ввод не является допустимым Email!",
"The input is not valid Phone!": "Введен неверный телефон!",
"Unknown Check Type": "Неизвестный тип проверки",

View File

@ -3,7 +3,6 @@
"Login": "登录",
"Logout": "登出",
"My Account": "我的账户",
"Settings for your account": "账户设置选项",
"Sign Up": "注册"
},
"application": {
@ -175,6 +174,7 @@
"State": "状态",
"State - Tooltip": "状态",
"Swagger": "API文档",
"Sync": "同步",
"Syncers": "同步器",
"Timestamp": "时间戳",
"Tokens": "令牌",
@ -224,7 +224,7 @@
"Continue with": "使用以下账号继续",
"Email or phone": "Email或手机号",
"Forgot password?": "忘记密码?",
"Invalid Email or phone": "无效的Email或手机号",
"Logging out...": "正在退出登录...",
"No account?": "没有账号?",
"Or sign in with another account": "或者,登录其他账号",
"Password": "密码",
@ -247,21 +247,41 @@
"Default avatar": "默认头像",
"Edit Organization": "编辑组织",
"Favicon": "图标",
"Is profile public": "公开用户主页",
"Is profile public - Tooltip": "关闭后,只有全局管理员或同组织用户才能访问用户主页",
"New Organization": "添加组织",
"Soft deletion": "软删除",
"Soft deletion - Tooltip": "启用后,删除用户信息时不会在数据库彻底清除,只会标记为已删除状态",
"Tags": "标签集合",
"Tags - Tooltip": "可供用户选择的标签的集合",
"Website URL": "网页地址",
"Website URL - Tooltip": "网页地址",
"Is profile public": "公开用户信息",
"Is profile public - Tooltip": "关闭后,只有全局管理员或同组织才能访问用户信息"
"Website URL - Tooltip": "网页地址"
},
"payment": {
"Currency": "币种",
"Currency - Tooltip": "如USD美元CNY人民币等",
"Edit Payment": "编辑付款",
"Individual": "个人",
"Invoice Tax ID": "纳税人识别号",
"Invoice Tax ID - Tooltip": "开票类型为单位时,必须输入单位纳税人识别号;开票类型为个人时,不需要填写",
"Invoice remark": "发票备注",
"Invoice remark - Tooltip": "备注不超过50个字",
"Invoice title": "发票抬头",
"Invoice title - Tooltip": "开票类型为单位时,发票抬头可输入单位名称;开票类型为个人时,系统自动填写为缴费人姓名",
"Invoice type": "开票类型",
"Invoice type - Tooltip": "开票类型可以为个人或者单位",
"Message": "消息",
"Message - Tooltip": "付款处理结果消息",
"New Payment": "添加付款",
"Organization": "单位",
"Person Email": "缴费人电子邮箱",
"Person Email - Tooltip": "缴费人本人的电子邮箱",
"Person ID card": "缴费人身份证号",
"Person ID card - Tooltip": "缴费人本人的身份证号",
"Person name": "缴费人姓名",
"Person name - Tooltip": "缴费人本人的姓名",
"Person phone": "缴费人手机号",
"Person phone - Tooltip": "缴费人本人的手机号",
"Please click the below button to return to the original website": "请点击下方按钮返回原网站",
"Price": "价格",
"Price - Tooltip": "商品价格",
@ -333,6 +353,10 @@
"Agent ID - Tooltip": "Agent ID - Tooltip",
"App ID": "App ID",
"App ID - Tooltip": "App ID - Tooltip",
"App key": "App key",
"App key - Tooltip": "App key - Tooltip",
"App secret": "App secret",
"AppSecret - Tooltip": "AppSecret - Tooltip",
"Auth URL": "Auth URL",
"Auth URL - Tooltip": "Auth URL - 工具提示",
"Bucket": "存储桶",
@ -340,6 +364,8 @@
"Can not parse Metadata": "无法解析元数据",
"Category": "分类",
"Category - Tooltip": "分类",
"Channel No.": "Channel No.",
"Channel No. - Tooltip": "Channel No. - Tooltip",
"Client ID": "客户端ID",
"Client ID - Tooltip": "Client ID",
"Client ID 2": "客户端 ID 2",
@ -382,13 +408,13 @@
"Region endpoint for Internet": "地域节点 (外网)",
"Region endpoint for Intranet": "地域节点 (内网)",
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
"Scope": "Scope",
"Scope - Tooltip": "Scope - 工具提示",
"SMS account": "SMS account",
"SMS account - Tooltip": "SMS account - Tooltip",
"SP ACS URL": "SP ACS URL",
"SP ACS URL - Tooltip": "SP ACS URL - 工具提示",
"SP Entity ID": "SP 实体 ID",
"Scope": "Scope",
"Scope - Tooltip": "Scope - 工具提示",
"Secret access key": "秘密访问密钥",
"SecretAccessKey - Tooltip": "访问密钥-工具提示",
"Sign Name": "签名名称",
@ -466,6 +492,8 @@
"Please input your real name!": "请输入您的姓名!",
"Please select your country/region!": "请选择您的国家/地区",
"Terms of Use": "《用户协议》",
"The input is not invoice Tax ID!": "您输入的纳税人识别号有误!",
"The input is not invoice title!": "您输入的发票抬头有误!",
"The input is not valid Email!": "您输入的电子邮箱格式有误!",
"The input is not valid Phone!": "您输入的手机号格式有误!",
"Unknown Check Type": "未知的验证码类型",