mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-08 17:10:27 +08:00
Compare commits
56 Commits
v1.611.0
...
revert-310
Author | SHA1 | Date | |
---|---|---|---|
93e9975acc | |||
f21aa9c0d2 | |||
4b2b875b2d | |||
df2a5681cc | |||
ac102480c7 | |||
feff47d2dc | |||
79b934d6c2 | |||
365449695b | |||
55a52093e8 | |||
e65fdeb1e0 | |||
a46c1cc775 | |||
5629343466 | |||
3718d2dc04 | |||
38b9ad1d9f | |||
5a92411006 | |||
52eaf6c822 | |||
cc84709151 | |||
22fca78be9 | |||
effd257040 | |||
a38747d90e | |||
da70682cd1 | |||
4a3bd84f84 | |||
7f2869cecb | |||
cef2ab213b | |||
cc979c310e | |||
13d73732ce | |||
5686fe5d22 | |||
d8cb82f67a | |||
cad2e1bcc3 | |||
52cc2e4fa7 | |||
8077a2ccba | |||
4cb8e4a514 | |||
2f48d45773 | |||
cff0c7a273 | |||
793a7d6cda | |||
4cc2120fed | |||
93b0f52f26 | |||
e228045e37 | |||
6b8c24e1f0 | |||
8a79bb64dd | |||
e5f9aab28f | |||
7d05b69aac | |||
868e66e866 | |||
40ad3c9234 | |||
e2cd0604c2 | |||
78c3065fbb | |||
af2a9f0374 | |||
bfcfb56336 | |||
c48306d117 | |||
6efec6b4b5 | |||
2daf26aa88 | |||
21c151bcf8 | |||
b6b0b7d318 | |||
0ecc1d599f | |||
3456fc6695 | |||
c302dc7b8e |
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
cache-dependency-path: ./web/yarn.lock
|
cache-dependency-path: ./web/yarn.lock
|
||||||
- run: yarn install && CI=false yarn run build
|
- run: yarn install && CI=false yarn run build
|
||||||
@ -101,7 +101,7 @@ jobs:
|
|||||||
working-directory: ./
|
working-directory: ./
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
cache: 'yarn'
|
cache: 'yarn'
|
||||||
cache-dependency-path: ./web/yarn.lock
|
cache-dependency-path: ./web/yarn.lock
|
||||||
- run: yarn install
|
- run: yarn install
|
||||||
@ -138,7 +138,7 @@ jobs:
|
|||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
|
|
||||||
- name: Fetch Previous version
|
- name: Fetch Previous version
|
||||||
id: get-previous-tag
|
id: get-previous-tag
|
||||||
@ -194,7 +194,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
target: STANDARD
|
target: STANDARD
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: casbin/casdoor:${{steps.get-current-tag.outputs.tag }},casbin/casdoor:latest
|
tags: casbin/casdoor:${{steps.get-current-tag.outputs.tag }},casbin/casdoor:latest
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
target: ALLINONE
|
target: ALLINONE
|
||||||
platforms: linux/amd64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: casbin/casdoor-all-in-one:${{steps.get-current-tag.outputs.tag }},casbin/casdoor-all-in-one:latest
|
tags: casbin/casdoor-all-in-one:${{steps.get-current-tag.outputs.tag }},casbin/casdoor-all-in-one:latest
|
||||||
|
|
||||||
|
14
Dockerfile
14
Dockerfile
@ -1,10 +1,10 @@
|
|||||||
FROM node:18.19.0 AS FRONT
|
FROM --platform=$BUILDPLATFORM node:18.19.0 AS FRONT
|
||||||
WORKDIR /web
|
WORKDIR /web
|
||||||
COPY ./web .
|
COPY ./web .
|
||||||
RUN yarn install --frozen-lockfile --network-timeout 1000000 && yarn run build
|
RUN yarn install --frozen-lockfile --network-timeout 1000000 && yarn run build
|
||||||
|
|
||||||
|
|
||||||
FROM golang:1.20.12 AS BACK
|
FROM --platform=$BUILDPLATFORM golang:1.20.12 AS BACK
|
||||||
WORKDIR /go/src/casdoor
|
WORKDIR /go/src/casdoor
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN ./build.sh
|
RUN ./build.sh
|
||||||
@ -13,6 +13,9 @@ RUN go test -v -run TestGetVersionInfo ./util/system_test.go ./util/system.go >
|
|||||||
FROM alpine:latest AS STANDARD
|
FROM alpine:latest AS STANDARD
|
||||||
LABEL MAINTAINER="https://casdoor.org/"
|
LABEL MAINTAINER="https://casdoor.org/"
|
||||||
ARG USER=casdoor
|
ARG USER=casdoor
|
||||||
|
ARG TARGETOS
|
||||||
|
ARG TARGETARCH
|
||||||
|
ENV BUILDX_ARCH="${TARGETOS:-linux}_${TARGETARCH:-amd64}"
|
||||||
|
|
||||||
RUN sed -i 's/https/http/' /etc/apk/repositories
|
RUN sed -i 's/https/http/' /etc/apk/repositories
|
||||||
RUN apk add --update sudo
|
RUN apk add --update sudo
|
||||||
@ -28,7 +31,7 @@ RUN adduser -D $USER -u 1000 \
|
|||||||
|
|
||||||
USER 1000
|
USER 1000
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/server ./server
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/server_${BUILDX_ARCH} ./server
|
||||||
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/swagger ./swagger
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/swagger ./swagger
|
||||||
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/conf/app.conf ./conf/app.conf
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/conf/app.conf ./conf/app.conf
|
||||||
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/version_info.txt ./go/src/casdoor/version_info.txt
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/version_info.txt ./go/src/casdoor/version_info.txt
|
||||||
@ -47,12 +50,15 @@ RUN apt update \
|
|||||||
|
|
||||||
FROM db AS ALLINONE
|
FROM db AS ALLINONE
|
||||||
LABEL MAINTAINER="https://casdoor.org/"
|
LABEL MAINTAINER="https://casdoor.org/"
|
||||||
|
ARG TARGETOS
|
||||||
|
ARG TARGETARCH
|
||||||
|
ENV BUILDX_ARCH="${TARGETOS:-linux}_${TARGETARCH:-amd64}"
|
||||||
|
|
||||||
RUN apt update
|
RUN apt update
|
||||||
RUN apt install -y ca-certificates && update-ca-certificates
|
RUN apt install -y ca-certificates && update-ca-certificates
|
||||||
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=BACK /go/src/casdoor/server ./server
|
COPY --from=BACK /go/src/casdoor/server_${BUILDX_ARCH} ./server
|
||||||
COPY --from=BACK /go/src/casdoor/swagger ./swagger
|
COPY --from=BACK /go/src/casdoor/swagger ./swagger
|
||||||
COPY --from=BACK /go/src/casdoor/docker-entrypoint.sh /docker-entrypoint.sh
|
COPY --from=BACK /go/src/casdoor/docker-entrypoint.sh /docker-entrypoint.sh
|
||||||
COPY --from=BACK /go/src/casdoor/conf/app.conf ./conf/app.conf
|
COPY --from=BACK /go/src/casdoor/conf/app.conf ./conf/app.conf
|
||||||
|
4
build.sh
4
build.sh
@ -8,4 +8,6 @@ else
|
|||||||
echo "Google is blocked, Go proxy is enabled: GOPROXY=https://goproxy.cn,direct"
|
echo "Google is blocked, Go proxy is enabled: GOPROXY=https://goproxy.cn,direct"
|
||||||
export GOPROXY="https://goproxy.cn,direct"
|
export GOPROXY="https://goproxy.cn,direct"
|
||||||
fi
|
fi
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o server .
|
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o server_linux_amd64 .
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-w -s" -o server_linux_arm64 .
|
||||||
|
@ -169,7 +169,11 @@ func (c *ApiController) Signup() {
|
|||||||
|
|
||||||
username := authForm.Username
|
username := authForm.Username
|
||||||
if !application.IsSignupItemVisible("Username") {
|
if !application.IsSignupItemVisible("Username") {
|
||||||
username = id
|
if organization.UseEmailAsUsername && application.IsSignupItemVisible("Email") {
|
||||||
|
username = authForm.Email
|
||||||
|
} else {
|
||||||
|
username = id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initScore, err := organization.GetInitScore()
|
initScore, err := organization.GetInitScore()
|
||||||
|
@ -117,7 +117,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
if form.Type == ResponseTypeLogin {
|
if form.Type == ResponseTypeLogin {
|
||||||
c.SetSessionUsername(userId)
|
c.SetSessionUsername(userId)
|
||||||
util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
|
util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
|
||||||
resp = &Response{Status: "ok", Msg: "", Data: userId}
|
resp = &Response{Status: "ok", Msg: "", Data: userId, Data2: user.NeedUpdatePassword}
|
||||||
} else if form.Type == ResponseTypeCode {
|
} else if form.Type == ResponseTypeCode {
|
||||||
clientId := c.Input().Get("clientId")
|
clientId := c.Input().Get("clientId")
|
||||||
responseType := c.Input().Get("responseType")
|
responseType := c.Input().Get("responseType")
|
||||||
@ -139,7 +139,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp = codeToResponse(code)
|
resp = codeToResponse(code)
|
||||||
|
resp.Data2 = user.NeedUpdatePassword
|
||||||
if application.EnableSigninSession || application.HasPromptPage() {
|
if application.EnableSigninSession || application.HasPromptPage() {
|
||||||
// The prompt page needs the user to be signed in
|
// The prompt page needs the user to be signed in
|
||||||
c.SetSessionUsername(userId)
|
c.SetSessionUsername(userId)
|
||||||
@ -152,6 +152,8 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
nonce := c.Input().Get("nonce")
|
nonce := c.Input().Get("nonce")
|
||||||
token, _ := object.GetTokenByUser(application, user, scope, nonce, c.Ctx.Request.Host)
|
token, _ := object.GetTokenByUser(application, user, scope, nonce, c.Ctx.Request.Host)
|
||||||
resp = tokenToResponse(token)
|
resp = tokenToResponse(token)
|
||||||
|
|
||||||
|
resp.Data2 = user.NeedUpdatePassword
|
||||||
}
|
}
|
||||||
} else if form.Type == ResponseTypeSaml { // saml flow
|
} else if form.Type == ResponseTypeSaml { // saml flow
|
||||||
res, redirectUrl, method, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host)
|
res, redirectUrl, method, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host)
|
||||||
@ -159,7 +161,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
c.ResponseError(err.Error(), nil)
|
c.ResponseError(err.Error(), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: map[string]string{"redirectUrl": redirectUrl, "method": method}}
|
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: map[string]interface{}{"redirectUrl": redirectUrl, "method": method, "needUpdatePassword": user.NeedUpdatePassword}}
|
||||||
|
|
||||||
if application.EnableSigninSession || application.HasPromptPage() {
|
if application.EnableSigninSession || application.HasPromptPage() {
|
||||||
// The prompt page needs the user to be signed in
|
// The prompt page needs the user to be signed in
|
||||||
@ -663,6 +665,11 @@ func (c *ApiController) Login() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if application.IsSignupItemRequired("Invitation code") {
|
||||||
|
c.ResponseError(c.T("check:Invitation code cannot be blank"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Handle username conflicts
|
// Handle username conflicts
|
||||||
var tmpUser *object.User
|
var tmpUser *object.User
|
||||||
tmpUser, err = object.GetUser(util.GetId(application.Organization, userInfo.Username))
|
tmpUser, err = object.GetUser(util.GetId(application.Organization, userInfo.Username))
|
||||||
|
@ -16,6 +16,7 @@ package controllers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/beego/beego/utils/pagination"
|
"github.com/beego/beego/utils/pagination"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
@ -163,11 +164,17 @@ func (c *ApiController) GetPolicies() {
|
|||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if adapter == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("the adapter: %s is not found"), adapterId))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = adapter.InitAdapter()
|
err = adapter.InitAdapter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ResponseOk()
|
c.ResponseOk()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/beego/beego/utils/pagination"
|
"github.com/beego/beego/utils/pagination"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
@ -164,6 +165,16 @@ func (c *ApiController) BuyProduct() {
|
|||||||
host := c.Ctx.Request.Host
|
host := c.Ctx.Request.Host
|
||||||
providerName := c.Input().Get("providerName")
|
providerName := c.Input().Get("providerName")
|
||||||
paymentEnv := c.Input().Get("paymentEnv")
|
paymentEnv := c.Input().Get("paymentEnv")
|
||||||
|
customPriceStr := c.Input().Get("customPrice")
|
||||||
|
if customPriceStr == "" {
|
||||||
|
customPriceStr = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
customPrice, err := strconv.ParseFloat(customPriceStr, 64)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// buy `pricingName/planName` for `paidUserName`
|
// buy `pricingName/planName` for `paidUserName`
|
||||||
pricingName := c.Input().Get("pricingName")
|
pricingName := c.Input().Get("pricingName")
|
||||||
@ -189,7 +200,7 @@ func (c *ApiController) BuyProduct() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
payment, attachInfo, err := object.BuyProduct(id, user, providerName, pricingName, planName, host, paymentEnv)
|
payment, attachInfo, err := object.BuyProduct(id, user, providerName, pricingName, planName, host, paymentEnv, customPrice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
|
@ -27,11 +27,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type EmailForm struct {
|
type EmailForm struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Sender string `json:"sender"`
|
Sender string `json:"sender"`
|
||||||
Receivers []string `json:"receivers"`
|
Receivers []string `json:"receivers"`
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
|
ProviderObject object.Provider `json:"providerObject"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SmsForm struct {
|
type SmsForm struct {
|
||||||
@ -74,7 +75,6 @@ func (c *ApiController) SendEmail() {
|
|||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// called by Casdoor SDK via Client ID & Client Secret, so the used Email provider will be the application' Email provider or the default Email provider
|
// called by Casdoor SDK via Client ID & Client Secret, so the used Email provider will be the application' Email provider or the default Email provider
|
||||||
provider, err = c.GetProviderFromContext("Email")
|
provider, err = c.GetProviderFromContext("Email")
|
||||||
@ -84,6 +84,13 @@ func (c *ApiController) SendEmail() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if emailForm.ProviderObject.Name != "" {
|
||||||
|
if emailForm.ProviderObject.ClientSecret == "***" {
|
||||||
|
emailForm.ProviderObject.ClientSecret = provider.ClientSecret
|
||||||
|
}
|
||||||
|
provider = &emailForm.ProviderObject
|
||||||
|
}
|
||||||
|
|
||||||
// when receiver is the reserved keyword: "TestSmtpServer", it means to test the SMTP server instead of sending a real Email
|
// when receiver is the reserved keyword: "TestSmtpServer", it means to test the SMTP server instead of sending a real Email
|
||||||
if len(emailForm.Receivers) == 1 && emailForm.Receivers[0] == "TestSmtpServer" {
|
if len(emailForm.Receivers) == 1 && emailForm.Receivers[0] == "TestSmtpServer" {
|
||||||
err = object.DailSmtpServer(provider)
|
err = object.DailSmtpServer(provider)
|
||||||
|
@ -46,10 +46,10 @@ func (c *ApiController) GetSystemInfo() {
|
|||||||
// @Success 200 {object} util.VersionInfo The Response object
|
// @Success 200 {object} util.VersionInfo The Response object
|
||||||
// @router /get-version-info [get]
|
// @router /get-version-info [get]
|
||||||
func (c *ApiController) GetVersionInfo() {
|
func (c *ApiController) GetVersionInfo() {
|
||||||
|
errInfo := ""
|
||||||
versionInfo, err := util.GetVersionInfo()
|
versionInfo, err := util.GetVersionInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
errInfo = "Git error: " + err.Error()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if versionInfo.Version != "" {
|
if versionInfo.Version != "" {
|
||||||
@ -59,9 +59,11 @@ func (c *ApiController) GetVersionInfo() {
|
|||||||
|
|
||||||
versionInfo, err = util.GetVersionInfoFromFile()
|
versionInfo, err = util.GetVersionInfoFromFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
errInfo = errInfo + ", File error: " + err.Error()
|
||||||
|
c.ResponseError(errInfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ResponseOk(versionInfo)
|
c.ResponseOk(versionInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +333,35 @@ func (c *ApiController) IntrospectToken() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if application.TokenFormat == "JWT-Standard" {
|
||||||
|
jwtToken, err := object.ParseStandardJwtTokenByApplication(tokenValue, application)
|
||||||
|
if err != nil || jwtToken.Valid() != nil {
|
||||||
|
// 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
|
||||||
|
c.Data["json"] = &object.IntrospectionResponse{Active: false}
|
||||||
|
c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = &object.IntrospectionResponse{
|
||||||
|
Active: true,
|
||||||
|
Scope: jwtToken.Scope,
|
||||||
|
ClientId: clientId,
|
||||||
|
Username: token.User,
|
||||||
|
TokenType: token.TokenType,
|
||||||
|
Exp: jwtToken.ExpiresAt.Unix(),
|
||||||
|
Iat: jwtToken.IssuedAt.Unix(),
|
||||||
|
Nbf: jwtToken.NotBefore.Unix(),
|
||||||
|
Sub: jwtToken.Subject,
|
||||||
|
Aud: jwtToken.Audience,
|
||||||
|
Iss: jwtToken.Issuer,
|
||||||
|
Jti: jwtToken.ID,
|
||||||
|
}
|
||||||
|
c.ServeJSON()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
jwtToken, err := object.ParseJwtTokenByApplication(tokenValue, application)
|
jwtToken, err := object.ParseJwtTokenByApplication(tokenValue, application)
|
||||||
if err != nil || jwtToken.Valid() != nil {
|
if err != nil || jwtToken.Valid() != nil {
|
||||||
// and token revoked case. but we not implement
|
// and token revoked case. but we not implement
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/beego/beego/utils/pagination"
|
"github.com/beego/beego/utils/pagination"
|
||||||
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
)
|
)
|
||||||
@ -293,6 +294,11 @@ func (c *ApiController) UpdateUser() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
|
||||||
|
if isUsernameLowered {
|
||||||
|
user.Name = strings.ToLower(user.Name)
|
||||||
|
}
|
||||||
|
|
||||||
isAdmin := c.IsAdmin()
|
isAdmin := c.IsAdmin()
|
||||||
if pass, err := object.CheckPermissionForUpdateUser(oldUser, &user, isAdmin, c.GetAcceptLanguage()); !pass {
|
if pass, err := object.CheckPermissionForUpdateUser(oldUser, &user, isAdmin, c.GetAcceptLanguage()); !pass {
|
||||||
c.ResponseError(err)
|
c.ResponseError(err)
|
||||||
@ -503,8 +509,21 @@ func (c *ApiController) SetPassword() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
organization, err := object.GetOrganizationByUser(targetUser)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if organization == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("the organization: %s is not found"), targetUser.Owner))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
targetUser.Password = newPassword
|
targetUser.Password = newPassword
|
||||||
_, err = object.SetUserField(targetUser, "password", targetUser.Password)
|
targetUser.UpdateUserPassword(organization)
|
||||||
|
targetUser.NeedUpdatePassword = false
|
||||||
|
|
||||||
|
_, err = object.UpdateUser(userId, targetUser, []string{"password", "need_update_password", "password_type"}, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
|
4
go.mod
4
go.mod
@ -9,12 +9,12 @@ require (
|
|||||||
github.com/beego/beego v1.12.12
|
github.com/beego/beego v1.12.12
|
||||||
github.com/beevik/etree v1.1.0
|
github.com/beevik/etree v1.1.0
|
||||||
github.com/casbin/casbin/v2 v2.77.2
|
github.com/casbin/casbin/v2 v2.77.2
|
||||||
github.com/casdoor/go-sms-sender v0.22.0
|
github.com/casdoor/go-sms-sender v0.24.0
|
||||||
github.com/casdoor/gomail/v2 v2.0.1
|
github.com/casdoor/gomail/v2 v2.0.1
|
||||||
github.com/casdoor/notify v0.45.0
|
github.com/casdoor/notify v0.45.0
|
||||||
github.com/casdoor/oss v1.6.0
|
github.com/casdoor/oss v1.6.0
|
||||||
github.com/casdoor/xorm-adapter/v3 v3.1.0
|
github.com/casdoor/xorm-adapter/v3 v3.1.0
|
||||||
github.com/casvisor/casvisor-go-sdk v1.3.0
|
github.com/casvisor/casvisor-go-sdk v1.4.0
|
||||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||||
github.com/denisenkom/go-mssqldb v0.9.0
|
github.com/denisenkom/go-mssqldb v0.9.0
|
||||||
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
|
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
|
||||||
|
10
go.sum
10
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/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/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/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/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/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=
|
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/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 h1:kIbfdJ7AA7H0uTQ8s0q4GGZqSS5V9wVE74RrXyD9XPs=
|
||||||
github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc=
|
github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc=
|
||||||
github.com/casdoor/go-sms-sender v0.22.0 h1:K4vj6IZgSESNvs8HchI5CIowvXHNpm7rXOV9QnCTZL4=
|
github.com/casdoor/go-sms-sender v0.24.0 h1:LNLsce3EG/87I3JS6UiajF3LlQmdIiCgebEu0IE4wSM=
|
||||||
github.com/casdoor/go-sms-sender v0.22.0/go.mod h1:cQs7qqohMJBgIVZebOCB8ko09naG1vzFJEH59VNIscs=
|
github.com/casdoor/go-sms-sender v0.24.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 h1:J+FG6x80s9e5lBHUn8Sv0Y56mud34KiWih5YdmudR/w=
|
||||||
github.com/casdoor/gomail/v2 v2.0.1/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q=
|
github.com/casdoor/gomail/v2 v2.0.1/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q=
|
||||||
github.com/casdoor/notify v0.45.0 h1:OlaFvcQFjGOgA4mRx07M8AH1gvb5xNo21mcqrVGlLgk=
|
github.com/casdoor/notify v0.45.0 h1:OlaFvcQFjGOgA4mRx07M8AH1gvb5xNo21mcqrVGlLgk=
|
||||||
@ -1093,8 +1095,8 @@ github.com/casdoor/oss v1.6.0 h1:IOWrGLJ+VO82qS796eaRnzFPPA1Sn3cotYTi7O/VIlQ=
|
|||||||
github.com/casdoor/oss v1.6.0/go.mod h1:rJAWA0hLhtu94t6IRpotLUkXO1NWMASirywQYaGizJE=
|
github.com/casdoor/oss v1.6.0/go.mod h1:rJAWA0hLhtu94t6IRpotLUkXO1NWMASirywQYaGizJE=
|
||||||
github.com/casdoor/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk=
|
github.com/casdoor/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk=
|
||||||
github.com/casdoor/xorm-adapter/v3 v3.1.0/go.mod h1:4WTcUw+bTgBylGHeGHzTtBvuTXRS23dtwzFLl9tsgFM=
|
github.com/casdoor/xorm-adapter/v3 v3.1.0/go.mod h1:4WTcUw+bTgBylGHeGHzTtBvuTXRS23dtwzFLl9tsgFM=
|
||||||
github.com/casvisor/casvisor-go-sdk v1.3.0 h1:HVgm2g3lWpNX2wBNidzR743QY4O5kAjLUJ9tS2juO8g=
|
github.com/casvisor/casvisor-go-sdk v1.4.0 h1:hbZEGGJ1cwdHFAxeXrMoNw6yha6Oyg2F0qQhBNCN/dg=
|
||||||
github.com/casvisor/casvisor-go-sdk v1.3.0/go.mod h1:frnNtH5GA0wxzAQLyZxxfL0RSsSub9GQPi2Ybe86ocE=
|
github.com/casvisor/casvisor-go-sdk v1.4.0/go.mod h1:frnNtH5GA0wxzAQLyZxxfL0RSsSub9GQPi2Ybe86ocE=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||||
|
@ -45,6 +45,8 @@ func TestGenerateI18nFrontend(t *testing.T) {
|
|||||||
applyToOtherLanguage("frontend", "uk", data)
|
applyToOtherLanguage("frontend", "uk", data)
|
||||||
applyToOtherLanguage("frontend", "kk", data)
|
applyToOtherLanguage("frontend", "kk", data)
|
||||||
applyToOtherLanguage("frontend", "fa", data)
|
applyToOtherLanguage("frontend", "fa", data)
|
||||||
|
applyToOtherLanguage("frontend", "cs", data)
|
||||||
|
applyToOtherLanguage("frontend", "sk", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateI18nBackend(t *testing.T) {
|
func TestGenerateI18nBackend(t *testing.T) {
|
||||||
@ -73,4 +75,6 @@ func TestGenerateI18nBackend(t *testing.T) {
|
|||||||
applyToOtherLanguage("backend", "uk", data)
|
applyToOtherLanguage("backend", "uk", data)
|
||||||
applyToOtherLanguage("backend", "kk", data)
|
applyToOtherLanguage("backend", "kk", data)
|
||||||
applyToOtherLanguage("backend", "fa", data)
|
applyToOtherLanguage("backend", "fa", data)
|
||||||
|
applyToOtherLanguage("backend", "cs", data)
|
||||||
|
applyToOtherLanguage("backend", "sk", data)
|
||||||
}
|
}
|
||||||
|
167
i18n/locales/cs/data.json
Normal file
167
i18n/locales/cs/data.json
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
{
|
||||||
|
"account": {
|
||||||
|
"Failed to add user": "Nepodařilo se přidat uživatele",
|
||||||
|
"Get init score failed, error: %w": "Nepodařilo se získat počáteční skóre, chyba: %w",
|
||||||
|
"Please sign out first": "Nejprve se prosím odhlaste",
|
||||||
|
"The application does not allow to sign up new account": "Aplikace neumožňuje registraci nového účtu"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"Challenge method should be S256": "Metoda výzvy by měla být S256",
|
||||||
|
"Failed to create user, user information is invalid: %s": "Nepodařilo se vytvořit uživatele, informace o uživateli jsou neplatné: %s",
|
||||||
|
"Failed to login in: %s": "Nepodařilo se přihlásit: %s",
|
||||||
|
"Invalid token": "Neplatný token",
|
||||||
|
"State expected: %s, but got: %s": "Očekávaný stav: %s, ale získán: %s",
|
||||||
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Účet pro poskytovatele: %s a uživatelské jméno: %s (%s) neexistuje a není povoleno se registrovat jako nový účet přes %%s, prosím použijte jiný způsob registrace",
|
||||||
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Účet pro poskytovatele: %s a uživatelské jméno: %s (%s) neexistuje a není povoleno se registrovat jako nový účet, prosím kontaktujte svou IT podporu",
|
||||||
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Účet pro poskytovatele: %s a uživatelské jméno: %s (%s) je již propojen s jiným účtem: %s (%s)",
|
||||||
|
"The application: %s does not exist": "Aplikace: %s neexistuje",
|
||||||
|
"The login method: login with LDAP is not enabled for the application": "Metoda přihlášení: přihlášení pomocí LDAP není pro aplikaci povolena",
|
||||||
|
"The login method: login with SMS is not enabled for the application": "Metoda přihlášení: přihlášení pomocí SMS není pro aplikaci povolena",
|
||||||
|
"The login method: login with email is not enabled for the application": "Metoda přihlášení: přihlášení pomocí emailu není pro aplikaci povolena",
|
||||||
|
"The login method: login with face is not enabled for the application": "Metoda přihlášení: přihlášení pomocí obličeje není pro aplikaci povolena",
|
||||||
|
"The login method: login with password is not enabled for the application": "Metoda přihlášení: přihlášení pomocí hesla není pro aplikaci povolena",
|
||||||
|
"The organization: %s does not exist": "Organizace: %s neexistuje",
|
||||||
|
"The provider: %s is not enabled for the application": "Poskytovatel: %s není pro aplikaci povolen",
|
||||||
|
"Unauthorized operation": "Neoprávněná operace",
|
||||||
|
"Unknown authentication type (not password or provider), form = %s": "Neznámý typ autentizace (není heslo nebo poskytovatel), formulář = %s",
|
||||||
|
"User's tag: %s is not listed in the application's tags": "Štítek uživatele: %s není uveden v štítcích aplikace",
|
||||||
|
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "Placený uživatel %s nemá aktivní nebo čekající předplatné a aplikace: %s nemá výchozí ceny"
|
||||||
|
},
|
||||||
|
"cas": {
|
||||||
|
"Service %s and %s do not match": "Služba %s a %s se neshodují"
|
||||||
|
},
|
||||||
|
"check": {
|
||||||
|
"Affiliation cannot be blank": "Příslušnost nemůže být prázdná",
|
||||||
|
"Default code does not match the code's matching rules": "Výchozí kód neodpovídá pravidlům pro shodu kódů",
|
||||||
|
"DisplayName cannot be blank": "Zobrazované jméno nemůže být prázdné",
|
||||||
|
"DisplayName is not valid real name": "Zobrazované jméno není platné skutečné jméno",
|
||||||
|
"Email already exists": "Email již existuje",
|
||||||
|
"Email cannot be empty": "Email nemůže být prázdný",
|
||||||
|
"Email is invalid": "Email je neplatný",
|
||||||
|
"Empty username.": "Prázdné uživatelské jméno.",
|
||||||
|
"Face data does not exist, cannot log in": "Data obličeje neexistují, nelze se přihlásit",
|
||||||
|
"Face data mismatch": "Neshoda dat obličeje",
|
||||||
|
"FirstName cannot be blank": "Křestní jméno nemůže být prázdné",
|
||||||
|
"Invitation code cannot be blank": "Pozvánkový kód nemůže být prázdný",
|
||||||
|
"Invitation code exhausted": "Pozvánkový kód vyčerpán",
|
||||||
|
"Invitation code is invalid": "Pozvánkový kód je neplatný",
|
||||||
|
"Invitation code suspended": "Pozvánkový kód pozastaven",
|
||||||
|
"LDAP user name or password incorrect": "Uživatelské jméno nebo heslo LDAP je nesprávné",
|
||||||
|
"LastName cannot be blank": "Příjmení nemůže být prázdné",
|
||||||
|
"Multiple accounts with same uid, please check your ldap server": "Více účtů se stejným uid, prosím zkontrolujte svůj ldap server",
|
||||||
|
"Organization does not exist": "Organizace neexistuje",
|
||||||
|
"Phone already exists": "Telefon již existuje",
|
||||||
|
"Phone cannot be empty": "Telefon nemůže být prázdný",
|
||||||
|
"Phone number is invalid": "Telefonní číslo je neplatné",
|
||||||
|
"Please register using the email corresponding to the invitation code": "Prosím zaregistrujte se pomocí emailu odpovídajícího pozvánkovému kódu",
|
||||||
|
"Please register using the phone corresponding to the invitation code": "Prosím zaregistrujte se pomocí telefonu odpovídajícího pozvánkovému kódu",
|
||||||
|
"Please register using the username corresponding to the invitation code": "Prosím zaregistrujte se pomocí uživatelského jména odpovídajícího pozvánkovému kódu",
|
||||||
|
"Session outdated, please login again": "Relace je zastaralá, prosím přihlaste se znovu",
|
||||||
|
"The invitation code has already been used": "Pozvánkový kód již byl použit",
|
||||||
|
"The user is forbidden to sign in, please contact the administrator": "Uživatel má zakázáno se přihlásit, prosím kontaktujte administrátora",
|
||||||
|
"The user: %s doesn't exist in LDAP server": "Uživatel: %s neexistuje na LDAP serveru",
|
||||||
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Uživatelské jméno může obsahovat pouze alfanumerické znaky, podtržítka nebo pomlčky, nemůže mít po sobě jdoucí pomlčky nebo podtržítka a nemůže začínat nebo končit pomlčkou nebo podtržítkem.",
|
||||||
|
"The value \\\"%s\\\" for account field \\\"%s\\\" doesn't match the account item regex": "Hodnota \\\"%s\\\" pro pole účtu \\\"%s\\\" neodpovídá regulárnímu výrazu položky účtu",
|
||||||
|
"The value \\\"%s\\\" for signup field \\\"%s\\\" doesn't match the signup item regex of the application \\\"%s\\\"": "Hodnota \\\"%s\\\" pro pole registrace \\\"%s\\\" neodpovídá regulárnímu výrazu položky registrace aplikace \\\"%s\\\"",
|
||||||
|
"Username already exists": "Uživatelské jméno již existuje",
|
||||||
|
"Username cannot be an email address": "Uživatelské jméno nemůže být emailová adresa",
|
||||||
|
"Username cannot contain white spaces": "Uživatelské jméno nemůže obsahovat mezery",
|
||||||
|
"Username cannot start with a digit": "Uživatelské jméno nemůže začínat číslicí",
|
||||||
|
"Username is too long (maximum is 39 characters).": "Uživatelské jméno je příliš dlouhé (maximálně 39 znaků).",
|
||||||
|
"Username must have at least 2 characters": "Uživatelské jméno musí mít alespoň 2 znaky",
|
||||||
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Zadali jste špatné heslo nebo kód příliš mnohokrát, prosím počkejte %d minut a zkuste to znovu",
|
||||||
|
"Your region is not allow to signup by phone": "Vaše oblast neumožňuje registraci pomocí telefonu",
|
||||||
|
"password or code is incorrect": "heslo nebo kód je nesprávné",
|
||||||
|
"password or code is incorrect, you have %d remaining chances": "heslo nebo kód je nesprávné, máte %d zbývajících pokusů",
|
||||||
|
"unsupported password type: %s": "nepodporovaný typ hesla: %s"
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"Missing parameter": "Chybějící parametr",
|
||||||
|
"Please login first": "Prosím, přihlaste se nejprve",
|
||||||
|
"The organization: %s should have one application at least": "Organizace: %s by měla mít alespoň jednu aplikaci",
|
||||||
|
"The user: %s doesn't exist": "Uživatel: %s neexistuje",
|
||||||
|
"don't support captchaProvider: ": "nepodporuje captchaProvider: ",
|
||||||
|
"this operation is not allowed in demo mode": "tato operace není povolena v demo režimu",
|
||||||
|
"this operation requires administrator to perform": "tato operace vyžaduje administrátora"
|
||||||
|
},
|
||||||
|
"ldap": {
|
||||||
|
"Ldap server exist": "Ldap server existuje"
|
||||||
|
},
|
||||||
|
"link": {
|
||||||
|
"Please link first": "Prosím, nejprve propojte",
|
||||||
|
"This application has no providers": "Tato aplikace nemá žádné poskytovatele",
|
||||||
|
"This application has no providers of type": "Tato aplikace nemá žádné poskytovatele typu",
|
||||||
|
"This provider can't be unlinked": "Tento poskytovatel nemůže být odpojen",
|
||||||
|
"You are not the global admin, you can't unlink other users": "Nejste globální administrátor, nemůžete odpojovat jiné uživatele",
|
||||||
|
"You can't unlink yourself, you are not a member of any application": "Nemůžete odpojit sami sebe, nejste členem žádné aplikace"
|
||||||
|
},
|
||||||
|
"organization": {
|
||||||
|
"Only admin can modify the %s.": "Pouze administrátor může upravit %s.",
|
||||||
|
"The %s is immutable.": "%s je neměnný.",
|
||||||
|
"Unknown modify rule %s.": "Neznámé pravidlo úpravy %s."
|
||||||
|
},
|
||||||
|
"permission": {
|
||||||
|
"The permission: \\\"%s\\\" doesn't exist": "Oprávnění: \\\"%s\\\" neexistuje"
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"Invalid application id": "Neplatné ID aplikace",
|
||||||
|
"the provider: %s does not exist": "poskytovatel: %s neexistuje"
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"User is nil for tag: avatar": "Uživatel je nil pro tag: avatar",
|
||||||
|
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Uživatelské jméno nebo úplná cesta k souboru je prázdná: uživatelské jméno = %s, úplná cesta k souboru = %s"
|
||||||
|
},
|
||||||
|
"saml": {
|
||||||
|
"Application %s not found": "Aplikace %s nebyla nalezena"
|
||||||
|
},
|
||||||
|
"saml_sp": {
|
||||||
|
"provider %s's category is not SAML": "poskytovatel %s není kategorie SAML"
|
||||||
|
},
|
||||||
|
"service": {
|
||||||
|
"Empty parameters for emailForm: %v": "Prázdné parametry pro emailForm: %v",
|
||||||
|
"Invalid Email receivers: %s": "Neplatní příjemci emailu: %s",
|
||||||
|
"Invalid phone receivers: %s": "Neplatní příjemci telefonu: %s"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"The objectKey: %s is not allowed": "objectKey: %s není povolen",
|
||||||
|
"The provider type: %s is not supported": "typ poskytovatele: %s není podporován"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"Grant_type: %s is not supported in this application": "Grant_type: %s není v této aplikaci podporován",
|
||||||
|
"Invalid application or wrong clientSecret": "Neplatná aplikace nebo špatný clientSecret",
|
||||||
|
"Invalid client_id": "Neplatné client_id",
|
||||||
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Přesměrovací URI: %s neexistuje v seznamu povolených přesměrovacích URI",
|
||||||
|
"Token not found, invalid accessToken": "Token nenalezen, neplatný accessToken"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"Display name cannot be empty": "Zobrazované jméno nemůže být prázdné",
|
||||||
|
"New password cannot contain blank space.": "Nové heslo nemůže obsahovat prázdné místo."
|
||||||
|
},
|
||||||
|
"user_upload": {
|
||||||
|
"Failed to import users": "Nepodařilo se importovat uživatele"
|
||||||
|
},
|
||||||
|
"util": {
|
||||||
|
"No application is found for userId: %s": "Pro userId: %s nebyla nalezena žádná aplikace",
|
||||||
|
"No provider for category: %s is found for application: %s": "Pro kategorii: %s nebyl nalezen žádný poskytovatel pro aplikaci: %s",
|
||||||
|
"The provider: %s is not found": "Poskytovatel: %s nebyl nalezen"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"Invalid captcha provider.": "Neplatný poskytovatel captcha.",
|
||||||
|
"Phone number is invalid in your region %s": "Telefonní číslo je ve vaší oblasti %s neplatné",
|
||||||
|
"The verification code has not been sent yet!": "Ověřovací kód ještě nebyl odeslán!",
|
||||||
|
"The verification code has not been sent yet, or has already been used!": "Ověřovací kód ještě nebyl odeslán, nebo již byl použit!",
|
||||||
|
"Turing test failed.": "Turingův test selhal.",
|
||||||
|
"Unable to get the email modify rule.": "Nelze získat pravidlo pro úpravu emailu.",
|
||||||
|
"Unable to get the phone modify rule.": "Nelze získat pravidlo pro úpravu telefonu.",
|
||||||
|
"Unknown type": "Neznámý typ",
|
||||||
|
"Wrong verification code!": "Špatný ověřovací kód!",
|
||||||
|
"You should verify your code in %d min!": "Měli byste ověřit svůj kód do %d minut!",
|
||||||
|
"please add a SMS provider to the \\\"Providers\\\" list for the application: %s": "prosím přidejte poskytovatele SMS do seznamu \\\"Providers\\\" pro aplikaci: %s",
|
||||||
|
"please add an Email provider to the \\\"Providers\\\" list for the application: %s": "prosím přidejte poskytovatele emailu do seznamu \\\"Providers\\\" pro aplikaci: %s",
|
||||||
|
"the user does not exist, please sign up first": "uživatel neexistuje, prosím nejprve se zaregistrujte"
|
||||||
|
},
|
||||||
|
"webauthn": {
|
||||||
|
"Found no credentials for this user": "Nebyly nalezeny žádné přihlašovací údaje pro tohoto uživatele",
|
||||||
|
"Please call WebAuthnSigninBegin first": "Prosím, nejprve zavolejte WebAuthnSigninBegin"
|
||||||
|
}
|
||||||
|
}
|
167
i18n/locales/sk/data.json
Normal file
167
i18n/locales/sk/data.json
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
{
|
||||||
|
"account": {
|
||||||
|
"Failed to add user": "Nepodarilo sa pridať používateľa",
|
||||||
|
"Get init score failed, error: %w": "Získanie počiatočného skóre zlyhalo, chyba: %w",
|
||||||
|
"Please sign out first": "Najskôr sa prosím odhláste",
|
||||||
|
"The application does not allow to sign up new account": "Aplikácia neumožňuje registráciu nového účtu"
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"Challenge method should be S256": "Metóda výzvy by mala byť S256",
|
||||||
|
"Failed to create user, user information is invalid: %s": "Nepodarilo sa vytvoriť používateľa, informácie o používateľovi sú neplatné: %s",
|
||||||
|
"Failed to login in: %s": "Prihlásenie zlyhalo: %s",
|
||||||
|
"Invalid token": "Neplatný token",
|
||||||
|
"State expected: %s, but got: %s": "Očakávaný stav: %s, ale dostali sme: %s",
|
||||||
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Účet pre poskytovateľa: %s a používateľské meno: %s (%s) neexistuje a nie je povolené zaregistrovať nový účet cez %%s, prosím použite iný spôsob registrácie",
|
||||||
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Účet pre poskytovateľa: %s a používateľské meno: %s (%s) neexistuje a nie je povolené zaregistrovať nový účet, prosím kontaktujte vašu IT podporu",
|
||||||
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Účet pre poskytovateľa: %s a používateľské meno: %s (%s) je už prepojený s iným účtom: %s (%s)",
|
||||||
|
"The application: %s does not exist": "Aplikácia: %s neexistuje",
|
||||||
|
"The login method: login with LDAP is not enabled for the application": "Metóda prihlásenia: prihlásenie pomocou LDAP nie je pre aplikáciu povolená",
|
||||||
|
"The login method: login with SMS is not enabled for the application": "Metóda prihlásenia: prihlásenie pomocou SMS nie je pre aplikáciu povolená",
|
||||||
|
"The login method: login with email is not enabled for the application": "Metóda prihlásenia: prihlásenie pomocou e-mailu nie je pre aplikáciu povolená",
|
||||||
|
"The login method: login with face is not enabled for the application": "Metóda prihlásenia: prihlásenie pomocou tváre nie je pre aplikáciu povolená",
|
||||||
|
"The login method: login with password is not enabled for the application": "Metóda prihlásenia: prihlásenie pomocou hesla nie je pre aplikáciu povolená",
|
||||||
|
"The organization: %s does not exist": "Organizácia: %s neexistuje",
|
||||||
|
"The provider: %s is not enabled for the application": "Poskytovateľ: %s nie je pre aplikáciu povolený",
|
||||||
|
"Unauthorized operation": "Neautorizovaná operácia",
|
||||||
|
"Unknown authentication type (not password or provider), form = %s": "Neznámy typ autentifikácie (nie heslo alebo poskytovateľ), forma = %s",
|
||||||
|
"User's tag: %s is not listed in the application's tags": "Štítok používateľa: %s nie je uvedený v štítkoch aplikácie",
|
||||||
|
"paid-user %s does not have active or pending subscription and the application: %s does not have default pricing": "platiaci používateľ %s nemá aktívne alebo čakajúce predplatné a aplikácia: %s nemá predvolenú cenovú politiku"
|
||||||
|
},
|
||||||
|
"cas": {
|
||||||
|
"Service %s and %s do not match": "Služba %s a %s sa nezhodujú"
|
||||||
|
},
|
||||||
|
"check": {
|
||||||
|
"Affiliation cannot be blank": "Príslušnosť nemôže byť prázdna",
|
||||||
|
"Default code does not match the code's matching rules": "Predvolený kód nezodpovedá pravidlám zodpovedania kódu",
|
||||||
|
"DisplayName cannot be blank": "Zobrazované meno nemôže byť prázdne",
|
||||||
|
"DisplayName is not valid real name": "Zobrazované meno nie je platné skutočné meno",
|
||||||
|
"Email already exists": "E-mail už existuje",
|
||||||
|
"Email cannot be empty": "E-mail nemôže byť prázdny",
|
||||||
|
"Email is invalid": "E-mail je neplatný",
|
||||||
|
"Empty username.": "Prázdne používateľské meno.",
|
||||||
|
"Face data does not exist, cannot log in": "Dáta o tvári neexistujú, nemožno sa prihlásiť",
|
||||||
|
"Face data mismatch": "Nesúlad dát o tvári",
|
||||||
|
"FirstName cannot be blank": "Meno nemôže byť prázdne",
|
||||||
|
"Invitation code cannot be blank": "Kód pozvania nemôže byť prázdny",
|
||||||
|
"Invitation code exhausted": "Kód pozvania bol vyčerpaný",
|
||||||
|
"Invitation code is invalid": "Kód pozvania je neplatný",
|
||||||
|
"Invitation code suspended": "Kód pozvania bol pozastavený",
|
||||||
|
"LDAP user name or password incorrect": "LDAP používateľské meno alebo heslo sú nesprávne",
|
||||||
|
"LastName cannot be blank": "Priezvisko nemôže byť prázdne",
|
||||||
|
"Multiple accounts with same uid, please check your ldap server": "Viacero účtov s rovnakým uid, skontrolujte svoj ldap server",
|
||||||
|
"Organization does not exist": "Organizácia neexistuje",
|
||||||
|
"Phone already exists": "Telefón už existuje",
|
||||||
|
"Phone cannot be empty": "Telefón nemôže byť prázdny",
|
||||||
|
"Phone number is invalid": "Telefónne číslo je neplatné",
|
||||||
|
"Please register using the email corresponding to the invitation code": "Prosím, zaregistrujte sa pomocou e-mailu zodpovedajúceho kódu pozvania",
|
||||||
|
"Please register using the phone corresponding to the invitation code": "Prosím, zaregistrujte sa pomocou telefónu zodpovedajúceho kódu pozvania",
|
||||||
|
"Please register using the username corresponding to the invitation code": "Prosím, zaregistrujte sa pomocou používateľského mena zodpovedajúceho kódu pozvania",
|
||||||
|
"Session outdated, please login again": "Relácia je zastaraná, prosím, prihláste sa znova",
|
||||||
|
"The invitation code has already been used": "Kód pozvania už bol použitý",
|
||||||
|
"The user is forbidden to sign in, please contact the administrator": "Používateľovi je zakázané prihlásenie, prosím, kontaktujte administrátora",
|
||||||
|
"The user: %s doesn't exist in LDAP server": "Používateľ: %s neexistuje na LDAP serveri",
|
||||||
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Používateľské meno môže obsahovať iba alfanumerické znaky, podtržníky alebo pomlčky, nemôže obsahovať po sebe idúce pomlčky alebo podtržníky a nemôže začínať alebo končiť pomlčkou alebo podtržníkom.",
|
||||||
|
"The value \\\"%s\\\" for account field \\\"%s\\\" doesn't match the account item regex": "Hodnota \\\"%s\\\" pre pole účtu \\\"%s\\\" nezodpovedá regulárnemu výrazu položky účtu",
|
||||||
|
"The value \\\"%s\\\" for signup field \\\"%s\\\" doesn't match the signup item regex of the application \\\"%s\\\"": "Hodnota \\\"%s\\\" pre pole registrácie \\\"%s\\\" nezodpovedá regulárnemu výrazu položky registrácie aplikácie \\\"%s\\\"",
|
||||||
|
"Username already exists": "Používateľské meno už existuje",
|
||||||
|
"Username cannot be an email address": "Používateľské meno nemôže byť e-mailová adresa",
|
||||||
|
"Username cannot contain white spaces": "Používateľské meno nemôže obsahovať medzery",
|
||||||
|
"Username cannot start with a digit": "Používateľské meno nemôže začínať číslicou",
|
||||||
|
"Username is too long (maximum is 39 characters).": "Používateľské meno je príliš dlhé (maximum je 39 znakov).",
|
||||||
|
"Username must have at least 2 characters": "Používateľské meno musí mať aspoň 2 znaky",
|
||||||
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Zadali ste nesprávne heslo alebo kód príliš veľa krát, prosím, počkajte %d minút a skúste to znova",
|
||||||
|
"Your region is not allow to signup by phone": "Váš región neumožňuje registráciu cez telefón",
|
||||||
|
"password or code is incorrect": "heslo alebo kód je nesprávne",
|
||||||
|
"password or code is incorrect, you have %d remaining chances": "heslo alebo kód je nesprávne, máte %d zostávajúcich pokusov",
|
||||||
|
"unsupported password type: %s": "nepodporovaný typ hesla: %s"
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"Missing parameter": "Chýbajúci parameter",
|
||||||
|
"Please login first": "Najskôr sa prosím prihláste",
|
||||||
|
"The organization: %s should have one application at least": "Organizácia: %s by mala mať aspoň jednu aplikáciu",
|
||||||
|
"The user: %s doesn't exist": "Používateľ: %s neexistuje",
|
||||||
|
"don't support captchaProvider: ": "nepodporuje captchaProvider: ",
|
||||||
|
"this operation is not allowed in demo mode": "táto operácia nie je povolená v demo režime",
|
||||||
|
"this operation requires administrator to perform": "táto operácia vyžaduje vykonanie administrátorom"
|
||||||
|
},
|
||||||
|
"ldap": {
|
||||||
|
"Ldap server exist": "LDAP server existuje"
|
||||||
|
},
|
||||||
|
"link": {
|
||||||
|
"Please link first": "Najskôr sa prosím prepojte",
|
||||||
|
"This application has no providers": "Táto aplikácia nemá žiadnych poskytovateľov",
|
||||||
|
"This application has no providers of type": "Táto aplikácia nemá poskytovateľov typu",
|
||||||
|
"This provider can't be unlinked": "Tento poskytovateľ nemôže byť odpojený",
|
||||||
|
"You are not the global admin, you can't unlink other users": "Nie ste globálny administrátor, nemôžete odpojiť iných používateľov",
|
||||||
|
"You can't unlink yourself, you are not a member of any application": "Nemôžete sa odpojiť, nie ste členom žiadnej aplikácie"
|
||||||
|
},
|
||||||
|
"organization": {
|
||||||
|
"Only admin can modify the %s.": "Len administrátor môže upravovať %s.",
|
||||||
|
"The %s is immutable.": "%s je nemenný.",
|
||||||
|
"Unknown modify rule %s.": "Neznáme pravidlo úprav %s."
|
||||||
|
},
|
||||||
|
"permission": {
|
||||||
|
"The permission: \\\"%s\\\" doesn't exist": "Povolenie: \\\"%s\\\" neexistuje"
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"Invalid application id": "Neplatné id aplikácie",
|
||||||
|
"the provider: %s does not exist": "poskytovateľ: %s neexistuje"
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"User is nil for tag: avatar": "Používateľ je nil pre tag: avatar",
|
||||||
|
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Používateľské meno alebo fullFilePath je prázdny: používateľské meno = %s, fullFilePath = %s"
|
||||||
|
},
|
||||||
|
"saml": {
|
||||||
|
"Application %s not found": "Aplikácia %s nebola nájdená"
|
||||||
|
},
|
||||||
|
"saml_sp": {
|
||||||
|
"provider %s's category is not SAML": "kategória poskytovateľa %s nie je SAML"
|
||||||
|
},
|
||||||
|
"service": {
|
||||||
|
"Empty parameters for emailForm: %v": "Prázdne parametre pre emailForm: %v",
|
||||||
|
"Invalid Email receivers: %s": "Neplatní príjemcovia e-mailu: %s",
|
||||||
|
"Invalid phone receivers: %s": "Neplatní príjemcovia telefónu: %s"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"The objectKey: %s is not allowed": "objectKey: %s nie je povolený",
|
||||||
|
"The provider type: %s is not supported": "Typ poskytovateľa: %s nie je podporovaný"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"Grant_type: %s is not supported in this application": "Grant_type: %s nie je podporovaný v tejto aplikácii",
|
||||||
|
"Invalid application or wrong clientSecret": "Neplatná aplikácia alebo nesprávny clientSecret",
|
||||||
|
"Invalid client_id": "Neplatný client_id",
|
||||||
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s neexistuje v zozname povolených Redirect URI",
|
||||||
|
"Token not found, invalid accessToken": "Token nebol nájdený, neplatný accessToken"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"Display name cannot be empty": "Zobrazované meno nemôže byť prázdne",
|
||||||
|
"New password cannot contain blank space.": "Nové heslo nemôže obsahovať medzery."
|
||||||
|
},
|
||||||
|
"user_upload": {
|
||||||
|
"Failed to import users": "Nepodarilo sa importovať používateľov"
|
||||||
|
},
|
||||||
|
"util": {
|
||||||
|
"No application is found for userId: %s": "Nebola nájdená žiadna aplikácia pre userId: %s",
|
||||||
|
"No provider for category: %s is found for application: %s": "Pre aplikáciu: %s nebol nájdený žiadny poskytovateľ pre kategóriu: %s",
|
||||||
|
"The provider: %s is not found": "Poskytovateľ: %s nebol nájdený"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"Invalid captcha provider.": "Neplatný captcha poskytovateľ.",
|
||||||
|
"Phone number is invalid in your region %s": "Telefónne číslo je neplatné vo vašom regióne %s",
|
||||||
|
"The verification code has not been sent yet!": "Overovací kód ešte nebol odoslaný!",
|
||||||
|
"The verification code has not been sent yet, or has already been used!": "Overovací kód ešte nebol odoslaný, alebo bol už použitý!",
|
||||||
|
"Turing test failed.": "Test Turinga zlyhal.",
|
||||||
|
"Unable to get the email modify rule.": "Nepodarilo sa získať pravidlo úpravy e-mailu.",
|
||||||
|
"Unable to get the phone modify rule.": "Nepodarilo sa získať pravidlo úpravy telefónu.",
|
||||||
|
"Unknown type": "Neznámy typ",
|
||||||
|
"Wrong verification code!": "Nesprávny overovací kód!",
|
||||||
|
"You should verify your code in %d min!": "Overte svoj kód za %d minút!",
|
||||||
|
"please add a SMS provider to the \\\"Providers\\\" list for the application: %s": "prosím pridajte SMS poskytovateľa do zoznamu \\\"Poskytovatelia\\\" pre aplikáciu: %s",
|
||||||
|
"please add an Email provider to the \\\"Providers\\\" list for the application: %s": "prosím pridajte e-mailového poskytovateľa do zoznamu \\\"Poskytovatelia\\\" pre aplikáciu: %s",
|
||||||
|
"the user does not exist, please sign up first": "používateľ neexistuje, prosím, zaregistrujte sa najskôr"
|
||||||
|
},
|
||||||
|
"webauthn": {
|
||||||
|
"Found no credentials for this user": "Nenašli sa žiadne prihlasovacie údaje pre tohto používateľa",
|
||||||
|
"Please call WebAuthnSigninBegin first": "Najskôr prosím zavolajte WebAuthnSigninBegin"
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
"github.com/nyaruka/phonenumbers"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -130,6 +131,23 @@ type GoogleUserInfo struct {
|
|||||||
Locale string `json:"locale"`
|
Locale string `json:"locale"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GooglePeopleApiPhoneNumberMetaData struct {
|
||||||
|
Primary bool `json:"primary"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GooglePeopleApiPhoneNumber struct {
|
||||||
|
CanonicalForm string `json:"canonicalForm"`
|
||||||
|
MetaData GooglePeopleApiPhoneNumberMetaData `json:"metadata"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GooglePeopleApiResult struct {
|
||||||
|
PhoneNumbers []GooglePeopleApiPhoneNumber `json:"phoneNumbers"`
|
||||||
|
Etag string `json:"etag"`
|
||||||
|
ResourceName string `json:"resourceName"`
|
||||||
|
}
|
||||||
|
|
||||||
func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||||
if strings.HasPrefix(token.AccessToken, GoogleIdTokenKey) {
|
if strings.HasPrefix(token.AccessToken, GoogleIdTokenKey) {
|
||||||
googleIdToken, ok := token.Extra(GoogleIdTokenKey).(GoogleIdToken)
|
googleIdToken, ok := token.Extra(GoogleIdTokenKey).(GoogleIdToken)
|
||||||
@ -167,12 +185,49 @@ func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
|||||||
return nil, errors.New("google email is empty")
|
return nil, errors.New("google email is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url = fmt.Sprintf("https://people.googleapis.com/v1/people/me?personFields=phoneNumbers&access_token=%s", token.AccessToken)
|
||||||
|
resp, err = idp.Client.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err = io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var googlePeopleResult GooglePeopleApiResult
|
||||||
|
err = json.Unmarshal(body, &googlePeopleResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var phoneNumber string
|
||||||
|
var countryCode string
|
||||||
|
if len(googlePeopleResult.PhoneNumbers) != 0 {
|
||||||
|
for _, phoneData := range googlePeopleResult.PhoneNumbers {
|
||||||
|
if phoneData.MetaData.Primary {
|
||||||
|
phoneNumber = phoneData.CanonicalForm
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
phoneNumberParsed, err := phonenumbers.Parse(phoneNumber, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
countryCode = phonenumbers.GetRegionCodeForNumber(phoneNumberParsed)
|
||||||
|
phoneNumber = fmt.Sprintf("%d", phoneNumberParsed.GetNationalNumber())
|
||||||
|
}
|
||||||
|
|
||||||
userInfo := UserInfo{
|
userInfo := UserInfo{
|
||||||
Id: googleUserInfo.Id,
|
Id: googleUserInfo.Id,
|
||||||
Username: googleUserInfo.Email,
|
Username: googleUserInfo.Email,
|
||||||
DisplayName: googleUserInfo.Name,
|
DisplayName: googleUserInfo.Name,
|
||||||
Email: googleUserInfo.Email,
|
Email: googleUserInfo.Email,
|
||||||
AvatarUrl: googleUserInfo.Picture,
|
AvatarUrl: googleUserInfo.Picture,
|
||||||
|
Phone: phoneNumber,
|
||||||
|
CountryCode: countryCode,
|
||||||
}
|
}
|
||||||
return &userInfo, nil
|
return &userInfo, nil
|
||||||
}
|
}
|
||||||
|
18
idp/lark.go
18
idp/lark.go
@ -22,6 +22,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nyaruka/phonenumbers"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -199,12 +200,25 @@ func (idp *LarkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var phoneNumber string
|
||||||
|
var countryCode string
|
||||||
|
if len(larkUserInfo.Data.Mobile) != 0 {
|
||||||
|
phoneNumberParsed, err := phonenumbers.Parse(larkUserInfo.Data.Mobile, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
countryCode = phonenumbers.GetRegionCodeForNumber(phoneNumberParsed)
|
||||||
|
phoneNumber = fmt.Sprintf("%d", phoneNumberParsed.GetNationalNumber())
|
||||||
|
}
|
||||||
|
|
||||||
userInfo := UserInfo{
|
userInfo := UserInfo{
|
||||||
Id: larkUserInfo.Data.OpenId,
|
Id: larkUserInfo.Data.OpenId,
|
||||||
DisplayName: larkUserInfo.Data.EnName,
|
DisplayName: larkUserInfo.Data.Name,
|
||||||
Username: larkUserInfo.Data.Name,
|
Username: larkUserInfo.Data.UserId,
|
||||||
Email: larkUserInfo.Data.Email,
|
Email: larkUserInfo.Data.Email,
|
||||||
AvatarUrl: larkUserInfo.Data.AvatarUrl,
|
AvatarUrl: larkUserInfo.Data.AvatarUrl,
|
||||||
|
Phone: phoneNumber,
|
||||||
|
CountryCode: countryCode,
|
||||||
}
|
}
|
||||||
return &userInfo, nil
|
return &userInfo, nil
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,9 @@
|
|||||||
"FI",
|
"FI",
|
||||||
"SE",
|
"SE",
|
||||||
"UA",
|
"UA",
|
||||||
"KZ"
|
"KZ",
|
||||||
|
"CZ",
|
||||||
|
"SK"
|
||||||
],
|
],
|
||||||
"defaultAvatar": "",
|
"defaultAvatar": "",
|
||||||
"defaultApplication": "",
|
"defaultApplication": "",
|
||||||
@ -62,7 +64,9 @@
|
|||||||
"sv",
|
"sv",
|
||||||
"uk",
|
"uk",
|
||||||
"kk",
|
"kk",
|
||||||
"fa"
|
"fa",
|
||||||
|
"cs",
|
||||||
|
"sk"
|
||||||
],
|
],
|
||||||
"masterPassword": "",
|
"masterPassword": "",
|
||||||
"defaultPassword": "",
|
"defaultPassword": "",
|
||||||
|
@ -59,7 +59,15 @@ func handleBind(w ldap.ResponseWriter, m *ldap.Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bindPassword := string(r.AuthenticationSimple())
|
bindPassword := string(r.AuthenticationSimple())
|
||||||
bindUser, err := object.CheckUserPassword(bindOrg, bindUsername, bindPassword, "en")
|
|
||||||
|
enableCaptcha := false
|
||||||
|
isSigninViaLdap := false
|
||||||
|
isPasswordWithLdapEnabled := false
|
||||||
|
if bindPassword != "" {
|
||||||
|
isPasswordWithLdapEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
bindUser, err := object.CheckUserPassword(bindOrg, bindUsername, bindPassword, "en", enableCaptcha, isSigninViaLdap, isPasswordWithLdapEnabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Bind failed User=%s, Pass=%#v, ErrMsg=%s", string(r.Name()), r.Authentication(), err)
|
log.Printf("Bind failed User=%s, Pass=%#v, ErrMsg=%s", string(r.Name()), r.Authentication(), err)
|
||||||
res.SetResultCode(ldap.LDAPResultInvalidCredentials)
|
res.SetResultCode(ldap.LDAPResultInvalidCredentials)
|
||||||
@ -122,6 +130,9 @@ func handleSearch(w ldap.ResponseWriter, m *ldap.Message) {
|
|||||||
e.AddAttribute("homeDirectory", message.AttributeValue("/home/"+user.Name))
|
e.AddAttribute("homeDirectory", message.AttributeValue("/home/"+user.Name))
|
||||||
e.AddAttribute("cn", message.AttributeValue(user.Name))
|
e.AddAttribute("cn", message.AttributeValue(user.Name))
|
||||||
e.AddAttribute("uid", message.AttributeValue(user.Id))
|
e.AddAttribute("uid", message.AttributeValue(user.Id))
|
||||||
|
for _, group := range user.Groups {
|
||||||
|
e.AddAttribute(ldapMemberOfAttr, message.AttributeValue(group))
|
||||||
|
}
|
||||||
attrs := r.Attributes()
|
attrs := r.Attributes()
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
if string(attr) == "*" {
|
if string(attr) == "*" {
|
||||||
|
21
ldap/util.go
21
ldap/util.go
@ -79,6 +79,8 @@ var ldapAttributesMapping = map[string]FieldRelation{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ldapMemberOfAttr = "memberOf"
|
||||||
|
|
||||||
var AdditionalLdapAttributes []message.LDAPString
|
var AdditionalLdapAttributes []message.LDAPString
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -180,7 +182,22 @@ func buildUserFilterCondition(filter interface{}) (builder.Cond, error) {
|
|||||||
}
|
}
|
||||||
return builder.Not{cond}, nil
|
return builder.Not{cond}, nil
|
||||||
case message.FilterEqualityMatch:
|
case message.FilterEqualityMatch:
|
||||||
field, err := getUserFieldFromAttribute(string(f.AttributeDesc()))
|
attr := string(f.AttributeDesc())
|
||||||
|
|
||||||
|
if attr == ldapMemberOfAttr {
|
||||||
|
groupId := string(f.AssertionValue())
|
||||||
|
users, err := object.GetGroupUsers(groupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var names []string
|
||||||
|
for _, user := range users {
|
||||||
|
names = append(names, user.Name)
|
||||||
|
}
|
||||||
|
return builder.In("name", names), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
field, err := getUserFieldFromAttribute(attr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -246,7 +263,7 @@ func GetFilteredUsers(m *ldap.Message) (filteredUsers []*object.User, code int)
|
|||||||
return nil, code
|
return nil, code
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == "*" && m.Client.IsOrgAdmin { // get all users from organization 'org'
|
if name == "*" { // get all users from organization 'org'
|
||||||
if m.Client.IsGlobalAdmin && org == "*" {
|
if m.Client.IsGlobalAdmin && org == "*" {
|
||||||
filteredUsers, err = object.GetGlobalUsersWithFilter(buildSafeCondition(r.Filter()))
|
filteredUsers, err = object.GetGlobalUsersWithFilter(buildSafeCondition(r.Filter()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -46,6 +46,7 @@ type SigninItem struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Visible bool `json:"visible"`
|
Visible bool `json:"visible"`
|
||||||
Label string `json:"label"`
|
Label string `json:"label"`
|
||||||
|
CustomCss string `json:"customCss"`
|
||||||
Placeholder string `json:"placeholder"`
|
Placeholder string `json:"placeholder"`
|
||||||
Rule string `json:"rule"`
|
Rule string `json:"rule"`
|
||||||
IsCustom bool `json:"isCustom"`
|
IsCustom bool `json:"isCustom"`
|
||||||
@ -209,7 +210,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem := &SigninItem{
|
signinItem := &SigninItem{
|
||||||
Name: "Back button",
|
Name: "Back button",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".back-button {\n top: 65px;\n left: 15px;\n position: absolute;\n}\n.back-inner-button{}",
|
CustomCss: ".back-button {\n top: 65px;\n left: 15px;\n position: absolute;\n}\n.back-inner-button{}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -217,7 +218,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Languages",
|
Name: "Languages",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-languages {\n top: 55px;\n right: 5px;\n position: absolute;\n}",
|
CustomCss: ".login-languages {\n top: 55px;\n right: 5px;\n position: absolute;\n}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -225,7 +226,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Logo",
|
Name: "Logo",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-logo-box {}",
|
CustomCss: ".login-logo-box {}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -233,7 +234,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Signin methods",
|
Name: "Signin methods",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".signin-methods {}",
|
CustomCss: ".signin-methods {}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -241,7 +242,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Username",
|
Name: "Username",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-username {}\n.login-username-input{}",
|
CustomCss: ".login-username {}\n.login-username-input{}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -249,7 +250,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Password",
|
Name: "Password",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-password {}\n.login-password-input{}",
|
CustomCss: ".login-password {}\n.login-password-input{}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -257,7 +258,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Agreement",
|
Name: "Agreement",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-agreement {}",
|
CustomCss: ".login-agreement {}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -265,7 +266,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Forgot password?",
|
Name: "Forgot password?",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-forget-password {\n display: inline-flex;\n justify-content: space-between;\n width: 320px;\n margin-bottom: 25px;\n}",
|
CustomCss: ".login-forget-password {\n display: inline-flex;\n justify-content: space-between;\n width: 320px;\n margin-bottom: 25px;\n}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -273,7 +274,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Login button",
|
Name: "Login button",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-button-box {\n margin-bottom: 5px;\n}\n.login-button {\n width: 100%;\n}",
|
CustomCss: ".login-button-box {\n margin-bottom: 5px;\n}\n.login-button {\n width: 100%;\n}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -281,7 +282,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Signup link",
|
Name: "Signup link",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".login-signup-link {\n margin-bottom: 24px;\n display: flex;\n justify-content: end;\n}",
|
CustomCss: ".login-signup-link {\n margin-bottom: 24px;\n display: flex;\n justify-content: end;\n}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
@ -289,12 +290,18 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
|
|||||||
signinItem = &SigninItem{
|
signinItem = &SigninItem{
|
||||||
Name: "Providers",
|
Name: "Providers",
|
||||||
Visible: true,
|
Visible: true,
|
||||||
Label: ".provider-img {\n width: 30px;\n margin: 5px;\n}\n.provider-big-img {\n margin-bottom: 10px;\n}",
|
CustomCss: ".provider-img {\n width: 30px;\n margin: 5px;\n}\n.provider-big-img {\n margin-bottom: 10px;\n}",
|
||||||
Placeholder: "",
|
Placeholder: "",
|
||||||
Rule: "None",
|
Rule: "None",
|
||||||
}
|
}
|
||||||
application.SigninItems = append(application.SigninItems, signinItem)
|
application.SigninItems = append(application.SigninItems, signinItem)
|
||||||
}
|
}
|
||||||
|
for idx, item := range application.SigninItems {
|
||||||
|
if item.Label != "" && item.CustomCss == "" {
|
||||||
|
application.SigninItems[idx].CustomCss = item.Label
|
||||||
|
application.SigninItems[idx].Label = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ func getBuiltInAccountItems() []*AccountItem {
|
|||||||
{Name: "Multi-factor authentication", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
{Name: "Multi-factor authentication", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
{Name: "WebAuthn credentials", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
{Name: "WebAuthn credentials", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
{Name: "Managed accounts", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
{Name: "Managed accounts", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
|
{Name: "MFA accounts", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +109,8 @@ func initBuiltInOrganization() bool {
|
|||||||
AccountItems: getBuiltInAccountItems(),
|
AccountItems: getBuiltInAccountItems(),
|
||||||
EnableSoftDeletion: false,
|
EnableSoftDeletion: false,
|
||||||
IsProfilePublic: false,
|
IsProfilePublic: false,
|
||||||
|
UseEmailAsUsername: false,
|
||||||
|
EnableTour: true,
|
||||||
}
|
}
|
||||||
_, err = AddOrganization(organization)
|
_, err = AddOrganization(organization)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -666,7 +666,7 @@ func initDefinedPlan(plan *Plan) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if !affected {
|
if !affected {
|
||||||
panic("Fail to delete enforcer")
|
panic("Fail to delete plan")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plan.CreatedTime = util.GetCurrentTime()
|
plan.CreatedTime = util.GetCurrentTime()
|
||||||
@ -677,7 +677,7 @@ func initDefinedPlan(plan *Plan) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initDefinedPricing(pricing *Pricing) {
|
func initDefinedPricing(pricing *Pricing) {
|
||||||
existed, err := getPlan(pricing.Owner, pricing.Name)
|
existed, err := getPricing(pricing.Owner, pricing.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -719,6 +719,7 @@ func initDefinedInvitation(invitation *Invitation) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initDefinedRecord(record *casvisorsdk.Record) {
|
func initDefinedRecord(record *casvisorsdk.Record) {
|
||||||
|
record.Id = 0
|
||||||
record.CreatedTime = util.GetCurrentTime()
|
record.CreatedTime = util.GetCurrentTime()
|
||||||
_ = AddRecord(record)
|
_ = AddRecord(record)
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,8 @@ type Organization struct {
|
|||||||
InitScore int `json:"initScore"`
|
InitScore int `json:"initScore"`
|
||||||
EnableSoftDeletion bool `json:"enableSoftDeletion"`
|
EnableSoftDeletion bool `json:"enableSoftDeletion"`
|
||||||
IsProfilePublic bool `json:"isProfilePublic"`
|
IsProfilePublic bool `json:"isProfilePublic"`
|
||||||
|
UseEmailAsUsername bool `json:"useEmailAsUsername"`
|
||||||
|
EnableTour bool `json:"enableTour"`
|
||||||
|
|
||||||
MfaItems []*MfaItem `xorm:"varchar(300)" json:"mfaItems"`
|
MfaItems []*MfaItem `xorm:"varchar(300)" json:"mfaItems"`
|
||||||
AccountItems []*AccountItem `xorm:"varchar(5000)" json:"accountItems"`
|
AccountItems []*AccountItem `xorm:"varchar(5000)" json:"accountItems"`
|
||||||
@ -354,6 +356,11 @@ func GetDefaultApplication(id string) (*Application, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = extendApplicationWithSigninMethods(defaultApplication)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return defaultApplication, nil
|
return defaultApplication, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ type Payment struct {
|
|||||||
Currency string `xorm:"varchar(100)" json:"currency"`
|
Currency string `xorm:"varchar(100)" json:"currency"`
|
||||||
Price float64 `json:"price"`
|
Price float64 `json:"price"`
|
||||||
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
|
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
|
||||||
|
IsRecharge bool `xorm:"bool" json:"isRecharge"`
|
||||||
|
|
||||||
// Payer Info
|
// Payer Info
|
||||||
User string `xorm:"varchar(100)" json:"user"`
|
User string `xorm:"varchar(100)" json:"user"`
|
||||||
PersonName string `xorm:"varchar(100)" json:"personName"`
|
PersonName string `xorm:"varchar(100)" json:"personName"`
|
||||||
@ -193,11 +195,16 @@ func notifyPayment(body []byte, owner string, paymentName string) (*Payment, *pp
|
|||||||
return payment, nil, err
|
return payment, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if notifyResult.Price != product.Price {
|
if notifyResult.Price != product.Price && !product.IsRecharge {
|
||||||
err = fmt.Errorf("the payment's price: %f doesn't equal to the expected price: %f", notifyResult.Price, product.Price)
|
err = fmt.Errorf("the payment's price: %f doesn't equal to the expected price: %f", notifyResult.Price, product.Price)
|
||||||
return payment, nil, err
|
return payment, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if payment.IsRecharge {
|
||||||
|
err = UpdateUserBalance(payment.Owner, payment.User, payment.Price)
|
||||||
|
return payment, notifyResult, err
|
||||||
|
}
|
||||||
|
|
||||||
return payment, notifyResult, nil
|
return payment, notifyResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +222,19 @@ func NotifyPayment(body []byte, owner string, paymentName string) (*Payment, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transaction, err := GetTransaction(payment.GetId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if transaction != nil {
|
||||||
|
transaction.State = payment.State
|
||||||
|
_, err = UpdateTransaction(transaction.GetId(), transaction)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return payment, nil
|
return payment, nil
|
||||||
|
@ -181,15 +181,15 @@ func UpdatePermission(id string, permission *Permission) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
|
// if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
|
||||||
isEmpty, _ := ormer.Engine.IsTableEmpty(oldPermission.Adapter)
|
// isEmpty, _ := ormer.Engine.IsTableEmpty(oldPermission.Adapter)
|
||||||
if isEmpty {
|
// if isEmpty {
|
||||||
err = ormer.Engine.DropTables(oldPermission.Adapter)
|
// err = ormer.Engine.DropTables(oldPermission.Adapter)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return false, err
|
// return false, err
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
err = addGroupingPolicies(permission)
|
err = addGroupingPolicies(permission)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -312,15 +312,15 @@ func DeletePermission(permission *Permission) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if permission.Adapter != "" && permission.Adapter != "permission_rule" {
|
// if permission.Adapter != "" && permission.Adapter != "permission_rule" {
|
||||||
isEmpty, _ := ormer.Engine.IsTableEmpty(permission.Adapter)
|
// isEmpty, _ := ormer.Engine.IsTableEmpty(permission.Adapter)
|
||||||
if isEmpty {
|
// if isEmpty {
|
||||||
err = ormer.Engine.DropTables(permission.Adapter)
|
// err = ormer.Engine.DropTables(permission.Adapter)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return false, err
|
// return false, err
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
return affected, nil
|
return affected, nil
|
||||||
|
@ -133,7 +133,7 @@ func AddPlan(plan *Plan) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DeletePlan(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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ func AddPricing(pricing *Pricing) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DeletePricing(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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ type Product struct {
|
|||||||
Price float64 `json:"price"`
|
Price float64 `json:"price"`
|
||||||
Quantity int `json:"quantity"`
|
Quantity int `json:"quantity"`
|
||||||
Sold int `json:"sold"`
|
Sold int `json:"sold"`
|
||||||
|
IsRecharge bool `json:"isRecharge"`
|
||||||
Providers []string `xorm:"varchar(255)" json:"providers"`
|
Providers []string `xorm:"varchar(255)" json:"providers"`
|
||||||
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
|
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ func (product *Product) getProvider(providerName string) (*Provider, error) {
|
|||||||
return provider, nil
|
return provider, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuyProduct(id string, user *User, providerName, pricingName, planName, host, paymentEnv string) (payment *Payment, attachInfo map[string]interface{}, err error) {
|
func BuyProduct(id string, user *User, providerName, pricingName, planName, host, paymentEnv string, customPrice float64) (payment *Payment, attachInfo map[string]interface{}, err error) {
|
||||||
product, err := GetProduct(id)
|
product, err := GetProduct(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -169,6 +170,14 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
|
|||||||
return nil, nil, fmt.Errorf("the product: %s does not exist", id)
|
return nil, nil, fmt.Errorf("the product: %s does not exist", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if product.IsRecharge {
|
||||||
|
if customPrice <= 0 {
|
||||||
|
return nil, nil, fmt.Errorf("the custom price should bigger than zero")
|
||||||
|
} else {
|
||||||
|
product.Price = customPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
provider, err := product.getProvider(providerName)
|
provider, err := product.getProvider(providerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -218,13 +227,17 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
|
|||||||
NotifyUrl: notifyUrl,
|
NotifyUrl: notifyUrl,
|
||||||
PaymentEnv: paymentEnv,
|
PaymentEnv: paymentEnv,
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom process for WeChat & WeChat Pay
|
// custom process for WeChat & WeChat Pay
|
||||||
if provider.Type == "WeChat Pay" {
|
if provider.Type == "WeChat Pay" {
|
||||||
payReq.PayerId, err = getUserExtraProperty(user, "WeChat", idp.BuildWechatOpenIdKey(provider.ClientId2))
|
payReq.PayerId, err = getUserExtraProperty(user, "WeChat", idp.BuildWechatOpenIdKey(provider.ClientId2))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
} else if provider.Type == "Balance" {
|
||||||
|
payReq.PayerId = user.GetId()
|
||||||
}
|
}
|
||||||
|
|
||||||
payResp, err := pProvider.Pay(payReq)
|
payResp, err := pProvider.Pay(payReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -246,6 +259,7 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
|
|||||||
Currency: product.Currency,
|
Currency: product.Currency,
|
||||||
Price: product.Price,
|
Price: product.Price,
|
||||||
ReturnUrl: product.ReturnUrl,
|
ReturnUrl: product.ReturnUrl,
|
||||||
|
IsRecharge: product.IsRecharge,
|
||||||
|
|
||||||
User: user.Name,
|
User: user.Name,
|
||||||
PayUrl: payResp.PayUrl,
|
PayUrl: payResp.PayUrl,
|
||||||
@ -254,8 +268,46 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
|
|||||||
OutOrderId: payResp.OrderId,
|
OutOrderId: payResp.OrderId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transaction := &Transaction{
|
||||||
|
Owner: payment.Owner,
|
||||||
|
Name: payment.Name,
|
||||||
|
DisplayName: payment.DisplayName,
|
||||||
|
Provider: provider.Name,
|
||||||
|
Category: provider.Category,
|
||||||
|
Type: provider.Type,
|
||||||
|
|
||||||
|
ProductName: product.Name,
|
||||||
|
ProductDisplayName: product.DisplayName,
|
||||||
|
Detail: product.Detail,
|
||||||
|
Tag: product.Tag,
|
||||||
|
Currency: product.Currency,
|
||||||
|
Amount: payment.Price,
|
||||||
|
ReturnUrl: payment.ReturnUrl,
|
||||||
|
|
||||||
|
User: payment.User,
|
||||||
|
Application: owner,
|
||||||
|
Payment: payment.GetId(),
|
||||||
|
|
||||||
|
State: pp.PaymentStateCreated,
|
||||||
|
}
|
||||||
|
|
||||||
if provider.Type == "Dummy" {
|
if provider.Type == "Dummy" {
|
||||||
payment.State = pp.PaymentStatePaid
|
payment.State = pp.PaymentStatePaid
|
||||||
|
err = UpdateUserBalance(user.Owner, user.Name, payment.Price)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
} else if provider.Type == "Balance" {
|
||||||
|
if product.Price > user.Balance {
|
||||||
|
return nil, nil, fmt.Errorf("insufficient user balance")
|
||||||
|
}
|
||||||
|
transaction.Amount = -transaction.Amount
|
||||||
|
err = UpdateUserBalance(user.Owner, user.Name, -product.Price)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
payment.State = pp.PaymentStatePaid
|
||||||
|
transaction.State = pp.PaymentStatePaid
|
||||||
}
|
}
|
||||||
|
|
||||||
affected, err := AddPayment(payment)
|
affected, err := AddPayment(payment)
|
||||||
@ -266,6 +318,17 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
|
|||||||
if !affected {
|
if !affected {
|
||||||
return nil, nil, fmt.Errorf("failed to add payment: %s", util.StructToJson(payment))
|
return nil, nil, fmt.Errorf("failed to add payment: %s", util.StructToJson(payment))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if product.IsRecharge || provider.Type == "Balance" {
|
||||||
|
affected, err = AddTransaction(transaction)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if !affected {
|
||||||
|
return nil, nil, fmt.Errorf("failed to add transaction: %s", util.StructToJson(payment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return payment, payResp.AttachInfo, nil
|
return payment, payResp.AttachInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,8 +367,9 @@ func CreateProductForPlan(plan *Plan) *Product {
|
|||||||
Price: plan.Price,
|
Price: plan.Price,
|
||||||
Currency: plan.Currency,
|
Currency: plan.Currency,
|
||||||
|
|
||||||
Quantity: 999,
|
Quantity: 999,
|
||||||
Sold: 0,
|
Sold: 0,
|
||||||
|
IsRecharge: false,
|
||||||
|
|
||||||
Providers: plan.PaymentProviders,
|
Providers: plan.PaymentProviders,
|
||||||
State: "Published",
|
State: "Published",
|
||||||
|
@ -50,7 +50,7 @@ type Provider struct {
|
|||||||
|
|
||||||
Host string `xorm:"varchar(100)" json:"host"`
|
Host string `xorm:"varchar(100)" json:"host"`
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
DisableSsl bool `json:"disableSsl"` // If the provider type is WeChat, DisableSsl means EnableQRCode
|
DisableSsl bool `json:"disableSsl"` // If the provider type is WeChat, DisableSsl means EnableQRCode, if type is Google, it means sync phone number
|
||||||
Title string `xorm:"varchar(100)" json:"title"`
|
Title string `xorm:"varchar(100)" json:"title"`
|
||||||
Content string `xorm:"varchar(2000)" json:"content"` // If provider type is WeChat, Content means QRCode string by Base64 encoding
|
Content string `xorm:"varchar(2000)" json:"content"` // If provider type is WeChat, Content means QRCode string by Base64 encoding
|
||||||
Receiver string `xorm:"varchar(100)" json:"receiver"`
|
Receiver string `xorm:"varchar(100)" json:"receiver"`
|
||||||
@ -309,6 +309,12 @@ func GetPaymentProvider(p *Provider) (pp.PaymentProvider, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return pp, nil
|
return pp, nil
|
||||||
|
} else if typ == "Balance" {
|
||||||
|
pp, err := pp.NewBalancePaymentProvider()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pp, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("the payment provider type: %s is not supported", p.Type)
|
return nil, fmt.Errorf("the payment provider type: %s is not supported", p.Type)
|
||||||
}
|
}
|
||||||
|
@ -90,12 +90,18 @@ func NewRecord(ctx *context.Context) (*casvisorsdk.Record, error) {
|
|||||||
Action: action,
|
Action: action,
|
||||||
Language: languageCode,
|
Language: languageCode,
|
||||||
Object: object,
|
Object: object,
|
||||||
|
StatusCode: 200,
|
||||||
Response: fmt.Sprintf("{status:\"%s\", msg:\"%s\"}", resp.Status, resp.Msg),
|
Response: fmt.Sprintf("{status:\"%s\", msg:\"%s\"}", resp.Status, resp.Msg),
|
||||||
IsTriggered: false,
|
IsTriggered: false,
|
||||||
}
|
}
|
||||||
return &record, nil
|
return &record, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addRecord(record *casvisorsdk.Record) (int64, error) {
|
||||||
|
affected, err := ormer.Engine.Insert(record)
|
||||||
|
return affected, err
|
||||||
|
}
|
||||||
|
|
||||||
func AddRecord(record *casvisorsdk.Record) bool {
|
func AddRecord(record *casvisorsdk.Record) bool {
|
||||||
if logPostOnly {
|
if logPostOnly {
|
||||||
if record.Method == "GET" {
|
if record.Method == "GET" {
|
||||||
@ -108,7 +114,6 @@ func AddRecord(record *casvisorsdk.Record) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
record.Owner = record.Organization
|
record.Owner = record.Organization
|
||||||
|
|
||||||
record.Object = maskPassword(record.Object)
|
record.Object = maskPassword(record.Object)
|
||||||
|
|
||||||
errWebhook := SendWebhooks(record)
|
errWebhook := SendWebhooks(record)
|
||||||
@ -119,7 +124,7 @@ func AddRecord(record *casvisorsdk.Record) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if casvisorsdk.GetClient() == nil {
|
if casvisorsdk.GetClient() == nil {
|
||||||
affected, err := ormer.Engine.Insert(record)
|
affected, err := addRecord(record)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -224,6 +229,40 @@ func getFilteredWebhooks(webhooks []*Webhook, organization string, action string
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addWebhookRecord(webhook *Webhook, record *casvisorsdk.Record, statusCode int, respBody string, sendError error) error {
|
||||||
|
if statusCode == 200 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(respBody) > 300 {
|
||||||
|
respBody = respBody[0:300]
|
||||||
|
}
|
||||||
|
|
||||||
|
webhookRecord := &casvisorsdk.Record{
|
||||||
|
Owner: record.Owner,
|
||||||
|
Name: util.GenerateId(),
|
||||||
|
CreatedTime: util.GetCurrentTime(),
|
||||||
|
Organization: record.Organization,
|
||||||
|
User: record.User,
|
||||||
|
|
||||||
|
Method: webhook.Method,
|
||||||
|
Action: "send-webhook",
|
||||||
|
RequestUri: webhook.Url,
|
||||||
|
StatusCode: statusCode,
|
||||||
|
Response: respBody,
|
||||||
|
Language: record.Language,
|
||||||
|
IsTriggered: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
if sendError != nil {
|
||||||
|
webhookRecord.Response = sendError.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := addRecord(webhookRecord)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func SendWebhooks(record *casvisorsdk.Record) error {
|
func SendWebhooks(record *casvisorsdk.Record) error {
|
||||||
webhooks, err := getWebhooksByOrganization("")
|
webhooks, err := getWebhooksByOrganization("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -248,11 +287,16 @@ func SendWebhooks(record *casvisorsdk.Record) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sendWebhook(webhook, record, user)
|
statusCode, respBody, err := sendWebhook(webhook, record, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = addWebhookRecord(webhook, record, statusCode, respBody, err)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
|
@ -48,7 +48,7 @@ func SendSms(provider *Provider, content string, phoneNumbers ...string) error {
|
|||||||
if provider.AppId != "" {
|
if provider.AppId != "" {
|
||||||
phoneNumbers = append([]string{provider.AppId}, phoneNumbers...)
|
phoneNumbers = append([]string{provider.AppId}, phoneNumbers...)
|
||||||
}
|
}
|
||||||
} else if provider.Type == sender.Aliyun || provider.Type == sender.SendCloud {
|
} else if provider.Type == sender.Aliyun {
|
||||||
for i, number := range phoneNumbers {
|
for i, number := range phoneNumbers {
|
||||||
phoneNumbers[i] = strings.TrimPrefix(number, "+86")
|
phoneNumbers[i] = strings.TrimPrefix(number, "+86")
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,8 @@ func GetMaskedSyncers(syncers []*Syncer, errs ...error) ([]*Syncer, error) {
|
|||||||
|
|
||||||
func UpdateSyncer(id string, syncer *Syncer) (bool, error) {
|
func UpdateSyncer(id string, syncer *Syncer) (bool, error) {
|
||||||
owner, name := util.GetOwnerAndNameFromId(id)
|
owner, name := util.GetOwnerAndNameFromId(id)
|
||||||
if s, err := getSyncer(owner, name); err != nil {
|
s, err := getSyncer(owner, name)
|
||||||
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
} else if s == nil {
|
} else if s == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -163,7 +164,7 @@ func UpdateSyncer(id string, syncer *Syncer) (bool, error) {
|
|||||||
|
|
||||||
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()
|
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()
|
||||||
if syncer.Password == "***" {
|
if syncer.Password == "***" {
|
||||||
session.Omit("password")
|
syncer.Password = s.Password
|
||||||
}
|
}
|
||||||
affected, err := session.Update(syncer)
|
affected, err := session.Update(syncer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -142,9 +142,11 @@ func (syncer *Syncer) syncUsers() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = AddUsersInBatch(newUsers)
|
if len(newUsers) != 0 {
|
||||||
if err != nil {
|
_, err = AddUsersInBatch(newUsers)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !syncer.IsReadOnly {
|
if !syncer.IsReadOnly {
|
||||||
|
@ -169,6 +169,12 @@ func (syncer *Syncer) setUserByKeyValue(user *User, key string, value string) {
|
|||||||
user.TotpSecret = value
|
user.TotpSecret = value
|
||||||
case "SignupApplication":
|
case "SignupApplication":
|
||||||
user.SignupApplication = value
|
user.SignupApplication = value
|
||||||
|
case "MfaPhoneEnabled":
|
||||||
|
user.MfaPhoneEnabled = util.ParseBool(value)
|
||||||
|
case "MfaEmailEnabled":
|
||||||
|
user.MfaEmailEnabled = util.ParseBool(value)
|
||||||
|
case "RecoveryCodes":
|
||||||
|
user.RecoveryCodes = strings.Split(value, ",")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,6 +309,9 @@ func (syncer *Syncer) getMapFromOriginalUser(user *OriginalUser) map[string]stri
|
|||||||
m["PreferredMfaType"] = user.PreferredMfaType
|
m["PreferredMfaType"] = user.PreferredMfaType
|
||||||
m["TotpSecret"] = user.TotpSecret
|
m["TotpSecret"] = user.TotpSecret
|
||||||
m["SignupApplication"] = user.SignupApplication
|
m["SignupApplication"] = user.SignupApplication
|
||||||
|
m["MfaPhoneEnabled"] = util.BoolToString(user.MfaPhoneEnabled)
|
||||||
|
m["MfaEmailEnabled"] = util.BoolToString(user.MfaEmailEnabled)
|
||||||
|
m["RecoveryCodes"] = strings.Join(user.RecoveryCodes, ",")
|
||||||
|
|
||||||
m2 := map[string]string{}
|
m2 := map[string]string{}
|
||||||
for _, tableColumn := range syncer.TableColumns {
|
for _, tableColumn := range syncer.TableColumns {
|
||||||
|
@ -139,6 +139,15 @@ type ClaimsShort struct {
|
|||||||
jwt.RegisteredClaims
|
jwt.RegisteredClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OIDCAddress struct {
|
||||||
|
Formatted string `json:"formatted"`
|
||||||
|
StreetAddress string `json:"street_address"`
|
||||||
|
Locality string `json:"locality"`
|
||||||
|
Region string `json:"region"`
|
||||||
|
PostalCode string `json:"postal_code"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
}
|
||||||
|
|
||||||
type ClaimsWithoutThirdIdp struct {
|
type ClaimsWithoutThirdIdp struct {
|
||||||
*UserWithoutThirdIdp
|
*UserWithoutThirdIdp
|
||||||
TokenType string `json:"tokenType,omitempty"`
|
TokenType string `json:"tokenType,omitempty"`
|
||||||
@ -386,6 +395,13 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
|||||||
refreshClaims["exp"] = jwt.NewNumericDate(refreshExpireTime)
|
refreshClaims["exp"] = jwt.NewNumericDate(refreshExpireTime)
|
||||||
refreshClaims["TokenType"] = "refresh-token"
|
refreshClaims["TokenType"] = "refresh-token"
|
||||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, refreshClaims)
|
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, refreshClaims)
|
||||||
|
} else if application.TokenFormat == "JWT-Standard" {
|
||||||
|
claimsStandard := getStandardClaims(claims)
|
||||||
|
|
||||||
|
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsStandard)
|
||||||
|
claimsStandard.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||||
|
claimsStandard.TokenType = "refresh-token"
|
||||||
|
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsStandard)
|
||||||
} else {
|
} else {
|
||||||
return "", "", "", fmt.Errorf("unknown application TokenFormat: %s", application.TokenFormat)
|
return "", "", "", fmt.Errorf("unknown application TokenFormat: %s", application.TokenFormat)
|
||||||
}
|
}
|
||||||
|
@ -309,12 +309,22 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = ParseJwtToken(refreshToken, cert)
|
if application.TokenFormat == "JWT-Standard" {
|
||||||
if err != nil {
|
_, err = ParseStandardJwtToken(refreshToken, cert)
|
||||||
return &TokenError{
|
if err != nil {
|
||||||
Error: InvalidGrant,
|
return &TokenError{
|
||||||
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
Error: InvalidGrant,
|
||||||
}, nil
|
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, err = ParseJwtToken(refreshToken, cert)
|
||||||
|
if err != nil {
|
||||||
|
return &TokenError{
|
||||||
|
Error: InvalidGrant,
|
||||||
|
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a new token
|
// generate a new token
|
||||||
|
106
object/token_standard_jwt.go
Normal file
106
object/token_standard_jwt.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// 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 object
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClaimsStandard struct {
|
||||||
|
*UserShort
|
||||||
|
Gender string `json:"gender,omitempty"`
|
||||||
|
TokenType string `json:"tokenType,omitempty"`
|
||||||
|
Nonce string `json:"nonce,omitempty"`
|
||||||
|
Scope string `json:"scope,omitempty"`
|
||||||
|
Address OIDCAddress `json:"address,omitempty"`
|
||||||
|
|
||||||
|
jwt.RegisteredClaims
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStreetAddress(user *User) string {
|
||||||
|
var addrs string
|
||||||
|
for _, addr := range user.Address {
|
||||||
|
addrs += addr + "\n"
|
||||||
|
}
|
||||||
|
return addrs
|
||||||
|
}
|
||||||
|
|
||||||
|
func getStandardClaims(claims Claims) ClaimsStandard {
|
||||||
|
res := ClaimsStandard{
|
||||||
|
UserShort: getShortUser(claims.User),
|
||||||
|
TokenType: claims.TokenType,
|
||||||
|
Nonce: claims.Nonce,
|
||||||
|
Scope: claims.Scope,
|
||||||
|
RegisteredClaims: claims.RegisteredClaims,
|
||||||
|
}
|
||||||
|
|
||||||
|
var scopes []string
|
||||||
|
|
||||||
|
if strings.Contains(claims.Scope, ",") {
|
||||||
|
scopes = strings.Split(claims.Scope, ",")
|
||||||
|
} else {
|
||||||
|
scopes = strings.Split(claims.Scope, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, scope := range scopes {
|
||||||
|
if scope == "address" {
|
||||||
|
res.Address = OIDCAddress{StreetAddress: getStreetAddress(claims.User)}
|
||||||
|
} else if scope == "profile" {
|
||||||
|
res.Gender = claims.User.Gender
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseStandardJwtToken(token string, cert *Cert) (*ClaimsStandard, error) {
|
||||||
|
t, err := jwt.ParseWithClaims(token, &ClaimsStandard{}, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||||
|
}
|
||||||
|
|
||||||
|
if cert.Certificate == "" {
|
||||||
|
return nil, fmt.Errorf("the certificate field should not be empty for the cert: %v", cert)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RSA certificate
|
||||||
|
certificate, err := jwt.ParseRSAPublicKeyFromPEM([]byte(cert.Certificate))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return certificate, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if t != nil {
|
||||||
|
if claims, ok := t.Claims.(*ClaimsStandard); ok && t.Valid {
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseStandardJwtTokenByApplication(token string, application *Application) (*ClaimsStandard, error) {
|
||||||
|
cert, err := getCertByApplication(application)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseStandardJwtToken(token, cert)
|
||||||
|
}
|
@ -17,6 +17,7 @@ package object
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/pp"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/xorm-io/core"
|
"github.com/xorm-io/core"
|
||||||
)
|
)
|
||||||
@ -43,7 +44,7 @@ type Transaction struct {
|
|||||||
Application string `xorm:"varchar(100)" json:"application"`
|
Application string `xorm:"varchar(100)" json:"application"`
|
||||||
Payment string `xorm:"varchar(100)" json:"payment"`
|
Payment string `xorm:"varchar(100)" json:"payment"`
|
||||||
|
|
||||||
State string `xorm:"varchar(100)" json:"state"`
|
State pp.PaymentState `xorm:"varchar(100)" json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTransactionCount(owner, field, value string) (int64, error) {
|
func GetTransactionCount(owner, field, value string) (int64, error) {
|
||||||
|
@ -203,7 +203,9 @@ type User struct {
|
|||||||
LastSigninWrongTime string `xorm:"varchar(100)" json:"lastSigninWrongTime"`
|
LastSigninWrongTime string `xorm:"varchar(100)" json:"lastSigninWrongTime"`
|
||||||
SigninWrongTimes int `json:"signinWrongTimes"`
|
SigninWrongTimes int `json:"signinWrongTimes"`
|
||||||
|
|
||||||
ManagedAccounts []ManagedAccount `xorm:"managedAccounts blob" json:"managedAccounts"`
|
ManagedAccounts []ManagedAccount `xorm:"managedAccounts blob" json:"managedAccounts"`
|
||||||
|
MfaAccounts []MfaAccount `xorm:"mfaAccounts blob" json:"mfaAccounts"`
|
||||||
|
NeedUpdatePassword bool `json:"needUpdatePassword"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Userinfo struct {
|
type Userinfo struct {
|
||||||
@ -229,6 +231,12 @@ type ManagedAccount struct {
|
|||||||
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
|
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MfaAccount struct {
|
||||||
|
AccountName string `xorm:"varchar(100)" json:"accountName"`
|
||||||
|
Issuer string `xorm:"varchar(100)" json:"issuer"`
|
||||||
|
SecretKey string `xorm:"varchar(100)" json:"secretKey"`
|
||||||
|
}
|
||||||
|
|
||||||
type FaceId struct {
|
type FaceId struct {
|
||||||
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||||
FaceIdData []float64 `json:"faceIdData"`
|
FaceIdData []float64 `json:"faceIdData"`
|
||||||
@ -602,6 +610,12 @@ func GetMaskedUser(user *User, isAdminOrSelf bool, errs ...error) (*User, error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if user.MfaAccounts != nil {
|
||||||
|
for _, mfaAccount := range user.MfaAccounts {
|
||||||
|
mfaAccount.SecretKey = "***"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if user.TotpSecret != "" {
|
if user.TotpSecret != "" {
|
||||||
user.TotpSecret = ""
|
user.TotpSecret = ""
|
||||||
}
|
}
|
||||||
@ -674,7 +688,7 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
|
|||||||
columns = []string{
|
columns = []string{
|
||||||
"owner", "display_name", "avatar", "first_name", "last_name",
|
"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",
|
"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",
|
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts", "face_ids", "mfaAccounts",
|
||||||
"signin_wrong_times", "last_signin_wrong_time", "groups", "access_key", "access_secret", "mfa_phone_enabled", "mfa_email_enabled",
|
"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",
|
"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",
|
"baidu", "alipay", "casdoor", "infoflow", "apple", "azuread", "azureadb2c", "slack", "steam", "bilibili", "okta", "douyin", "line", "amazon",
|
||||||
@ -682,11 +696,11 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
|
|||||||
"eveonline", "fitbit", "gitea", "heroku", "influxcloud", "instagram", "intercom", "kakao", "lastfm", "mailru", "meetup",
|
"eveonline", "fitbit", "gitea", "heroku", "influxcloud", "instagram", "intercom", "kakao", "lastfm", "mailru", "meetup",
|
||||||
"microsoftonline", "naver", "nextcloud", "onedrive", "oura", "patreon", "paypal", "salesforce", "shopify", "soundcloud",
|
"microsoftonline", "naver", "nextcloud", "onedrive", "oura", "patreon", "paypal", "salesforce", "shopify", "soundcloud",
|
||||||
"spotify", "strava", "stripe", "type", "tiktok", "tumblr", "twitch", "twitter", "typetalk", "uber", "vk", "wepay", "xero", "yahoo",
|
"spotify", "strava", "stripe", "type", "tiktok", "tumblr", "twitch", "twitter", "typetalk", "uber", "vk", "wepay", "xero", "yahoo",
|
||||||
"yammer", "yandex", "zoom", "custom",
|
"yammer", "yandex", "zoom", "custom", "need_update_password",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isAdmin {
|
if isAdmin {
|
||||||
columns = append(columns, "name", "id", "email", "phone", "country_code", "type")
|
columns = append(columns, "name", "id", "email", "phone", "country_code", "type", "balance")
|
||||||
}
|
}
|
||||||
|
|
||||||
columns = append(columns, "updated_time")
|
columns = append(columns, "updated_time")
|
||||||
@ -877,6 +891,7 @@ func AddUsers(users []*User) (bool, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.Name = strings.TrimSpace(user.Name)
|
||||||
if isUsernameLowered {
|
if isUsernameLowered {
|
||||||
user.Name = strings.ToLower(user.Name)
|
user.Name = strings.ToLower(user.Name)
|
||||||
}
|
}
|
||||||
@ -1155,3 +1170,13 @@ func GenerateIdForNewUser(application *Application) (string, error) {
|
|||||||
res := strconv.Itoa(lastUserId + 1)
|
res := strconv.Itoa(lastUserId + 1)
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdateUserBalance(owner string, name string, balance float64) error {
|
||||||
|
user, err := getUser(owner, name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user.Balance += balance
|
||||||
|
_, err = UpdateUser(user.GetId(), user, []string{"balance"}, true)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
@ -21,12 +21,11 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/i18n"
|
"github.com/casdoor/casdoor/i18n"
|
||||||
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/idp"
|
"github.com/casdoor/casdoor/idp"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/xorm-io/core"
|
"github.com/xorm-io/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -57,6 +56,13 @@ func HasUserByField(organizationName string, field string, value string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetUserByFields(organization string, field string) (*User, error) {
|
func GetUserByFields(organization string, field string) (*User, error) {
|
||||||
|
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
|
||||||
|
if isUsernameLowered {
|
||||||
|
field = strings.ToLower(field)
|
||||||
|
}
|
||||||
|
|
||||||
|
field = strings.TrimSpace(field)
|
||||||
|
|
||||||
// check username
|
// check username
|
||||||
user, err := GetUserByField(organization, "name", field)
|
user, err := GetUserByField(organization, "name", field)
|
||||||
if err != nil || user != nil {
|
if err != nil || user != nil {
|
||||||
@ -387,6 +393,20 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, lang str
|
|||||||
itemsChanged = append(itemsChanged, item)
|
itemsChanged = append(itemsChanged, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if oldUser.Address == nil {
|
||||||
|
oldUser.Address = []string{}
|
||||||
|
}
|
||||||
|
oldUserAddressJson, _ := json.Marshal(oldUser.Address)
|
||||||
|
|
||||||
|
if newUser.Address == nil {
|
||||||
|
newUser.Address = []string{}
|
||||||
|
}
|
||||||
|
newUserAddressJson, _ := json.Marshal(newUser.Address)
|
||||||
|
if string(oldUserAddressJson) != string(newUserAddressJson) {
|
||||||
|
item := GetAccountItemByName("Address", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
if newUser.FaceIds != nil {
|
if newUser.FaceIds != nil {
|
||||||
item := GetAccountItemByName("Face ID", organization)
|
item := GetAccountItemByName("Face ID", organization)
|
||||||
itemsChanged = append(itemsChanged, item)
|
itemsChanged = append(itemsChanged, item)
|
||||||
@ -405,12 +425,46 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, lang str
|
|||||||
item := GetAccountItemByName("Is deleted", organization)
|
item := GetAccountItemByName("Is deleted", organization)
|
||||||
itemsChanged = append(itemsChanged, item)
|
itemsChanged = append(itemsChanged, item)
|
||||||
}
|
}
|
||||||
|
if oldUser.NeedUpdatePassword != newUser.NeedUpdatePassword {
|
||||||
|
item := GetAccountItemByName("Need update password", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.Balance != newUser.Balance {
|
||||||
|
item := GetAccountItemByName("Balance", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
if oldUser.Score != newUser.Score {
|
if oldUser.Score != newUser.Score {
|
||||||
item := GetAccountItemByName("Score", organization)
|
item := GetAccountItemByName("Score", organization)
|
||||||
itemsChanged = append(itemsChanged, item)
|
itemsChanged = append(itemsChanged, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if oldUser.Karma != newUser.Karma {
|
||||||
|
item := GetAccountItemByName("Karma", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.Language != newUser.Language {
|
||||||
|
item := GetAccountItemByName("Language", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.Ranking != newUser.Ranking {
|
||||||
|
item := GetAccountItemByName("Ranking", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.Currency != newUser.Currency {
|
||||||
|
item := GetAccountItemByName("Currency", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.Hash != newUser.Hash {
|
||||||
|
item := GetAccountItemByName("Hash", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
for _, accountItem := range itemsChanged {
|
for _, accountItem := range itemsChanged {
|
||||||
|
|
||||||
if pass, err := CheckAccountItemModifyRule(accountItem, isAdmin, lang); !pass {
|
if pass, err := CheckAccountItemModifyRule(accountItem, isAdmin, lang); !pass {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ import (
|
|||||||
"github.com/casvisor/casvisor-go-sdk/casvisorsdk"
|
"github.com/casvisor/casvisor-go-sdk/casvisorsdk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func sendWebhook(webhook *Webhook, record *casvisorsdk.Record, extendedUser *User) error {
|
func sendWebhook(webhook *Webhook, record *casvisorsdk.Record, extendedUser *User) (int, string, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
|
||||||
type RecordEx struct {
|
type RecordEx struct {
|
||||||
@ -38,7 +39,7 @@ func sendWebhook(webhook *Webhook, record *casvisorsdk.Record, extendedUser *Use
|
|||||||
|
|
||||||
req, err := http.NewRequest(webhook.Method, webhook.Url, body)
|
req, err := http.NewRequest(webhook.Method, webhook.Url, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", webhook.ContentType)
|
req.Header.Set("Content-Type", webhook.ContentType)
|
||||||
@ -47,6 +48,15 @@ func sendWebhook(webhook *Webhook, record *casvisorsdk.Record, extendedUser *Use
|
|||||||
req.Header.Set(header.Name, header.Value)
|
req.Header.Set(header.Name, header.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = client.Do(req)
|
resp, err := client.Do(req)
|
||||||
return err
|
if err != nil {
|
||||||
|
return 0, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
bodyBytes, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return 0, "", err
|
||||||
|
}
|
||||||
|
return resp.StatusCode, string(bodyBytes), err
|
||||||
}
|
}
|
||||||
|
50
pp/balance.go
Normal file
50
pp/balance.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// 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 pp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BalancePaymentProvider struct{}
|
||||||
|
|
||||||
|
func NewBalancePaymentProvider() (*BalancePaymentProvider, error) {
|
||||||
|
pp := &BalancePaymentProvider{}
|
||||||
|
return pp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *BalancePaymentProvider) Pay(r *PayReq) (*PayResp, error) {
|
||||||
|
owner, _ := util.GetOwnerAndNameFromId(r.PayerId)
|
||||||
|
return &PayResp{
|
||||||
|
PayUrl: r.ReturnUrl,
|
||||||
|
OrderId: fmt.Sprintf("%s/%s", owner, r.PaymentName),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *BalancePaymentProvider) Notify(body []byte, orderId string) (*NotifyResult, error) {
|
||||||
|
return &NotifyResult{
|
||||||
|
PaymentStatus: PaymentStatePaid,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *BalancePaymentProvider) GetInvoice(paymentName string, personName string, personIdCard string, personEmail string, personPhone string, invoiceType string, invoiceTitle string, invoiceTaxId string) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *BalancePaymentProvider) GetResponseError(err error) string {
|
||||||
|
return ""
|
||||||
|
}
|
@ -18,6 +18,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
@ -27,6 +28,14 @@ import (
|
|||||||
"layeh.com/radius/rfc2866"
|
"layeh.com/radius/rfc2866"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var StateMap map[string]AccessStateContent
|
||||||
|
|
||||||
|
const StateExpiredTime = time.Second * 120
|
||||||
|
|
||||||
|
type AccessStateContent struct {
|
||||||
|
ExpiredAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
func StartRadiusServer() {
|
func StartRadiusServer() {
|
||||||
secret := conf.GetConfigString("radiusSecret")
|
secret := conf.GetConfigString("radiusSecret")
|
||||||
server := radius.PacketServer{
|
server := radius.PacketServer{
|
||||||
@ -55,6 +64,7 @@ func handleAccessRequest(w radius.ResponseWriter, r *radius.Request) {
|
|||||||
username := rfc2865.UserName_GetString(r.Packet)
|
username := rfc2865.UserName_GetString(r.Packet)
|
||||||
password := rfc2865.UserPassword_GetString(r.Packet)
|
password := rfc2865.UserPassword_GetString(r.Packet)
|
||||||
organization := rfc2865.Class_GetString(r.Packet)
|
organization := rfc2865.Class_GetString(r.Packet)
|
||||||
|
state := rfc2865.State_GetString(r.Packet)
|
||||||
log.Printf("handleAccessRequest() username=%v, org=%v, password=%v", username, organization, password)
|
log.Printf("handleAccessRequest() username=%v, org=%v, password=%v", username, organization, password)
|
||||||
|
|
||||||
if organization == "" {
|
if organization == "" {
|
||||||
@ -62,12 +72,75 @@ func handleAccessRequest(w radius.ResponseWriter, r *radius.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := object.CheckUserPassword(organization, username, password, "en")
|
var user *object.User
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if state == "" {
|
||||||
|
user, err = object.CheckUserPassword(organization, username, password, "en")
|
||||||
|
} else {
|
||||||
|
user, err = object.GetUser(fmt.Sprintf("%s/%s", organization, username))
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Write(r.Response(radius.CodeAccessReject))
|
w.Write(r.Response(radius.CodeAccessReject))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if user.IsMfaEnabled() {
|
||||||
|
mfaProp := user.GetMfaProps(object.TotpType, false)
|
||||||
|
if mfaProp == nil {
|
||||||
|
w.Write(r.Response(radius.CodeAccessReject))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if StateMap == nil {
|
||||||
|
StateMap = map[string]AccessStateContent{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if state != "" {
|
||||||
|
stateContent, ok := StateMap[state]
|
||||||
|
if !ok {
|
||||||
|
w.Write(r.Response(radius.CodeAccessReject))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(StateMap, state)
|
||||||
|
if stateContent.ExpiredAt.Before(time.Now()) {
|
||||||
|
w.Write(r.Response(radius.CodeAccessReject))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mfaUtil := object.GetMfaUtil(mfaProp.MfaType, mfaProp)
|
||||||
|
if mfaUtil.Verify(password) != nil {
|
||||||
|
w.Write(r.Response(radius.CodeAccessReject))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(r.Response(radius.CodeAccessAccept))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
responseState := util.GenerateId()
|
||||||
|
StateMap[responseState] = AccessStateContent{
|
||||||
|
time.Now().Add(StateExpiredTime),
|
||||||
|
}
|
||||||
|
|
||||||
|
err = rfc2865.State_Set(r.Packet, []byte(responseState))
|
||||||
|
if err != nil {
|
||||||
|
w.Write(r.Response(radius.CodeAccessReject))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = rfc2865.ReplyMessage_Set(r.Packet, []byte("please enter OTP"))
|
||||||
|
if err != nil {
|
||||||
|
w.Write(r.Response(radius.CodeAccessReject))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Packet.Code = radius.CodeAccessChallenge
|
||||||
|
w.Write(r.Packet)
|
||||||
|
}
|
||||||
|
|
||||||
w.Write(r.Response(radius.CodeAccessAccept))
|
w.Write(r.Response(radius.CodeAccessAccept))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,20 +35,13 @@ type Object struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getUsername(ctx *context.Context) (username string) {
|
func getUsername(ctx *context.Context) (username string) {
|
||||||
defer func() {
|
username, ok := ctx.Input.Session("username").(string)
|
||||||
if r := recover(); r != nil {
|
if !ok || username == "" {
|
||||||
username, _ = getUsernameByClientIdSecret(ctx)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
username = ctx.Input.Session("username").(string)
|
|
||||||
|
|
||||||
if username == "" {
|
|
||||||
username, _ = getUsernameByClientIdSecret(ctx)
|
username, _ = getUsernameByClientIdSecret(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
if username == "" {
|
if username == "" {
|
||||||
username = getUsernameByKeys(ctx)
|
username, _ = getUsernameByKeys(ctx)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -91,17 +91,22 @@ func getUsernameByClientIdSecret(ctx *context.Context) (string, error) {
|
|||||||
return fmt.Sprintf("app/%s", application.Name), nil
|
return fmt.Sprintf("app/%s", application.Name), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUsernameByKeys(ctx *context.Context) string {
|
func getUsernameByKeys(ctx *context.Context) (string, error) {
|
||||||
accessKey, accessSecret := getKeys(ctx)
|
accessKey, accessSecret := getKeys(ctx)
|
||||||
user, err := object.GetUserByAccessKey(accessKey)
|
user, err := object.GetUserByAccessKey(accessKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if user != nil && accessSecret == user.AccessSecret {
|
if user == nil {
|
||||||
return user.GetId()
|
return "", fmt.Errorf("user not found for access key: %s", accessKey)
|
||||||
}
|
}
|
||||||
return ""
|
|
||||||
|
if accessSecret != user.AccessSecret {
|
||||||
|
return "", fmt.Errorf("incorrect access secret for user: %s", user.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.GetId(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSessionUser(ctx *context.Context) string {
|
func getSessionUser(ctx *context.Context) string {
|
||||||
|
@ -354,9 +354,16 @@ func StringToInterfaceArray(array []string) []interface{} {
|
|||||||
func StringToInterfaceArray2d(arrays [][]string) [][]interface{} {
|
func StringToInterfaceArray2d(arrays [][]string) [][]interface{} {
|
||||||
var interfaceArrays [][]interface{}
|
var interfaceArrays [][]interface{}
|
||||||
for _, req := range arrays {
|
for _, req := range arrays {
|
||||||
var interfaceArray []interface{}
|
var (
|
||||||
for _, r := range req {
|
interfaceArray []interface{}
|
||||||
interfaceArray = append(interfaceArray, r)
|
elem interface{}
|
||||||
|
)
|
||||||
|
for _, elem = range req {
|
||||||
|
jStruct, err := TryJsonToAnonymousStruct(elem.(string))
|
||||||
|
if err == nil {
|
||||||
|
elem = jStruct
|
||||||
|
}
|
||||||
|
interfaceArray = append(interfaceArray, elem)
|
||||||
}
|
}
|
||||||
interfaceArrays = append(interfaceArrays, interfaceArray)
|
interfaceArrays = append(interfaceArrays, interfaceArray)
|
||||||
}
|
}
|
||||||
|
@ -252,8 +252,8 @@ class AdapterEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("provider:DB test"), i18next.t("provider:DB test - Tooltip"))} :
|
{Setting.getLabel(i18next.t("provider:DB test"), i18next.t("provider:DB test - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={2} >
|
<Col span={2} >
|
||||||
<Button type={"primary"} onClick={() => {
|
<Button disabled={this.state.organizationName !== this.state.adapter.owner} type={"primary"} onClick={() => {
|
||||||
AdapterBackend.getPolicies("", "", `${this.state.organizationName}/${this.state.adapterName}`)
|
AdapterBackend.getPolicies("", "", `${this.state.adapter.owner}/${this.state.adapter.name}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("syncer:Connect successfully"));
|
Setting.showMessage("success", i18next.t("syncer:Connect successfully"));
|
||||||
@ -279,13 +279,14 @@ class AdapterEditPage extends React.Component {
|
|||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
||||||
this.setState({
|
this.setState({
|
||||||
|
organizationName: this.state.adapter.owner,
|
||||||
adapterName: this.state.adapter.name,
|
adapterName: this.state.adapter.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exitAfterSave) {
|
if (exitAfterSave) {
|
||||||
this.props.history.push("/adapters");
|
this.props.history.push("/adapters");
|
||||||
} else {
|
} else {
|
||||||
this.props.history.push(`/adapters/${this.state.organizationName}/${this.state.adapter.name}`);
|
this.props.history.push(`/adapters/${this.state.adapter.owner}/${this.state.adapter.name}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
|
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
|
||||||
|
@ -16,6 +16,7 @@ import React, {Component, Suspense, lazy} from "react";
|
|||||||
import "./App.less";
|
import "./App.less";
|
||||||
import {Helmet} from "react-helmet";
|
import {Helmet} from "react-helmet";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
|
import {setOrgIsTourVisible, setTourLogo} from "./TourConfig";
|
||||||
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
|
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
|
||||||
import {GithubOutlined, InfoCircleFilled, ShareAltOutlined} from "@ant-design/icons";
|
import {GithubOutlined, InfoCircleFilled, ShareAltOutlined} from "@ant-design/icons";
|
||||||
import {Alert, Button, ConfigProvider, Drawer, FloatButton, Layout, Result, Tooltip} from "antd";
|
import {Alert, Button, ConfigProvider, Drawer, FloatButton, Layout, Result, Tooltip} from "antd";
|
||||||
@ -247,6 +248,8 @@ class App extends Component {
|
|||||||
|
|
||||||
this.setLanguage(account);
|
this.setLanguage(account);
|
||||||
this.setTheme(Setting.getThemeData(account.organization), Conf.InitThemeAlgorithm);
|
this.setTheme(Setting.getThemeData(account.organization), Conf.InitThemeAlgorithm);
|
||||||
|
setTourLogo(account.organization.logo);
|
||||||
|
setOrgIsTourVisible(account.organization.enableTour);
|
||||||
} else {
|
} else {
|
||||||
if (res.data !== "Please login first") {
|
if (res.data !== "Please login first") {
|
||||||
Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`);
|
Setting.showMessage("error", `${i18next.t("application:Failed to sign in")}: ${res.msg}`);
|
||||||
@ -414,6 +417,7 @@ class App extends Component {
|
|||||||
<Layout id="parent-area">
|
<Layout id="parent-area">
|
||||||
<ManagementPage
|
<ManagementPage
|
||||||
account={this.state.account}
|
account={this.state.account}
|
||||||
|
application={this.state.application}
|
||||||
uri={this.state.uri}
|
uri={this.state.uri}
|
||||||
themeData={this.state.themeData}
|
themeData={this.state.themeData}
|
||||||
themeAlgorithm={this.state.themeAlgorithm}
|
themeAlgorithm={this.state.themeAlgorithm}
|
||||||
|
@ -384,7 +384,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.application.tokenFormat} onChange={(value => {this.updateApplicationField("tokenFormat", value);})}
|
<Select virtual={false} style={{width: "100%"}} value={this.state.application.tokenFormat} onChange={(value => {this.updateApplicationField("tokenFormat", value);})}
|
||||||
options={["JWT", "JWT-Empty", "JWT-Custom"].map((item) => Setting.getOption(item, item))}
|
options={["JWT", "JWT-Empty", "JWT-Custom", "JWT-Standard"].map((item) => Setting.getOption(item, item))}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -108,8 +108,8 @@ class EntryPage extends React.Component {
|
|||||||
<Route exact path="/signup/oauth/authorize" render={(props) => <SignupPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />} />
|
<Route exact path="/signup/oauth/authorize" render={(props) => <SignupPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />} />
|
||||||
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage {...this.props} application={this.state.application} type={"code"} mode={"signin"} onUpdateApplication={onUpdateApplication} {...props} />} />
|
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage {...this.props} application={this.state.application} type={"code"} mode={"signin"} onUpdateApplication={onUpdateApplication} {...props} />} />
|
||||||
<Route exact path="/login/saml/authorize/:owner/:applicationName" render={(props) => <LoginPage {...this.props} application={this.state.application} type={"saml"} mode={"signin"} onUpdateApplication={onUpdateApplication} {...props} />} />
|
<Route exact path="/login/saml/authorize/:owner/:applicationName" render={(props) => <LoginPage {...this.props} application={this.state.application} type={"saml"} mode={"signin"} onUpdateApplication={onUpdateApplication} {...props} />} />
|
||||||
<Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
<Route exact path="/forget" render={(props) => <SelfForgetPage {...this.props} account={this.props.account} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />} />
|
||||||
<Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
<Route exact path="/forget/:applicationName" render={(props) => <ForgetPage {...this.props} account={this.props.account} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />} />
|
||||||
<Route exact path="/prompt" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
<Route exact path="/prompt" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
||||||
<Route exact path="/prompt/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
<Route exact path="/prompt/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
||||||
<Route exact path="/result" render={(props) => this.renderHomeIfLoggedIn(<ResultPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
<Route exact path="/result" render={(props) => this.renderHomeIfLoggedIn(<ResultPage {...this.props} application={this.state.application} onUpdateApplication={onUpdateApplication} {...props} />)} />
|
||||||
|
@ -199,7 +199,7 @@ class InvitationEditPage extends React.Component {
|
|||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.invitation.application}
|
<Select virtual={false} style={{width: "100%"}} value={this.state.invitation.application}
|
||||||
onChange={(value => {this.updateInvitationField("application", value);})}
|
onChange={(value => {this.updateInvitationField("application", value);})}
|
||||||
options={[
|
options={[
|
||||||
{label: "All", value: i18next.t("general:All")},
|
{label: i18next.t("general:All"), value: "All"},
|
||||||
...this.state.applications.map((application) => Setting.getOption(application.name, application.name)),
|
...this.state.applications.map((application) => Setting.getOption(application.name, application.name)),
|
||||||
]} />
|
]} />
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -328,6 +328,8 @@ function ManagementPage(props) {
|
|||||||
return <Redirect to="/login" />;
|
return <Redirect to="/login" />;
|
||||||
} else if (props.account === undefined) {
|
} else if (props.account === undefined) {
|
||||||
return null;
|
return null;
|
||||||
|
} else if (props.account.needUpdatePassword) {
|
||||||
|
return <Redirect to={"/forget/" + props.application.name} />;
|
||||||
} else {
|
} else {
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
@ -409,7 +411,7 @@ function ManagementPage(props) {
|
|||||||
return Setting.isMobile() || window.location.pathname.startsWith("/trees");
|
return Setting.isMobile() || window.location.pathname.startsWith("/trees");
|
||||||
}
|
}
|
||||||
|
|
||||||
const menuStyleRight = Setting.isAdminUser(props.account) && !Setting.isMobile() ? "calc(180px + 280px)" : "280px";
|
const menuStyleRight = Setting.isAdminUser(props.account) && !Setting.isMobile() ? "calc(180px + 280px)" : "320px";
|
||||||
|
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
setMenuVisible(false);
|
setMenuVisible(false);
|
||||||
|
@ -436,6 +436,26 @@ class OrganizationEditPage extends React.Component {
|
|||||||
}} />
|
}} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 19 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("organization:Use Email as username"), i18next.t("organization:Use Email as username - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={1} >
|
||||||
|
<Switch checked={this.state.organization.useEmailAsUsername} onChange={checked => {
|
||||||
|
this.updateOrganizationField("useEmailAsUsername", checked);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 19 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("general:Enable tour"), i18next.t("general:Enable tour - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={1} >
|
||||||
|
<Switch checked={this.state.organization.enableTour} onChange={checked => {
|
||||||
|
this.updateOrganizationField("enableTour", checked);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("organization:Account items"), i18next.t("organization:Account items - Tooltip"))} :
|
{Setting.getLabel(i18next.t("organization:Account items"), i18next.t("organization:Account items - Tooltip"))} :
|
||||||
|
@ -44,6 +44,7 @@ class OrganizationListPage extends BaseListPage {
|
|||||||
defaultPassword: "",
|
defaultPassword: "",
|
||||||
enableSoftDeletion: false,
|
enableSoftDeletion: false,
|
||||||
isProfilePublic: true,
|
isProfilePublic: true,
|
||||||
|
enableTour: true,
|
||||||
accountItems: [
|
accountItems: [
|
||||||
{name: "Organization", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
{name: "Organization", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||||
{name: "ID", visible: true, viewRule: "Public", modifyRule: "Immutable"},
|
{name: "ID", visible: true, viewRule: "Public", modifyRule: "Immutable"},
|
||||||
@ -87,6 +88,7 @@ class OrganizationListPage extends BaseListPage {
|
|||||||
{Name: "Multi-factor authentication", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
{Name: "Multi-factor authentication", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
{Name: "WebAuthn credentials", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
{Name: "WebAuthn credentials", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
{Name: "Managed accounts", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
{Name: "Managed accounts", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
|
{Name: "MFA accounts", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import {Button, Result, Spin} from "antd";
|
|||||||
import * as PaymentBackend from "./backend/PaymentBackend";
|
import * as PaymentBackend from "./backend/PaymentBackend";
|
||||||
import * as PricingBackend from "./backend/PricingBackend";
|
import * as PricingBackend from "./backend/PricingBackend";
|
||||||
import * as SubscriptionBackend from "./backend/SubscriptionBackend";
|
import * as SubscriptionBackend from "./backend/SubscriptionBackend";
|
||||||
|
import * as UserBackend from "./backend/UserBackend";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ class PaymentResultPage extends React.Component {
|
|||||||
pricing: props.pricing ?? null,
|
pricing: props.pricing ?? null,
|
||||||
subscription: props.subscription ?? null,
|
subscription: props.subscription ?? null,
|
||||||
timeout: null,
|
timeout: null,
|
||||||
|
user: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +43,25 @@ class PaymentResultPage extends React.Component {
|
|||||||
this.getPayment();
|
this.getPayment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUser() {
|
||||||
|
UserBackend.getUser(this.props.account.owner, this.props.account.name)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.data === null) {
|
||||||
|
this.props.history.push("/404");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === "error") {
|
||||||
|
Setting.showMessage("error", res.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
user: res.data,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
if (this.state.timeout !== null) {
|
if (this.state.timeout !== null) {
|
||||||
clearTimeout(this.state.timeout);
|
clearTimeout(this.state.timeout);
|
||||||
@ -101,7 +122,7 @@ class PaymentResultPage extends React.Component {
|
|||||||
payment: payment,
|
payment: payment,
|
||||||
});
|
});
|
||||||
if (payment.state === "Created") {
|
if (payment.state === "Created") {
|
||||||
if (["PayPal", "Stripe", "Alipay", "WeChat Pay"].includes(payment.type)) {
|
if (["PayPal", "Stripe", "Alipay", "WeChat Pay", "Balance"].includes(payment.type)) {
|
||||||
this.setState({
|
this.setState({
|
||||||
timeout: setTimeout(async() => {
|
timeout: setTimeout(async() => {
|
||||||
await PaymentBackend.notifyPayment(this.state.owner, this.state.paymentName);
|
await PaymentBackend.notifyPayment(this.state.owner, this.state.paymentName);
|
||||||
@ -114,6 +135,12 @@ class PaymentResultPage extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (payment.state === "Paid") {
|
||||||
|
if (this.props.account) {
|
||||||
|
this.getUser();
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Setting.showMessage("error", err.message);
|
Setting.showMessage("error", err.message);
|
||||||
return;
|
return;
|
||||||
@ -136,6 +163,27 @@ class PaymentResultPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (payment.state === "Paid") {
|
if (payment.state === "Paid") {
|
||||||
|
if (payment.isRecharge) {
|
||||||
|
return (
|
||||||
|
<div className="login-content">
|
||||||
|
{
|
||||||
|
Setting.renderHelmet(payment)
|
||||||
|
}
|
||||||
|
<Result
|
||||||
|
status="success"
|
||||||
|
title={`${i18next.t("payment:Recharged successfully")}`}
|
||||||
|
subTitle={`${i18next.t("payment:You have successfully recharged")} ${payment.price} ${Setting.getCurrencyText(payment)}, ${i18next.t("payment:Your current balance is")} ${this.state.user?.balance} ${Setting.getCurrencyText(payment)}`}
|
||||||
|
extra={[
|
||||||
|
<Button type="primary" key="returnUrl" onClick={() => {
|
||||||
|
this.goToPaymentUrl(payment);
|
||||||
|
}}>
|
||||||
|
{i18next.t("payment:Return to Website")}
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="login-content">
|
<div className="login-content">
|
||||||
{
|
{
|
||||||
|
@ -487,6 +487,7 @@ class PermissionEditPage extends React.Component {
|
|||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
||||||
this.setState({
|
this.setState({
|
||||||
|
organizationName: this.state.permission.owner,
|
||||||
permissionName: this.state.permission.name,
|
permissionName: this.state.permission.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Descriptions, Spin} from "antd";
|
import {Button, Descriptions, InputNumber, Space, Spin} from "antd";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import * as ProductBackend from "./backend/ProductBackend";
|
import * as ProductBackend from "./backend/ProductBackend";
|
||||||
import * as PlanBackend from "./backend/PlanBackend";
|
import * as PlanBackend from "./backend/PlanBackend";
|
||||||
@ -36,6 +36,7 @@ class ProductBuyPage extends React.Component {
|
|||||||
pricing: props?.pricing ?? null,
|
pricing: props?.pricing ?? null,
|
||||||
plan: null,
|
plan: null,
|
||||||
isPlacingOrder: false,
|
isPlacingOrder: false,
|
||||||
|
customPrice: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,18 +128,8 @@ class ProductBuyPage extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrencyText(product) {
|
|
||||||
if (product?.currency === "USD") {
|
|
||||||
return i18next.t("product:USD");
|
|
||||||
} else if (product?.currency === "CNY") {
|
|
||||||
return i18next.t("product:CNY");
|
|
||||||
} else {
|
|
||||||
return "(Unknown currency)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getPrice(product) {
|
getPrice(product) {
|
||||||
return `${this.getCurrencySymbol(product)}${product?.price} (${this.getCurrencyText(product)})`;
|
return `${this.getCurrencySymbol(product)}${product?.price} (${Setting.getCurrencyText(product)})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call Weechat Pay via jsapi
|
// Call Weechat Pay via jsapi
|
||||||
@ -192,7 +183,7 @@ class ProductBuyPage extends React.Component {
|
|||||||
isPlacingOrder: true,
|
isPlacingOrder: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
ProductBackend.buyProduct(product.owner, product.name, provider.name, this.state.pricingName ?? "", this.state.planName ?? "", this.state.userName ?? "", this.state.paymentEnv)
|
ProductBackend.buyProduct(product.owner, product.name, provider.name, this.state.pricingName ?? "", this.state.planName ?? "", this.state.userName ?? "", this.state.paymentEnv, this.state.customPrice)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
const payment = res.data;
|
const payment = res.data;
|
||||||
@ -295,15 +286,27 @@ class ProductBuyPage extends React.Component {
|
|||||||
<Descriptions.Item label={i18next.t("product:Image")} span={3}>
|
<Descriptions.Item label={i18next.t("product:Image")} span={3}>
|
||||||
<img src={product?.image} alt={product?.name} height={90} style={{marginBottom: "20px"}} />
|
<img src={product?.image} alt={product?.name} height={90} style={{marginBottom: "20px"}} />
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={i18next.t("product:Price")}>
|
{
|
||||||
<span style={{fontSize: 28, color: "red", fontWeight: "bold"}}>
|
product.isRecharge ? (
|
||||||
{
|
<Descriptions.Item span={3} label={i18next.t("product:Price")}>
|
||||||
this.getPrice(product)
|
<Space>
|
||||||
}
|
<InputNumber min={0} value={this.state.customPrice} onChange={(e) => {this.setState({customPrice: e});}} /> {Setting.getCurrencyText(product)}
|
||||||
</span>
|
</Space>
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={i18next.t("product:Quantity")}><span style={{fontSize: 16}}>{product?.quantity}</span></Descriptions.Item>
|
) : (
|
||||||
<Descriptions.Item label={i18next.t("product:Sold")}><span style={{fontSize: 16}}>{product?.sold}</span></Descriptions.Item>
|
<React.Fragment>
|
||||||
|
<Descriptions.Item label={i18next.t("product:Price")}>
|
||||||
|
<span style={{fontSize: 28, color: "red", fontWeight: "bold"}}>
|
||||||
|
{
|
||||||
|
this.getPrice(product)
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={i18next.t("product:Quantity")}><span style={{fontSize: 16}}>{product?.quantity}</span></Descriptions.Item>
|
||||||
|
<Descriptions.Item label={i18next.t("product:Sold")}><span style={{fontSize: 16}}>{product?.sold}</span></Descriptions.Item>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
<Descriptions.Item label={i18next.t("product:Pay")} span={3}>
|
<Descriptions.Item label={i18next.t("product:Pay")} span={3}>
|
||||||
{
|
{
|
||||||
this.renderPay(product)
|
this.renderPay(product)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Card, Col, Input, InputNumber, Row, Select} from "antd";
|
import {Button, Card, Col, Input, InputNumber, Row, Select, Switch} from "antd";
|
||||||
import * as ProductBackend from "./backend/ProductBackend";
|
import * as ProductBackend from "./backend/ProductBackend";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
@ -216,14 +216,27 @@ class ProductEditPage extends React.Component {
|
|||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("product:Price"), i18next.t("product:Price - Tooltip"))} :
|
{Setting.getLabel(i18next.t("product:Is recharge"), i18next.t("product:Is recharge - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<InputNumber value={this.state.product.price} disabled={isCreatedByPlan} onChange={value => {
|
<Switch checked={this.state.product.isRecharge} onChange={value => {
|
||||||
this.updateProductField("price", value);
|
this.updateProductField("isRecharge", value);
|
||||||
}} />
|
}} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
{
|
||||||
|
this.state.product.isRecharge ? null : (
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("product:Price"), i18next.t("product:Price - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<InputNumber value={this.state.product.price} disabled={isCreatedByPlan} onChange={value => {
|
||||||
|
this.updateProductField("price", value);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("product:Quantity"), i18next.t("product:Quantity - Tooltip"))} :
|
{Setting.getLabel(i18next.t("product:Quantity"), i18next.t("product:Quantity - Tooltip"))} :
|
||||||
|
@ -38,6 +38,7 @@ class ProductListPage extends BaseListPage {
|
|||||||
price: 300,
|
price: 300,
|
||||||
quantity: 99,
|
quantity: 99,
|
||||||
sold: 10,
|
sold: 10,
|
||||||
|
isRecharge: false,
|
||||||
providers: [],
|
providers: [],
|
||||||
state: "Published",
|
state: "Published",
|
||||||
};
|
};
|
||||||
|
@ -209,8 +209,6 @@ class ProviderEditPage extends React.Component {
|
|||||||
return Setting.getLabel(i18next.t("provider:Public key"), i18next.t("provider:Public key - Tooltip"));
|
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") {
|
} 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"));
|
return Setting.getLabel(i18next.t("provider:Sender Id"), i18next.t("provider:Sender Id - Tooltip"));
|
||||||
} else if (provider.type === "SendCloud SMS") {
|
|
||||||
return "SMS_USER";
|
|
||||||
} else {
|
} else {
|
||||||
return Setting.getLabel(i18next.t("provider:Client ID"), i18next.t("provider:Client ID - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Client ID"), i18next.t("provider:Client ID - Tooltip"));
|
||||||
}
|
}
|
||||||
@ -262,8 +260,6 @@ class ProviderEditPage extends React.Component {
|
|||||||
return Setting.getLabel(i18next.t("provider:Auth Key"), i18next.t("provider:Auth Key - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Auth Key"), i18next.t("provider:Auth Key - Tooltip"));
|
||||||
} else if (provider.type === "Infobip SMS") {
|
} else if (provider.type === "Infobip SMS") {
|
||||||
return Setting.getLabel(i18next.t("provider:Api Key"), i18next.t("provider:Api Key - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Api Key"), i18next.t("provider:Api Key - Tooltip"));
|
||||||
} else if (provider.type === "SendCloud SMS") {
|
|
||||||
return "SMS_KEY";
|
|
||||||
} else {
|
} else {
|
||||||
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
return Setting.getLabel(i18next.t("provider:Client secret"), i18next.t("provider:Client secret - Tooltip"));
|
||||||
}
|
}
|
||||||
@ -729,7 +725,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
(this.state.provider.category === "Web3") ||
|
(this.state.provider.category === "Web3") ||
|
||||||
(this.state.provider.category === "Storage" && this.state.provider.type === "Local File System") ||
|
(this.state.provider.category === "Storage" && this.state.provider.type === "Local File System") ||
|
||||||
(this.state.provider.category === "SMS" && this.state.provider.type === "Custom HTTP SMS") ||
|
(this.state.provider.category === "SMS" && this.state.provider.type === "Custom HTTP SMS") ||
|
||||||
(this.state.provider.category === "Notification" && (this.state.provider.type === "Google Chat" || this.state.provider.type === "Custom HTTP")) ? null : (
|
(this.state.provider.category === "Notification" && (this.state.provider.type === "Google Chat" || this.state.provider.type === "Custom HTTP") || this.state.provider.type === "Balance") ? null : (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{
|
{
|
||||||
(this.state.provider.category === "Storage" && this.state.provider.type === "Google Cloud Storage") ||
|
(this.state.provider.category === "Storage" && this.state.provider.type === "Google Cloud Storage") ||
|
||||||
@ -832,6 +828,20 @@ class ProviderEditPage extends React.Component {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
this.state.provider.type !== "Google" ? null : (
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("provider:Get phone number"), i18next.t("provider:Get phone number - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={1} >
|
||||||
|
<Switch disabled={!this.state.provider.clientId} checked={this.state.provider.disableSsl} onChange={checked => {
|
||||||
|
this.updateProviderField("disableSsl", checked);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)
|
||||||
|
}
|
||||||
{
|
{
|
||||||
this.state.provider.type !== "ADFS" && this.state.provider.type !== "AzureAD" && this.state.provider.type !== "AzureADB2C" && this.state.provider.type !== "Casdoor" && this.state.provider.type !== "Okta" ? null : (
|
this.state.provider.type !== "ADFS" && this.state.provider.type !== "AzureAD" && this.state.provider.type !== "AzureADB2C" && this.state.provider.type !== "Casdoor" && this.state.provider.type !== "Okta" ? null : (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -1093,7 +1103,7 @@ class ProviderEditPage extends React.Component {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
) : this.state.provider.category === "SMS" ? (
|
) : this.state.provider.category === "SMS" ? (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{["Custom HTTP SMS", "Twilio SMS", "Amazon SNS", "Azure ACS", "Msg91 SMS", "Infobip SMS", "SendCloud SMS"].includes(this.state.provider.type) ?
|
{["Custom HTTP SMS", "Twilio SMS", "Amazon SNS", "Azure ACS", "Msg91 SMS", "Infobip SMS"].includes(this.state.provider.type) ?
|
||||||
null :
|
null :
|
||||||
(<Row style={{marginTop: "20px"}} >
|
(<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
@ -151,6 +151,14 @@ class RecordListPage extends BaseListPage {
|
|||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("language"),
|
...this.getColumnSearchProps("language"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("record:Status code"),
|
||||||
|
dataIndex: "statusCode",
|
||||||
|
key: "statusCode",
|
||||||
|
width: "90px",
|
||||||
|
sorter: true,
|
||||||
|
...this.getColumnSearchProps("statusCode"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("record:Response"),
|
title: i18next.t("record:Response"),
|
||||||
dataIndex: "response",
|
dataIndex: "response",
|
||||||
|
@ -56,6 +56,8 @@ export const Countries = [
|
|||||||
{label: "Українська", key: "uk", country: "UA", alt: "Українська"},
|
{label: "Українська", key: "uk", country: "UA", alt: "Українська"},
|
||||||
{label: "Қазақ", key: "kk", country: "KZ", alt: "Қазақ"},
|
{label: "Қазақ", key: "kk", country: "KZ", alt: "Қазақ"},
|
||||||
{label: "فارسی", key: "fa", country: "IR", alt: "فارسی"},
|
{label: "فارسی", key: "fa", country: "IR", alt: "فارسی"},
|
||||||
|
{label: "Čeština", key: "cs", country: "CZ", alt: "Čeština"},
|
||||||
|
{label: "Slovenčina", key: "sk", country: "SK", alt: "Slovenčina"},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function getThemeData(organization, application) {
|
export function getThemeData(organization, application) {
|
||||||
@ -139,10 +141,6 @@ export const OtherProviderInfo = {
|
|||||||
logo: `${StaticBaseUrl}/img/social_twilio.svg`,
|
logo: `${StaticBaseUrl}/img/social_twilio.svg`,
|
||||||
url: "https://www.twilio.com/messaging",
|
url: "https://www.twilio.com/messaging",
|
||||||
},
|
},
|
||||||
"SendCloud SMS": {
|
|
||||||
logo: `${StaticBaseUrl}/img/sms_sendcloud.png`,
|
|
||||||
url: "https://www.sendcloud.net/",
|
|
||||||
},
|
|
||||||
"SmsBao SMS": {
|
"SmsBao SMS": {
|
||||||
logo: `${StaticBaseUrl}/img/social_smsbao.png`,
|
logo: `${StaticBaseUrl}/img/social_smsbao.png`,
|
||||||
url: "https://www.smsbao.com/",
|
url: "https://www.smsbao.com/",
|
||||||
@ -251,6 +249,10 @@ export const OtherProviderInfo = {
|
|||||||
logo: `${StaticBaseUrl}/img/payment_paypal.png`,
|
logo: `${StaticBaseUrl}/img/payment_paypal.png`,
|
||||||
url: "",
|
url: "",
|
||||||
},
|
},
|
||||||
|
"Balance": {
|
||||||
|
logo: `${StaticBaseUrl}/img/payment_balance.svg`,
|
||||||
|
url: "",
|
||||||
|
},
|
||||||
"Alipay": {
|
"Alipay": {
|
||||||
logo: `${StaticBaseUrl}/img/payment_alipay.png`,
|
logo: `${StaticBaseUrl}/img/payment_alipay.png`,
|
||||||
url: "https://www.alipay.com/",
|
url: "https://www.alipay.com/",
|
||||||
@ -1043,7 +1045,6 @@ export function getProviderTypeOptions(category) {
|
|||||||
{id: "Huawei Cloud SMS", name: "Huawei Cloud SMS"},
|
{id: "Huawei Cloud SMS", name: "Huawei Cloud SMS"},
|
||||||
{id: "UCloud SMS", name: "UCloud SMS"},
|
{id: "UCloud SMS", name: "UCloud SMS"},
|
||||||
{id: "Twilio SMS", name: "Twilio SMS"},
|
{id: "Twilio SMS", name: "Twilio SMS"},
|
||||||
{id: "SendCloud SMS", name: "SendCloud SMS"},
|
|
||||||
{id: "SmsBao SMS", name: "SmsBao SMS"},
|
{id: "SmsBao SMS", name: "SmsBao SMS"},
|
||||||
{id: "SUBMAIL SMS", name: "SUBMAIL SMS"},
|
{id: "SUBMAIL SMS", name: "SUBMAIL SMS"},
|
||||||
{id: "Msg91 SMS", name: "Msg91 SMS"},
|
{id: "Msg91 SMS", name: "Msg91 SMS"},
|
||||||
@ -1072,6 +1073,7 @@ export function getProviderTypeOptions(category) {
|
|||||||
} else if (category === "Payment") {
|
} else if (category === "Payment") {
|
||||||
return ([
|
return ([
|
||||||
{id: "Dummy", name: "Dummy"},
|
{id: "Dummy", name: "Dummy"},
|
||||||
|
{id: "Balance", name: "Balance"},
|
||||||
{id: "Alipay", name: "Alipay"},
|
{id: "Alipay", name: "Alipay"},
|
||||||
{id: "WeChat Pay", name: "WeChat Pay"},
|
{id: "WeChat Pay", name: "WeChat Pay"},
|
||||||
{id: "PayPal", name: "PayPal"},
|
{id: "PayPal", name: "PayPal"},
|
||||||
@ -1468,7 +1470,7 @@ export function getUserCommonFields() {
|
|||||||
return ["Owner", "Name", "CreatedTime", "UpdatedTime", "DeletedTime", "Id", "Type", "Password", "PasswordSalt", "DisplayName", "FirstName", "LastName", "Avatar", "PermanentAvatar",
|
return ["Owner", "Name", "CreatedTime", "UpdatedTime", "DeletedTime", "Id", "Type", "Password", "PasswordSalt", "DisplayName", "FirstName", "LastName", "Avatar", "PermanentAvatar",
|
||||||
"Email", "EmailVerified", "Phone", "Location", "Address", "Affiliation", "Title", "IdCardType", "IdCard", "Homepage", "Bio", "Tag", "Region",
|
"Email", "EmailVerified", "Phone", "Location", "Address", "Affiliation", "Title", "IdCardType", "IdCard", "Homepage", "Bio", "Tag", "Region",
|
||||||
"Language", "Gender", "Birthday", "Education", "Score", "Ranking", "IsDefaultAvatar", "IsOnline", "IsAdmin", "IsForbidden", "IsDeleted", "CreatedIp",
|
"Language", "Gender", "Birthday", "Education", "Score", "Ranking", "IsDefaultAvatar", "IsOnline", "IsAdmin", "IsForbidden", "IsDeleted", "CreatedIp",
|
||||||
"PreferredMfaType", "TotpSecret", "SignupApplication"];
|
"PreferredMfaType", "TotpSecret", "SignupApplication", "RecoveryCodes", "MfaPhoneEnabled", "MfaEmailEnabled"];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDefaultFooterContent() {
|
export function getDefaultFooterContent() {
|
||||||
@ -1521,3 +1523,13 @@ export function getDefaultHtmlEmailContent() {
|
|||||||
</body>
|
</body>
|
||||||
</html>`;
|
</html>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCurrencyText(product) {
|
||||||
|
if (product?.currency === "USD") {
|
||||||
|
return i18next.t("product:USD");
|
||||||
|
} else if (product?.currency === "CNY") {
|
||||||
|
return i18next.t("product:CNY");
|
||||||
|
} else {
|
||||||
|
return "(Unknown currency)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -203,13 +203,24 @@ export function getNextUrl(pathName = window.location.pathname) {
|
|||||||
return TourUrlList[TourUrlList.indexOf(pathName.replace("/", "")) + 1] || "";
|
return TourUrlList[TourUrlList.indexOf(pathName.replace("/", "")) + 1] || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let orgIsTourVisible = true;
|
||||||
|
|
||||||
|
export function setOrgIsTourVisible(visible) {
|
||||||
|
orgIsTourVisible = visible;
|
||||||
|
}
|
||||||
|
|
||||||
export function setIsTourVisible(visible) {
|
export function setIsTourVisible(visible) {
|
||||||
localStorage.setItem("isTourVisible", visible);
|
localStorage.setItem("isTourVisible", visible);
|
||||||
window.dispatchEvent(new Event("storageTourChanged"));
|
}
|
||||||
|
|
||||||
|
export function setTourLogo(tourLogoSrc) {
|
||||||
|
if (tourLogoSrc !== "") {
|
||||||
|
TourObj["home"][0]["cover"] = (<img alt="casdoor.png" src={tourLogoSrc} />);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTourVisible() {
|
export function getTourVisible() {
|
||||||
return localStorage.getItem("isTourVisible") !== "false";
|
return localStorage.getItem("isTourVisible") !== "false" && orgIsTourVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNextButtonChild(nextPathName) {
|
export function getNextButtonChild(nextPathName) {
|
||||||
|
@ -41,6 +41,7 @@ import {CheckCircleOutlined, HolderOutlined, UsergroupAddOutlined} from "@ant-de
|
|||||||
import * as MfaBackend from "./backend/MfaBackend";
|
import * as MfaBackend from "./backend/MfaBackend";
|
||||||
import AccountAvatar from "./account/AccountAvatar";
|
import AccountAvatar from "./account/AccountAvatar";
|
||||||
import FaceIdTable from "./table/FaceIdTable";
|
import FaceIdTable from "./table/FaceIdTable";
|
||||||
|
import MfaAccountTable from "./table/MfaAccountTable";
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
@ -202,7 +203,7 @@ class UserEditPage extends React.Component {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUserField(key, value) {
|
updateUserField(key, value, idx) {
|
||||||
if (this.props.account === null) {
|
if (this.props.account === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -210,7 +211,15 @@ class UserEditPage extends React.Component {
|
|||||||
value = this.parseUserField(key, value);
|
value = this.parseUserField(key, value);
|
||||||
|
|
||||||
const user = this.state.user;
|
const user = this.state.user;
|
||||||
user[key] = value;
|
if (key === "address") {
|
||||||
|
if (!user[key]) {
|
||||||
|
user[key] = ["", ""];
|
||||||
|
}
|
||||||
|
user[key][idx] = value;
|
||||||
|
} else {
|
||||||
|
user[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
user: user,
|
user: user,
|
||||||
});
|
});
|
||||||
@ -501,16 +510,33 @@ class UserEditPage extends React.Component {
|
|||||||
);
|
);
|
||||||
} else if (accountItem.name === "Address") {
|
} else if (accountItem.name === "Address") {
|
||||||
return (
|
return (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<React.Fragment>
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Row style={{marginTop: "20px"}} >
|
||||||
{Setting.getLabel(i18next.t("user:Address"), i18next.t("user:Address - Tooltip"))} :
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
</Col>
|
{Setting.getLabel(i18next.t("user:Address"), i18next.t("user:Address - Tooltip"))} :
|
||||||
<Col span={22} >
|
</Col>
|
||||||
<Input value={this.state.user.address} onChange={e => {
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
this.updateUserField("address", e.target.value);
|
<span>{i18next.t("user:Address line") + " 1"}</span> :
|
||||||
}} />
|
</Col>
|
||||||
</Col>
|
<Col span={20} >
|
||||||
</Row>
|
<Input value={!this.state.user.address ? "" : this.state.user.address[0]} onChange={e => {
|
||||||
|
this.updateUserField("address", e.target.value, 0);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
</Col>
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
<span>{i18next.t("user:Address line") + " 2"}</span> :
|
||||||
|
</Col>
|
||||||
|
<Col span={20} >
|
||||||
|
<Input value={!this.state.user.address ? "" : this.state.user.address[1]} onChange={e => {
|
||||||
|
this.updateUserField("address", e.target.value, 1);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
} else if (accountItem.name === "Affiliation") {
|
} else if (accountItem.name === "Affiliation") {
|
||||||
return (
|
return (
|
||||||
@ -682,6 +708,19 @@ class UserEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
} else if (accountItem.name === "Balance") {
|
||||||
|
return (
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("user:Balance"), i18next.t("user:Balance - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<InputNumber value={this.state.user.balance} onChange={value => {
|
||||||
|
this.updateUserField("balance", value);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
} else if (accountItem.name === "Score") {
|
} else if (accountItem.name === "Score") {
|
||||||
return (
|
return (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -1001,6 +1040,34 @@ class UserEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
} else if (accountItem.name === "MFA accounts") {
|
||||||
|
return (
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("user:MFA accounts"), i18next.t("user:MFA accounts"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<MfaAccountTable
|
||||||
|
title={i18next.t("user:MFA accounts")}
|
||||||
|
table={this.state.user.mfaAccounts}
|
||||||
|
onUpdateTable={(table) => {this.updateUserField("mfaAccounts", table);}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
} else if (accountItem.name === "Need update password") {
|
||||||
|
return (
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
|
{Setting.getLabel(i18next.t("user:Need update password"), i18next.t("user:Need update password - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={(Setting.isMobile()) ? 22 : 2} >
|
||||||
|
<Switch disabled={(!this.state.user.phone) && (!this.state.user.email) && (!this.state.user.mfaProps)} checked={this.state.user.needUpdatePassword} onChange={checked => {
|
||||||
|
this.updateUserField("needUpdatePassword", checked);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +167,9 @@ class WebhookEditPage extends React.Component {
|
|||||||
["add", "update", "delete"].forEach(action => {
|
["add", "update", "delete"].forEach(action => {
|
||||||
res.push(`${action}-${obj}`);
|
res.push(`${action}-${obj}`);
|
||||||
});
|
});
|
||||||
|
if (obj === "payment") {
|
||||||
|
res.push("invoice-payment", "notify-payment");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -153,21 +153,37 @@ class AuthCallback extends React.Component {
|
|||||||
// OAuth
|
// OAuth
|
||||||
const oAuthParams = Util.getOAuthGetParameters(innerParams);
|
const oAuthParams = Util.getOAuthGetParameters(innerParams);
|
||||||
const concatChar = oAuthParams?.redirectUri?.includes("?") ? "&" : "?";
|
const concatChar = oAuthParams?.redirectUri?.includes("?") ? "&" : "?";
|
||||||
|
const signinUrl = localStorage.getItem("signinUrl");
|
||||||
|
|
||||||
AuthBackend.login(body, oAuthParams)
|
AuthBackend.login(body, oAuthParams)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
const responseType = this.getResponseType();
|
const responseType = this.getResponseType();
|
||||||
if (responseType === "login") {
|
if (responseType === "login") {
|
||||||
|
if (res.data2) {
|
||||||
|
sessionStorage.setItem("signinUrl", signinUrl);
|
||||||
|
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Setting.showMessage("success", "Logged in successfully");
|
Setting.showMessage("success", "Logged in successfully");
|
||||||
// Setting.goToLinkSoft(this, "/");
|
// Setting.goToLinkSoft(this, "/");
|
||||||
|
|
||||||
const link = Setting.getFromLink();
|
const link = Setting.getFromLink();
|
||||||
Setting.goToLink(link);
|
Setting.goToLink(link);
|
||||||
} else if (responseType === "code") {
|
} else if (responseType === "code") {
|
||||||
|
if (res.data2) {
|
||||||
|
sessionStorage.setItem("signinUrl", signinUrl);
|
||||||
|
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const code = res.data;
|
const code = res.data;
|
||||||
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
|
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
|
||||||
// Setting.showMessage("success", `Authorization code: ${res.data}`);
|
// Setting.showMessage("success", `Authorization code: ${res.data}`);
|
||||||
} else if (responseType === "token" || responseType === "id_token") {
|
} else if (responseType === "token" || responseType === "id_token") {
|
||||||
|
if (res.data2) {
|
||||||
|
sessionStorage.setItem("signinUrl", signinUrl);
|
||||||
|
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const token = res.data;
|
const token = res.data;
|
||||||
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
|
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
|
||||||
} else if (responseType === "link") {
|
} else if (responseType === "link") {
|
||||||
@ -181,6 +197,11 @@ class AuthCallback extends React.Component {
|
|||||||
relayState: oAuthParams.relayState,
|
relayState: oAuthParams.relayState,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
if (res.data2.needUpdatePassword) {
|
||||||
|
sessionStorage.setItem("signinUrl", signinUrl);
|
||||||
|
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const SAMLResponse = res.data;
|
const SAMLResponse = res.data;
|
||||||
const redirectUri = res.data2.redirectUrl;
|
const redirectUri = res.data2.redirectUrl;
|
||||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||||
|
@ -35,8 +35,8 @@ class ForgetPage extends React.Component {
|
|||||||
classes: props,
|
classes: props,
|
||||||
applicationName: props.applicationName ?? props.match.params?.applicationName,
|
applicationName: props.applicationName ?? props.match.params?.applicationName,
|
||||||
msg: null,
|
msg: null,
|
||||||
name: "",
|
name: props.account ? props.account.name : "",
|
||||||
username: "",
|
username: props.account ? props.account.name : "",
|
||||||
phone: "",
|
phone: "",
|
||||||
email: "",
|
email: "",
|
||||||
dest: "",
|
dest: "",
|
||||||
@ -44,7 +44,6 @@ class ForgetPage extends React.Component {
|
|||||||
verifyType: "", // "email", "phone"
|
verifyType: "", // "email", "phone"
|
||||||
current: 0,
|
current: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.form = React.createRef();
|
this.form = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +204,7 @@ class ForgetPage extends React.Component {
|
|||||||
initialValues={{
|
initialValues={{
|
||||||
application: application.name,
|
application: application.name,
|
||||||
organization: application.organization,
|
organization: application.organization,
|
||||||
|
username: this.state.name,
|
||||||
}}
|
}}
|
||||||
style={{width: "300px"}}
|
style={{width: "300px"}}
|
||||||
size="large"
|
size="large"
|
||||||
@ -488,7 +488,7 @@ class ForgetPage extends React.Component {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<div style={{textAlign: "center", fontSize: "28px"}}>
|
<div style={{textAlign: "center", fontSize: "28px"}}>
|
||||||
{i18next.t("forget:Retrieve password")}
|
{i18next.t("forget:Reset password")}
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React, {Suspense, lazy} from "react";
|
import React, {Suspense, lazy} from "react";
|
||||||
import {Button, Checkbox, Col, Form, Input, Result, Spin, Tabs} from "antd";
|
import {Button, Checkbox, Col, Form, Input, Result, Spin, Tabs, message} from "antd";
|
||||||
import {ArrowLeftOutlined, LockOutlined, UserOutlined} from "@ant-design/icons";
|
import {ArrowLeftOutlined, LockOutlined, UserOutlined} from "@ant-design/icons";
|
||||||
import {withRouter} from "react-router-dom";
|
import {withRouter} from "react-router-dom";
|
||||||
import * as UserWebauthnBackend from "../backend/UserWebauthnBackend";
|
import * as UserWebauthnBackend from "../backend/UserWebauthnBackend";
|
||||||
@ -23,7 +23,6 @@ import * as AuthBackend from "./AuthBackend";
|
|||||||
import * as OrganizationBackend from "../backend/OrganizationBackend";
|
import * as OrganizationBackend from "../backend/OrganizationBackend";
|
||||||
import * as ApplicationBackend from "../backend/ApplicationBackend";
|
import * as ApplicationBackend from "../backend/ApplicationBackend";
|
||||||
import * as Provider from "./Provider";
|
import * as Provider from "./Provider";
|
||||||
import * as ProviderButton from "./ProviderButton";
|
|
||||||
import * as Util from "./Util";
|
import * as Util from "./Util";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import * as AgreementModal from "../common/modal/AgreementModal";
|
import * as AgreementModal from "../common/modal/AgreementModal";
|
||||||
@ -36,6 +35,7 @@ import {CaptchaModal, CaptchaRule} from "../common/modal/CaptchaModal";
|
|||||||
import RedirectForm from "../common/RedirectForm";
|
import RedirectForm from "../common/RedirectForm";
|
||||||
import {MfaAuthVerifyForm, NextMfa, RequiredMfa} from "./mfa/MfaAuthVerifyForm";
|
import {MfaAuthVerifyForm, NextMfa, RequiredMfa} from "./mfa/MfaAuthVerifyForm";
|
||||||
import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
|
import {GoogleOneTapLoginVirtualButton} from "./GoogleLoginButton";
|
||||||
|
import * as ProviderButton from "./ProviderButton";
|
||||||
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
|
const FaceRecognitionModal = lazy(() => import("../common/modal/FaceRecognitionModal"));
|
||||||
|
|
||||||
class LoginPage extends React.Component {
|
class LoginPage extends React.Component {
|
||||||
@ -68,6 +68,8 @@ class LoginPage extends React.Component {
|
|||||||
this.state.applicationName = props.match?.params?.casApplicationName;
|
this.state.applicationName = props.match?.params?.casApplicationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
localStorage.setItem("signinUrl", window.location.href);
|
||||||
|
|
||||||
this.form = React.createRef();
|
this.form = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +302,12 @@ class LoginPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resp.data2) {
|
||||||
|
sessionStorage.setItem("signinUrl", window.location.href);
|
||||||
|
Setting.goToLinkSoft(ths, `/forget/${application.name}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Setting.hasPromptPage(application)) {
|
if (Setting.hasPromptPage(application)) {
|
||||||
AuthBackend.getAccount()
|
AuthBackend.getAccount()
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@ -442,15 +450,27 @@ class LoginPage extends React.Component {
|
|||||||
const responseType = values["type"];
|
const responseType = values["type"];
|
||||||
|
|
||||||
if (responseType === "login") {
|
if (responseType === "login") {
|
||||||
|
if (res.data2) {
|
||||||
|
sessionStorage.setItem("signinUrl", window.location.href);
|
||||||
|
Setting.goToLink(this, `/forget/${this.state.applicationName}`);
|
||||||
|
}
|
||||||
Setting.showMessage("success", i18next.t("application:Logged in successfully"));
|
Setting.showMessage("success", i18next.t("application:Logged in successfully"));
|
||||||
this.props.onLoginSuccess();
|
this.props.onLoginSuccess();
|
||||||
} else if (responseType === "code") {
|
} else if (responseType === "code") {
|
||||||
this.postCodeLoginAction(res);
|
this.postCodeLoginAction(res);
|
||||||
} else if (responseType === "token" || responseType === "id_token") {
|
} else if (responseType === "token" || responseType === "id_token") {
|
||||||
|
if (res.data2) {
|
||||||
|
sessionStorage.setItem("signinUrl", window.location.href);
|
||||||
|
Setting.goToLink(this, `/forget/${this.state.applicationName}`);
|
||||||
|
}
|
||||||
const amendatoryResponseType = responseType === "token" ? "access_token" : responseType;
|
const amendatoryResponseType = responseType === "token" ? "access_token" : responseType;
|
||||||
const accessToken = res.data;
|
const accessToken = res.data;
|
||||||
Setting.goToLink(`${oAuthParams.redirectUri}#${amendatoryResponseType}=${accessToken}&state=${oAuthParams.state}&token_type=bearer`);
|
Setting.goToLink(`${oAuthParams.redirectUri}#${amendatoryResponseType}=${accessToken}&state=${oAuthParams.state}&token_type=bearer`);
|
||||||
} else if (responseType === "saml") {
|
} else if (responseType === "saml") {
|
||||||
|
if (res.data2.needUpdatePassword) {
|
||||||
|
sessionStorage.setItem("signinUrl", window.location.href);
|
||||||
|
Setting.goToLink(this, `/forget/${this.state.applicationName}`);
|
||||||
|
}
|
||||||
if (res.data2.method === "POST") {
|
if (res.data2.method === "POST") {
|
||||||
this.setState({
|
this.setState({
|
||||||
samlResponse: res.data,
|
samlResponse: res.data,
|
||||||
@ -532,7 +552,7 @@ class LoginPage extends React.Component {
|
|||||||
if (signinItem.name === "Logo") {
|
if (signinItem.name === "Logo") {
|
||||||
return (
|
return (
|
||||||
<div className="login-logo-box">
|
<div className="login-logo-box">
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
{
|
{
|
||||||
Setting.renderHelmet(application)
|
Setting.renderHelmet(application)
|
||||||
}
|
}
|
||||||
@ -544,7 +564,7 @@ class LoginPage extends React.Component {
|
|||||||
} else if (signinItem.name === "Back button") {
|
} else if (signinItem.name === "Back button") {
|
||||||
return (
|
return (
|
||||||
<div className="back-button">
|
<div className="back-button">
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
{
|
{
|
||||||
this.renderBackButton()
|
this.renderBackButton()
|
||||||
}
|
}
|
||||||
@ -562,14 +582,14 @@ class LoginPage extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="login-languages">
|
<div className="login-languages">
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
<LanguageSelect languages={application.organizationObj.languages} />
|
<LanguageSelect languages={application.organizationObj.languages} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (signinItem.name === "Signin methods") {
|
} else if (signinItem.name === "Signin methods") {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
{this.renderMethodChoiceBox()}
|
{this.renderMethodChoiceBox()}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -577,10 +597,11 @@ class LoginPage extends React.Component {
|
|||||||
} else if (signinItem.name === "Username") {
|
} else if (signinItem.name === "Username") {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="username"
|
name="username"
|
||||||
className="login-username"
|
className="login-username"
|
||||||
|
label={signinItem.label ? signinItem.label : null}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
@ -653,14 +674,14 @@ class LoginPage extends React.Component {
|
|||||||
} else if (signinItem.name === "Password") {
|
} else if (signinItem.name === "Password") {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
{this.renderPasswordOrCodeInput()}
|
{this.renderPasswordOrCodeInput(signinItem)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (signinItem.name === "Forgot password?") {
|
} else if (signinItem.name === "Forgot password?") {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
<div className="login-forget-password">
|
<div className="login-forget-password">
|
||||||
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
|
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
|
||||||
<Checkbox style={{float: "left"}}>
|
<Checkbox style={{float: "left"}}>
|
||||||
@ -668,7 +689,7 @@ class LoginPage extends React.Component {
|
|||||||
</Checkbox>
|
</Checkbox>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{
|
{
|
||||||
signinItem.visible ? Setting.renderForgetLink(application, i18next.t("login:Forgot password?")) : null
|
signinItem.visible ? Setting.renderForgetLink(application, signinItem.label ? signinItem.label : i18next.t("login:Forgot password?")) : null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -678,7 +699,7 @@ class LoginPage extends React.Component {
|
|||||||
} else if (signinItem.name === "Login button") {
|
} else if (signinItem.name === "Login button") {
|
||||||
return (
|
return (
|
||||||
<Form.Item className="login-button-box">
|
<Form.Item className="login-button-box">
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
@ -687,7 +708,7 @@ class LoginPage extends React.Component {
|
|||||||
{
|
{
|
||||||
this.state.loginMethod === "webAuthn" ? i18next.t("login:Sign in with WebAuthn") :
|
this.state.loginMethod === "webAuthn" ? i18next.t("login:Sign in with WebAuthn") :
|
||||||
this.state.loginMethod === "faceId" ? i18next.t("login:Sign in with Face ID") :
|
this.state.loginMethod === "faceId" ? i18next.t("login:Sign in with Face ID") :
|
||||||
i18next.t("login:Sign In")
|
signinItem.label ? signinItem.label : i18next.t("login:Sign In")
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
{
|
{
|
||||||
@ -722,11 +743,24 @@ class LoginPage extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
{
|
{
|
||||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map((providerItem, id) => {
|
||||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, null, null, signinItem.rule, this.props.location);
|
return (
|
||||||
|
<span key ={id} onClick={(e) => {
|
||||||
|
const agreementChecked = this.form.current.getFieldValue("agreement");
|
||||||
|
|
||||||
|
if (agreementChecked !== undefined && typeof agreementChecked === "boolean" && !agreementChecked) {
|
||||||
|
e.preventDefault();
|
||||||
|
message.error(i18next.t("signup:Please accept the agreement!"));
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
ProviderButton.renderProviderLogo(providerItem.provider, application, null, null, signinItem.rule, this.props.location)
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -737,13 +771,13 @@ class LoginPage extends React.Component {
|
|||||||
);
|
);
|
||||||
} else if (signinItem.name.startsWith("Text ") || signinItem?.isCustom) {
|
} else if (signinItem.name.startsWith("Text ") || signinItem?.isCustom) {
|
||||||
return (
|
return (
|
||||||
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
|
<div dangerouslySetInnerHTML={{__html: signinItem.customCss}} />
|
||||||
);
|
);
|
||||||
} else if (signinItem.name === "Signup link") {
|
} else if (signinItem.name === "Signup link") {
|
||||||
return (
|
return (
|
||||||
<div style={{width: "100%"}} className="login-signup-link">
|
<div style={{width: "100%"}} className="login-signup-link">
|
||||||
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.label?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
|
||||||
{this.renderFooter(application)}
|
{this.renderFooter(application, signinItem)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -896,17 +930,20 @@ class LoginPage extends React.Component {
|
|||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFooter(application) {
|
renderFooter(application, signinItem) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
!application.enableSignUp ? null : (
|
!application.enableSignUp ? null : (
|
||||||
<React.Fragment>
|
signinItem.label ? Setting.renderSignupLink(application, signinItem.label) :
|
||||||
{i18next.t("login:No account?")}
|
(
|
||||||
{
|
<React.Fragment>
|
||||||
Setting.renderSignupLink(application, i18next.t("login:sign up now"))
|
{i18next.t("login:No account?")}
|
||||||
}
|
{
|
||||||
</React.Fragment>
|
Setting.renderSignupLink(application, i18next.t("login:sign up now"))
|
||||||
|
}
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -1022,7 +1059,7 @@ class LoginPage extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPasswordOrCodeInput() {
|
renderPasswordOrCodeInput(signinItem) {
|
||||||
const application = this.getApplicationObj();
|
const application = this.getApplicationObj();
|
||||||
if (this.state.loginMethod === "password" || this.state.loginMethod === "ldap") {
|
if (this.state.loginMethod === "password" || this.state.loginMethod === "ldap") {
|
||||||
return (
|
return (
|
||||||
@ -1031,6 +1068,7 @@ class LoginPage extends React.Component {
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name="password"
|
name="password"
|
||||||
className="login-password"
|
className="login-password"
|
||||||
|
label={signinItem.label ? signinItem.label : null}
|
||||||
rules={[{required: true, message: i18next.t("login:Please input your password!")}]}
|
rules={[{required: true, message: i18next.t("login:Please input your password!")}]}
|
||||||
>
|
>
|
||||||
<Input.Password
|
<Input.Password
|
||||||
|
@ -61,9 +61,9 @@ const authInfo = {
|
|||||||
},
|
},
|
||||||
WeCom: {
|
WeCom: {
|
||||||
scope: "snsapi_userinfo",
|
scope: "snsapi_userinfo",
|
||||||
endpoint: "https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect",
|
endpoint: "https://login.work.weixin.qq.com/wwlogin/sso/login",
|
||||||
silentEndpoint: "https://open.weixin.qq.com/connect/oauth2/authorize",
|
silentEndpoint: "https://open.weixin.qq.com/connect/oauth2/authorize",
|
||||||
internalEndpoint: "https://open.work.weixin.qq.com/wwopen/sso/qrConnect",
|
internalEndpoint: "https://login.work.weixin.qq.com/wwlogin/sso/login",
|
||||||
},
|
},
|
||||||
Lark: {
|
Lark: {
|
||||||
// scope: "email",
|
// scope: "email",
|
||||||
@ -384,8 +384,7 @@ export function getAuthUrl(application, provider, method, code) {
|
|||||||
|
|
||||||
let endpoint = authInfo[provider.type].endpoint;
|
let endpoint = authInfo[provider.type].endpoint;
|
||||||
let redirectUri = `${window.location.origin}/callback`;
|
let redirectUri = `${window.location.origin}/callback`;
|
||||||
const scope = authInfo[provider.type].scope;
|
let scope = authInfo[provider.type].scope;
|
||||||
|
|
||||||
const isShortState = (provider.type === "WeChat" && navigator.userAgent.includes("MicroMessenger")) || (provider.type === "Twitter");
|
const isShortState = (provider.type === "WeChat" && navigator.userAgent.includes("MicroMessenger")) || (provider.type === "Twitter");
|
||||||
const state = Util.getStateFromQueryParams(application.name, provider.name, method, isShortState);
|
const state = Util.getStateFromQueryParams(application.name, provider.name, method, isShortState);
|
||||||
const codeChallenge = "P3S-a7dr8bgM4bF6vOyiKkKETDl16rcAzao9F8UIL1Y"; // SHA256(Base64-URL-encode("casdoor-verifier"))
|
const codeChallenge = "P3S-a7dr8bgM4bF6vOyiKkKETDl16rcAzao9F8UIL1Y"; // SHA256(Base64-URL-encode("casdoor-verifier"))
|
||||||
@ -396,9 +395,11 @@ export function getAuthUrl(application, provider, method, code) {
|
|||||||
}
|
}
|
||||||
} else if (provider.type === "Apple") {
|
} else if (provider.type === "Apple") {
|
||||||
redirectUri = `${window.location.origin}/api/callback`;
|
redirectUri = `${window.location.origin}/api/callback`;
|
||||||
|
} else if (provider.type === "Google" && provider.disableSsl) {
|
||||||
|
scope += "+https://www.googleapis.com/auth/user.phonenumbers.read";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (provider.type === "Google" || provider.type === "GitHub" || provider.type === "QQ" || provider.type === "Facebook"
|
if (provider.type === "Google" || provider.type === "GitHub" || provider.type === "Facebook"
|
||||||
|| provider.type === "Weibo" || provider.type === "Gitee" || provider.type === "LinkedIn" || provider.type === "GitLab" || provider.type === "AzureAD"
|
|| provider.type === "Weibo" || provider.type === "Gitee" || provider.type === "LinkedIn" || provider.type === "GitLab" || provider.type === "AzureAD"
|
||||||
|| provider.type === "Slack" || provider.type === "Line" || provider.type === "Amazon" || provider.type === "Auth0" || provider.type === "BattleNet"
|
|| provider.type === "Slack" || provider.type === "Line" || provider.type === "Amazon" || provider.type === "Auth0" || provider.type === "BattleNet"
|
||||||
|| provider.type === "Bitbucket" || provider.type === "Box" || provider.type === "CloudFoundry" || provider.type === "Dailymotion"
|
|| provider.type === "Bitbucket" || provider.type === "Box" || provider.type === "CloudFoundry" || provider.type === "Dailymotion"
|
||||||
@ -410,6 +411,8 @@ export function getAuthUrl(application, provider, method, code) {
|
|||||||
|| provider.type === "Twitch" || provider.type === "Typetalk" || provider.type === "Uber" || provider.type === "VK" || provider.type === "Wepay"
|
|| provider.type === "Twitch" || provider.type === "Typetalk" || provider.type === "Uber" || provider.type === "VK" || provider.type === "Wepay"
|
||||||
|| provider.type === "Xero" || provider.type === "Yahoo" || provider.type === "Yammer" || provider.type === "Yandex" || provider.type === "Zoom") {
|
|| provider.type === "Xero" || provider.type === "Yahoo" || provider.type === "Yammer" || provider.type === "Yandex" || provider.type === "Zoom") {
|
||||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&state=${state}`;
|
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&state=${state}`;
|
||||||
|
} else if (provider.type === "QQ") {
|
||||||
|
return `${endpoint}?response_type=code&client_id=${provider.clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&state=${encodeURIComponent(state)}&scope=${encodeURIComponent(scope)}`;
|
||||||
} else if (provider.type === "AzureADB2C") {
|
} else if (provider.type === "AzureADB2C") {
|
||||||
return `https://${provider.domain}.b2clogin.com/${provider.domain}.onmicrosoft.com/${provider.appId}/oauth2/v2.0/authorize?client_id=${provider.clientId}&nonce=defaultNonce&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&response_type=code&state=${state}&prompt=login`;
|
return `https://${provider.domain}.b2clogin.com/${provider.domain}.onmicrosoft.com/${provider.appId}/oauth2/v2.0/authorize?client_id=${provider.clientId}&nonce=defaultNonce&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&response_type=code&state=${state}&prompt=login`;
|
||||||
} else if (provider.type === "DingTalk") {
|
} else if (provider.type === "DingTalk") {
|
||||||
@ -430,7 +433,7 @@ export function getAuthUrl(application, provider, method, code) {
|
|||||||
return `${endpoint}?appid=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&scope=${scope}&response_type=code#wechat_redirect`;
|
return `${endpoint}?appid=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&scope=${scope}&response_type=code#wechat_redirect`;
|
||||||
} else if (provider.method === "Normal") {
|
} else if (provider.method === "Normal") {
|
||||||
endpoint = authInfo[provider.type].internalEndpoint;
|
endpoint = authInfo[provider.type].internalEndpoint;
|
||||||
return `${endpoint}?appid=${provider.clientId}&agentid=${provider.appId}&redirect_uri=${redirectUri}&state=${state}&usertype=member`;
|
return `${endpoint}?login_type=CorpApp&appid=${provider.clientId}&agentid=${provider.appId}&redirect_uri=${redirectUri}&state=${state}`;
|
||||||
} else {
|
} else {
|
||||||
return `https://error:not-supported-provider-method:${provider.method}`;
|
return `https://error:not-supported-provider-method:${provider.method}`;
|
||||||
}
|
}
|
||||||
@ -439,7 +442,8 @@ export function getAuthUrl(application, provider, method, code) {
|
|||||||
endpoint = authInfo[provider.type].silentEndpoint;
|
endpoint = authInfo[provider.type].silentEndpoint;
|
||||||
return `${endpoint}?appid=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&scope=${scope}&response_type=code#wechat_redirect`;
|
return `${endpoint}?appid=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&scope=${scope}&response_type=code#wechat_redirect`;
|
||||||
} else if (provider.method === "Normal") {
|
} else if (provider.method === "Normal") {
|
||||||
return `${endpoint}?appid=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&usertype=member`;
|
endpoint = authInfo[provider.type].endpoint;
|
||||||
|
return `${endpoint}?login_type=ServiceApp&appid=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}`;
|
||||||
} else {
|
} else {
|
||||||
return `https://error:not-supported-provider-method:${provider.method}`;
|
return `https://error:not-supported-provider-method:${provider.method}`;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Form, Input, Radio, Result, Row} from "antd";
|
import {Button, Form, Input, Radio, Result, Row, message} from "antd";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import * as AuthBackend from "./AuthBackend";
|
import * as AuthBackend from "./AuthBackend";
|
||||||
import * as ProviderButton from "./ProviderButton";
|
import * as ProviderButton from "./ProviderButton";
|
||||||
@ -389,6 +389,14 @@ class SignupPage extends React.Component {
|
|||||||
return Promise.reject(i18next.t("signup:The input is not valid Email!"));
|
return Promise.reject(i18next.t("signup:The input is not valid Email!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (signupItem.regex) {
|
||||||
|
const reg = new RegExp(signupItem.regex);
|
||||||
|
if (!reg.test(this.state.email)) {
|
||||||
|
this.setState({validEmail: false});
|
||||||
|
return Promise.reject(i18next.t("signup:The input Email doesn't match the signup item regex!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({validEmail: true});
|
this.setState({validEmail: true});
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
},
|
},
|
||||||
@ -645,8 +653,21 @@ class SignupPage extends React.Component {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
||||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map((providerItem, id) => {
|
||||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, null, null, signupItem.rule, this.props.location);
|
return (
|
||||||
|
<span key={id} onClick={(e) => {
|
||||||
|
const agreementChecked = this.form.current.getFieldValue("agreement");
|
||||||
|
|
||||||
|
if (agreementChecked !== undefined && typeof agreementChecked === "boolean" && !agreementChecked) {
|
||||||
|
e.preventDefault();
|
||||||
|
message.error(i18next.t("signup:Please accept the agreement!"));
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
{
|
||||||
|
ProviderButton.renderProviderLogo(providerItem.provider, application, null, null, signupItem.rule, this.props.location)
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
})
|
})
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -70,8 +70,8 @@ export function deleteProduct(product) {
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buyProduct(owner, name, providerName, pricingName = "", planName = "", userName = "", paymentEnv = "") {
|
export function buyProduct(owner, name, providerName, pricingName = "", planName = "", userName = "", paymentEnv = "", customPrice = 0) {
|
||||||
return fetch(`${Setting.ServerUrl}/api/buy-product?id=${owner}/${encodeURIComponent(name)}&providerName=${providerName}&pricingName=${pricingName}&planName=${planName}&userName=${userName}&paymentEnv=${paymentEnv}`, {
|
return fetch(`${Setting.ServerUrl}/api/buy-product?id=${owner}/${encodeURIComponent(name)}&providerName=${providerName}&pricingName=${pricingName}&planName=${planName}&userName=${userName}&paymentEnv=${paymentEnv}&customPrice=${customPrice}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -50,6 +50,7 @@ function testEmailProvider(provider, email = "") {
|
|||||||
sender: provider.displayName,
|
sender: provider.displayName,
|
||||||
receivers: email === "" ? ["TestSmtpServer"] : [email],
|
receivers: email === "" ? ["TestSmtpServer"] : [email],
|
||||||
provider: provider.name,
|
provider: provider.name,
|
||||||
|
providerObject: provider,
|
||||||
};
|
};
|
||||||
|
|
||||||
return fetch(`${Setting.ServerUrl}/api/send-email`, {
|
return fetch(`${Setting.ServerUrl}/api/send-email`, {
|
||||||
|
@ -125,6 +125,14 @@ function initLanguage() {
|
|||||||
case "fa":
|
case "fa":
|
||||||
language = "fa";
|
language = "fa";
|
||||||
break;
|
break;
|
||||||
|
case "cs":
|
||||||
|
case "cs-CZ":
|
||||||
|
language = "cs";
|
||||||
|
break;
|
||||||
|
case "sk":
|
||||||
|
case "sk-SK":
|
||||||
|
language = "sk";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
language = Conf.DefaultLanguage;
|
language = Conf.DefaultLanguage;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
1209
web/src/locales/cs/data.json
Normal file
1209
web/src/locales/cs/data.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Nächster Schritt",
|
"Next Step": "Nächster Schritt",
|
||||||
"Please input your username!": "Bitte gib deinen Benutzernamen ein!",
|
"Please input your username!": "Bitte gib deinen Benutzernamen ein!",
|
||||||
"Reset": "Zurücksetzen",
|
"Reset": "Zurücksetzen",
|
||||||
"Retrieve password": "Passwort abrufen",
|
"Reset password": "Passwort abrufen",
|
||||||
"Unknown forget type": "Unbekannter Vergesslichkeitstyp",
|
"Unknown forget type": "Unbekannter Vergesslichkeitstyp",
|
||||||
"Verify": "überprüfen"
|
"Verify": "überprüfen"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Wenn aktiviert, werden gelöschte Benutzer nicht vollständig aus der Datenbank entfernt. Stattdessen werden sie als gelöscht markiert",
|
"Soft deletion - Tooltip": "Wenn aktiviert, werden gelöschte Benutzer nicht vollständig aus der Datenbank entfernt. Stattdessen werden sie als gelöscht markiert",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Sammlung von Tags, die für Benutzer zur Auswahl zur Verfügung stehen",
|
"Tags - Tooltip": "Sammlung von Tags, die für Benutzer zur Auswahl zur Verfügung stehen",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "Ansichtsregel",
|
"View rule": "Ansichtsregel",
|
||||||
"Visible": "Sichtbar",
|
"Visible": "Sichtbar",
|
||||||
"Website URL": "Website-URL",
|
"Website URL": "Website-URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "In Bearbeitung...",
|
"Processing...": "In Bearbeitung...",
|
||||||
"Product": "Produkt",
|
"Product": "Produkt",
|
||||||
"Product - Tooltip": "Produktname",
|
"Product - Tooltip": "Produktname",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Ergebnis",
|
"Result": "Ergebnis",
|
||||||
"Return to Website": "Zurück zur Website",
|
"Return to Website": "Zurück zur Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "Die Zahlung wird immer noch bearbeitet",
|
"The payment is still under processing": "Die Zahlung wird immer noch bearbeitet",
|
||||||
"Type - Tooltip": "Zahlungsmethode, die beim Kauf des Produkts verwendet wurde",
|
"Type - Tooltip": "Zahlungsmethode, die beim Kauf des Produkts verwendet wurde",
|
||||||
"You have successfully completed the payment": "Sie haben die Zahlung erfolgreich abgeschlossen",
|
"You have successfully completed the payment": "Sie haben die Zahlung erfolgreich abgeschlossen",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "Bitte warten Sie ein paar Sekunden...",
|
"please wait for a few seconds...": "Bitte warten Sie ein paar Sekunden...",
|
||||||
"the current state is": "der aktuelle Zustand ist"
|
"the current state is": "der aktuelle Zustand ist"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Produkt bearbeiten",
|
"Edit Product": "Produkt bearbeiten",
|
||||||
"Image": "Bild",
|
"Image": "Bild",
|
||||||
"Image - Tooltip": "Bild des Produkts",
|
"Image - Tooltip": "Bild des Produkts",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Neues Produkt",
|
"New Product": "Neues Produkt",
|
||||||
"Pay": "Zahlen",
|
"Pay": "Zahlen",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "From address - Tooltip",
|
"From address - Tooltip": "From address - Tooltip",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "From name - Tooltip",
|
"From name - Tooltip": "From name - Tooltip",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name des Hosts",
|
"Host - Tooltip": "Name des Hosts",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Kopiere den Link",
|
"Copy Link": "Kopiere den Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "Die Eingabe ist keine Rechnungssteuer-ID!",
|
"The input is not invoice Tax ID!": "Die Eingabe ist keine Rechnungssteuer-ID!",
|
||||||
"The input is not invoice title!": "Der Eingabewert ist nicht die Rechnungsbezeichnung!",
|
"The input is not invoice title!": "Der Eingabewert ist nicht die Rechnungsbezeichnung!",
|
||||||
"The input is not valid Email!": "Die Eingabe ist keine gültige E-Mail-Adresse!",
|
"The input is not valid Email!": "Die Eingabe ist keine gültige E-Mail-Adresse!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Drittanbieter-Anmeldungen, die mit dem Benutzer verknüpft sind",
|
"3rd-party logins - Tooltip": "Drittanbieter-Anmeldungen, die mit dem Benutzer verknüpft sind",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Address - Tooltip": "Wohnadresse",
|
"Address - Tooltip": "Wohnadresse",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Zugehörigkeit",
|
"Affiliation": "Zugehörigkeit",
|
||||||
"Affiliation - Tooltip": "Arbeitgeber, wie Firmenname oder Organisationsname",
|
"Affiliation - Tooltip": "Arbeitgeber, wie Firmenname oder Organisationsname",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Selbstvorstellung des Nutzers",
|
"Bio - Tooltip": "Selbstvorstellung des Nutzers",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Verwaltete Konten",
|
"Managed accounts": "Verwaltete Konten",
|
||||||
"Modify password...": "Passwort ändern...",
|
"Modify password...": "Passwort ändern...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Neue E-Mail",
|
"New Email": "Neue E-Mail",
|
||||||
"New Password": "Neues Passwort",
|
"New Password": "Neues Passwort",
|
||||||
"New User": "Neuer Benutzer",
|
"New User": "Neuer Benutzer",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "Eingabe des Passworts"
|
"input password": "Eingabe des Passworts"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Siguiente paso",
|
"Next Step": "Siguiente paso",
|
||||||
"Please input your username!": "¡Por favor, ingrese su nombre de usuario!",
|
"Please input your username!": "¡Por favor, ingrese su nombre de usuario!",
|
||||||
"Reset": "Restablecer",
|
"Reset": "Restablecer",
|
||||||
"Retrieve password": "Recuperar contraseña",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Tipo de olvido desconocido",
|
"Unknown forget type": "Tipo de olvido desconocido",
|
||||||
"Verify": "Verificar"
|
"Verify": "Verificar"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Cuando se habilita, la eliminación de usuarios no los eliminará por completo de la base de datos. En su lugar, se marcarán como eliminados",
|
"Soft deletion - Tooltip": "Cuando se habilita, la eliminación de usuarios no los eliminará por completo de la base de datos. En su lugar, se marcarán como eliminados",
|
||||||
"Tags": "Etiquetas",
|
"Tags": "Etiquetas",
|
||||||
"Tags - Tooltip": "Colección de etiquetas disponibles para que los usuarios elijan",
|
"Tags - Tooltip": "Colección de etiquetas disponibles para que los usuarios elijan",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "Regla de visualización",
|
"View rule": "Regla de visualización",
|
||||||
"Visible": "Visible - Visible",
|
"Visible": "Visible - Visible",
|
||||||
"Website URL": "URL del sitio web",
|
"Website URL": "URL del sitio web",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Procesando...",
|
"Processing...": "Procesando...",
|
||||||
"Product": "Producto",
|
"Product": "Producto",
|
||||||
"Product - Tooltip": "Nombre del producto",
|
"Product - Tooltip": "Nombre del producto",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Resultado",
|
"Result": "Resultado",
|
||||||
"Return to Website": "Regresar al sitio web",
|
"Return to Website": "Regresar al sitio web",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "El pago aún está en proceso",
|
"The payment is still under processing": "El pago aún está en proceso",
|
||||||
"Type - Tooltip": "Método de pago utilizado al comprar el producto",
|
"Type - Tooltip": "Método de pago utilizado al comprar el producto",
|
||||||
"You have successfully completed the payment": "Has completado el pago exitosamente",
|
"You have successfully completed the payment": "Has completado el pago exitosamente",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "Por favor espera unos segundos...",
|
"please wait for a few seconds...": "Por favor espera unos segundos...",
|
||||||
"the current state is": "el estado actual es"
|
"the current state is": "el estado actual es"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Editar Producto",
|
"Edit Product": "Editar Producto",
|
||||||
"Image": "Imagen",
|
"Image": "Imagen",
|
||||||
"Image - Tooltip": "Imagen del producto",
|
"Image - Tooltip": "Imagen del producto",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Nuevo producto",
|
"New Product": "Nuevo producto",
|
||||||
"Pay": "Pagar",
|
"Pay": "Pagar",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "From address - Tooltip",
|
"From address - Tooltip": "From address - Tooltip",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "From name - Tooltip",
|
"From name - Tooltip": "From name - Tooltip",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Anfitrión",
|
"Host": "Anfitrión",
|
||||||
"Host - Tooltip": "Nombre del anfitrión",
|
"Host - Tooltip": "Nombre del anfitrión",
|
||||||
"IdP": "IdP = Proveedor de Identidad",
|
"IdP": "IdP = Proveedor de Identidad",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copiar enlace",
|
"Copy Link": "Copiar enlace",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "¡La entrada no es el ID fiscal de la factura!",
|
"The input is not invoice Tax ID!": "¡La entrada no es el ID fiscal de la factura!",
|
||||||
"The input is not invoice title!": "¡El entrada no es el título de la factura!",
|
"The input is not invoice title!": "¡El entrada no es el título de la factura!",
|
||||||
"The input is not valid Email!": "¡La entrada no es un correo electrónico válido!",
|
"The input is not valid Email!": "¡La entrada no es un correo electrónico válido!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Accesos sociales ligados por el usuario",
|
"3rd-party logins - Tooltip": "Accesos sociales ligados por el usuario",
|
||||||
"Address": "Dirección",
|
"Address": "Dirección",
|
||||||
"Address - Tooltip": "Dirección residencial",
|
"Address - Tooltip": "Dirección residencial",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Afiliación",
|
"Affiliation": "Afiliación",
|
||||||
"Affiliation - Tooltip": "Empleador, como el nombre de una empresa u organización",
|
"Affiliation - Tooltip": "Empleador, como el nombre de una empresa u organización",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio - Biografía",
|
"Bio": "Bio - Biografía",
|
||||||
"Bio - Tooltip": "Introducción personal del usuario",
|
"Bio - Tooltip": "Introducción personal del usuario",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Cuentas gestionadas",
|
"Managed accounts": "Cuentas gestionadas",
|
||||||
"Modify password...": "Modificar contraseña...",
|
"Modify password...": "Modificar contraseña...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Nuevo correo electrónico",
|
"New Email": "Nuevo correo electrónico",
|
||||||
"New Password": "Nueva contraseña",
|
"New Password": "Nueva contraseña",
|
||||||
"New User": "Nuevo Usuario",
|
"New User": "Nuevo Usuario",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "Ingresar contraseña"
|
"input password": "Ingresar contraseña"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Étape suivante",
|
"Next Step": "Étape suivante",
|
||||||
"Please input your username!": "Veuillez saisir votre identifiant !",
|
"Please input your username!": "Veuillez saisir votre identifiant !",
|
||||||
"Reset": "Réinitialiser",
|
"Reset": "Réinitialiser",
|
||||||
"Retrieve password": "Récupérer le mot de passe",
|
"Reset password": "Récupérer le mot de passe",
|
||||||
"Unknown forget type": "Type d'oubli inconnu",
|
"Unknown forget type": "Type d'oubli inconnu",
|
||||||
"Verify": "Vérifier"
|
"Verify": "Vérifier"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Lorsque c'est activée, la suppression de compte ne les retirera pas complètement de la base de données. Au lieu de cela, ils seront marqués comme supprimés",
|
"Soft deletion - Tooltip": "Lorsque c'est activée, la suppression de compte ne les retirera pas complètement de la base de données. Au lieu de cela, ils seront marqués comme supprimés",
|
||||||
"Tags": "Étiquettes",
|
"Tags": "Étiquettes",
|
||||||
"Tags - Tooltip": "Collection d'étiquettes disponibles pour les comptes",
|
"Tags - Tooltip": "Collection d'étiquettes disponibles pour les comptes",
|
||||||
|
"Use Email as username": "Utiliser l'e-mail comme identifiant",
|
||||||
|
"Use Email as username - Tooltip": "Utiliser l'adresse e-mail comme identifiant pour les comptes lorsque l'identifiant ne fait pas partie des champs d'inscription",
|
||||||
"View rule": "Règle de visibilité",
|
"View rule": "Règle de visibilité",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "URL du site web",
|
"Website URL": "URL du site web",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Traitement...",
|
"Processing...": "Traitement...",
|
||||||
"Product": "Produit",
|
"Product": "Produit",
|
||||||
"Product - Tooltip": "Nom du produit",
|
"Product - Tooltip": "Nom du produit",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Résultat",
|
"Result": "Résultat",
|
||||||
"Return to Website": "Retourner sur le site web",
|
"Return to Website": "Retourner sur le site web",
|
||||||
"The payment has been canceled": "Le paiement a été annulé",
|
"The payment has been canceled": "Le paiement a été annulé",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "Le paiement est encore en cours de traitement",
|
"The payment is still under processing": "Le paiement est encore en cours de traitement",
|
||||||
"Type - Tooltip": "Méthode de paiement utilisée lors de l'achat du produit",
|
"Type - Tooltip": "Méthode de paiement utilisée lors de l'achat du produit",
|
||||||
"You have successfully completed the payment": "Vous avez effectué le paiement avec succès",
|
"You have successfully completed the payment": "Vous avez effectué le paiement avec succès",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "Veuillez patienter quelques secondes...",
|
"please wait for a few seconds...": "Veuillez patienter quelques secondes...",
|
||||||
"the current state is": "l'état actuel est"
|
"the current state is": "l'état actuel est"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Modifier le produit",
|
"Edit Product": "Modifier le produit",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image du produit",
|
"Image - Tooltip": "Image du produit",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Nouveau produit",
|
"New Product": "Nouveau produit",
|
||||||
"Pay": "Payer",
|
"Pay": "Payer",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "L'adresse e-mail affichée comme expéditeur dans les e-mails envoyés",
|
"From address - Tooltip": "L'adresse e-mail affichée comme expéditeur dans les e-mails envoyés",
|
||||||
"From name": "Nom de l'expéditeur",
|
"From name": "Nom de l'expéditeur",
|
||||||
"From name - Tooltip": "Le nom affiché comme expéditeur dans les e-mails envoyés",
|
"From name - Tooltip": "Le nom affiché comme expéditeur dans les e-mails envoyés",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Hôte",
|
"Host": "Hôte",
|
||||||
"Host - Tooltip": "Nom d'hôte",
|
"Host - Tooltip": "Nom d'hôte",
|
||||||
"IdP": "IdP (Identité Fournisseur)",
|
"IdP": "IdP (Identité Fournisseur)",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copier le lien",
|
"Copy Link": "Copier le lien",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "L'entrée n'est pas l'identifiant fiscal de la facture !",
|
"The input is not invoice Tax ID!": "L'entrée n'est pas l'identifiant fiscal de la facture !",
|
||||||
"The input is not invoice title!": "L'entrée n'est pas un nom ou une dénomination sociale !",
|
"The input is not invoice title!": "L'entrée n'est pas un nom ou une dénomination sociale !",
|
||||||
"The input is not valid Email!": "L'entrée n'est pas une adresse e-mail valide !",
|
"The input is not valid Email!": "L'entrée n'est pas une adresse e-mail valide !",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Service de connexions tiers liés au compte",
|
"3rd-party logins - Tooltip": "Service de connexions tiers liés au compte",
|
||||||
"Address": "Adresse",
|
"Address": "Adresse",
|
||||||
"Address - Tooltip": "Adresse résidentielle",
|
"Address - Tooltip": "Adresse résidentielle",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employeur, tel que le nom de l'entreprise ou de l'organisation",
|
"Affiliation - Tooltip": "Employeur, tel que le nom de l'entreprise ou de l'organisation",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Biographie du compte",
|
"Bio - Tooltip": "Biographie du compte",
|
||||||
"Birthday": "Date de naissance",
|
"Birthday": "Date de naissance",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Comptes gérés",
|
"Managed accounts": "Comptes gérés",
|
||||||
"Modify password...": "Modifier le mot de passe...",
|
"Modify password...": "Modifier le mot de passe...",
|
||||||
"Multi-factor authentication": "Authentification multifacteur",
|
"Multi-factor authentication": "Authentification multifacteur",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Nouvelle adresse e-mail",
|
"New Email": "Nouvelle adresse e-mail",
|
||||||
"New Password": "Nouveau mot de passe",
|
"New Password": "Nouveau mot de passe",
|
||||||
"New User": "Nouveau compte",
|
"New User": "Nouveau compte",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "saisir le mot de passe"
|
"input password": "saisir le mot de passe"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Langkah selanjutnya",
|
"Next Step": "Langkah selanjutnya",
|
||||||
"Please input your username!": "Silakan masukkan nama pengguna Anda!",
|
"Please input your username!": "Silakan masukkan nama pengguna Anda!",
|
||||||
"Reset": "Menyetel-ulang",
|
"Reset": "Menyetel-ulang",
|
||||||
"Retrieve password": "Mengambil password",
|
"Reset password": "Mengambil password",
|
||||||
"Unknown forget type": "Tipe yang tidak diketahui terlupakan",
|
"Unknown forget type": "Tipe yang tidak diketahui terlupakan",
|
||||||
"Verify": "Memverifikasi"
|
"Verify": "Memverifikasi"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Ketika diaktifkan, menghapus pengguna tidak akan sepenuhnya menghapus mereka dari database. Sebaliknya, mereka akan ditandai sebagai dihapus",
|
"Soft deletion - Tooltip": "Ketika diaktifkan, menghapus pengguna tidak akan sepenuhnya menghapus mereka dari database. Sebaliknya, mereka akan ditandai sebagai dihapus",
|
||||||
"Tags": "Tag-tag",
|
"Tags": "Tag-tag",
|
||||||
"Tags - Tooltip": "Kumpulan tag yang tersedia bagi pengguna untuk dipilih",
|
"Tags - Tooltip": "Kumpulan tag yang tersedia bagi pengguna untuk dipilih",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "Aturan tampilan",
|
"View rule": "Aturan tampilan",
|
||||||
"Visible": "Terlihat",
|
"Visible": "Terlihat",
|
||||||
"Website URL": "URL situs web",
|
"Website URL": "URL situs web",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Pemrosesan...",
|
"Processing...": "Pemrosesan...",
|
||||||
"Product": "Produk",
|
"Product": "Produk",
|
||||||
"Product - Tooltip": "Nama Produk",
|
"Product - Tooltip": "Nama Produk",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Hasil",
|
"Result": "Hasil",
|
||||||
"Return to Website": "Kembali ke Situs Web",
|
"Return to Website": "Kembali ke Situs Web",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "Pembayaran masih dalam proses",
|
"The payment is still under processing": "Pembayaran masih dalam proses",
|
||||||
"Type - Tooltip": "Metode pembayaran yang digunakan saat membeli produk",
|
"Type - Tooltip": "Metode pembayaran yang digunakan saat membeli produk",
|
||||||
"You have successfully completed the payment": "Anda telah berhasil menyelesaikan pembayaran",
|
"You have successfully completed the payment": "Anda telah berhasil menyelesaikan pembayaran",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "Mohon tunggu beberapa detik...",
|
"please wait for a few seconds...": "Mohon tunggu beberapa detik...",
|
||||||
"the current state is": "keadaan saat ini adalah"
|
"the current state is": "keadaan saat ini adalah"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Produk",
|
"Edit Product": "Edit Produk",
|
||||||
"Image": "Gambar",
|
"Image": "Gambar",
|
||||||
"Image - Tooltip": "Gambar produk",
|
"Image - Tooltip": "Gambar produk",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Produk Baru",
|
"New Product": "Produk Baru",
|
||||||
"Pay": "Bayar",
|
"Pay": "Bayar",
|
||||||
"PayPal": "Paypal",
|
"PayPal": "Paypal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "From address - Tooltip",
|
"From address - Tooltip": "From address - Tooltip",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "From name - Tooltip",
|
"From name - Tooltip": "From name - Tooltip",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Tuan rumah",
|
"Host": "Tuan rumah",
|
||||||
"Host - Tooltip": "Nama tuan rumah",
|
"Host - Tooltip": "Nama tuan rumah",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Salin Tautan",
|
"Copy Link": "Salin Tautan",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "Input ini bukan Tax ID faktur!",
|
"The input is not invoice Tax ID!": "Input ini bukan Tax ID faktur!",
|
||||||
"The input is not invoice title!": "Masukan bukan judul faktur!",
|
"The input is not invoice title!": "Masukan bukan judul faktur!",
|
||||||
"The input is not valid Email!": "Input yang dimasukkan bukan sesuai dengan format Email yang valid!",
|
"The input is not valid Email!": "Input yang dimasukkan bukan sesuai dengan format Email yang valid!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Masuk sosial yang terhubung oleh pengguna",
|
"3rd-party logins - Tooltip": "Masuk sosial yang terhubung oleh pengguna",
|
||||||
"Address": "Alamat",
|
"Address": "Alamat",
|
||||||
"Address - Tooltip": "Alamat tempat tinggal",
|
"Address - Tooltip": "Alamat tempat tinggal",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Afiliasi",
|
"Affiliation": "Afiliasi",
|
||||||
"Affiliation - Tooltip": "Pemberi Kerja, seperti nama perusahaan atau nama organisasi",
|
"Affiliation - Tooltip": "Pemberi Kerja, seperti nama perusahaan atau nama organisasi",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio: Biografi",
|
"Bio": "Bio: Biografi",
|
||||||
"Bio - Tooltip": "Pengenalan diri dari pengguna",
|
"Bio - Tooltip": "Pengenalan diri dari pengguna",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Akun yang dikelola",
|
"Managed accounts": "Akun yang dikelola",
|
||||||
"Modify password...": "Mengubah kata sandi...",
|
"Modify password...": "Mengubah kata sandi...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Email baru",
|
"New Email": "Email baru",
|
||||||
"New Password": "Kata Sandi Baru",
|
"New Password": "Kata Sandi Baru",
|
||||||
"New User": "Pengguna Baru",
|
"New User": "Pengguna Baru",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "masukkan kata sandi"
|
"input password": "masukkan kata sandi"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "次のステップ",
|
"Next Step": "次のステップ",
|
||||||
"Please input your username!": "ユーザー名を入力してください!",
|
"Please input your username!": "ユーザー名を入力してください!",
|
||||||
"Reset": "リセット",
|
"Reset": "リセット",
|
||||||
"Retrieve password": "パスワードの取得",
|
"Reset password": "パスワードの取得",
|
||||||
"Unknown forget type": "未知の忘却タイプ",
|
"Unknown forget type": "未知の忘却タイプ",
|
||||||
"Verify": "検証"
|
"Verify": "検証"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "有効になっている場合、ユーザーを削除しても完全にデータベースから削除されません。代わりに、削除されたとマークされます",
|
"Soft deletion - Tooltip": "有効になっている場合、ユーザーを削除しても完全にデータベースから削除されません。代わりに、削除されたとマークされます",
|
||||||
"Tags": "タグ",
|
"Tags": "タグ",
|
||||||
"Tags - Tooltip": "ユーザーが選択できるタグのコレクション",
|
"Tags - Tooltip": "ユーザーが選択できるタグのコレクション",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "ビュールール",
|
"View rule": "ビュールール",
|
||||||
"Visible": "見える",
|
"Visible": "見える",
|
||||||
"Website URL": "ウェブサイトのURL",
|
"Website URL": "ウェブサイトのURL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "処理中... ",
|
"Processing...": "処理中... ",
|
||||||
"Product": "製品",
|
"Product": "製品",
|
||||||
"Product - Tooltip": "製品名",
|
"Product - Tooltip": "製品名",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "結果",
|
"Result": "結果",
|
||||||
"Return to Website": "ウェブサイトに戻る",
|
"Return to Website": "ウェブサイトに戻る",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "支払いはまだ処理中です",
|
"The payment is still under processing": "支払いはまだ処理中です",
|
||||||
"Type - Tooltip": "製品を購入する際に使用される支払方法",
|
"Type - Tooltip": "製品を購入する際に使用される支払方法",
|
||||||
"You have successfully completed the payment": "あなたは支払いを正常に完了しました",
|
"You have successfully completed the payment": "あなたは支払いを正常に完了しました",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "数秒お待ちください...",
|
"please wait for a few seconds...": "数秒お待ちください...",
|
||||||
"the current state is": "現在の状態は"
|
"the current state is": "現在の状態は"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "製品を編集",
|
"Edit Product": "製品を編集",
|
||||||
"Image": "画像",
|
"Image": "画像",
|
||||||
"Image - Tooltip": "製品のイメージ",
|
"Image - Tooltip": "製品のイメージ",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "新製品",
|
"New Product": "新製品",
|
||||||
"Pay": "支払う",
|
"Pay": "支払う",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "From address - Tooltip",
|
"From address - Tooltip": "From address - Tooltip",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "From name - Tooltip",
|
"From name - Tooltip": "From name - Tooltip",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "ホスト",
|
"Host": "ホスト",
|
||||||
"Host - Tooltip": "ホストの名前",
|
"Host - Tooltip": "ホストの名前",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "コピー リンク",
|
"Copy Link": "コピー リンク",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"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!": "入力されたものは有効なメールではありません",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "ユーザーによってリンクされたソーシャルログイン",
|
"3rd-party logins - Tooltip": "ユーザーによってリンクされたソーシャルログイン",
|
||||||
"Address": "住所",
|
"Address": "住所",
|
||||||
"Address - Tooltip": "住所",
|
"Address - Tooltip": "住所",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "所属",
|
"Affiliation": "所属",
|
||||||
"Affiliation - Tooltip": "企業名や団体名などの雇用主",
|
"Affiliation - Tooltip": "企業名や団体名などの雇用主",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "バイオ技術",
|
"Bio": "バイオ技術",
|
||||||
"Bio - Tooltip": "ユーザーの自己紹介\n\n私は○○です。私は○○(国、都市、職業など)出身で、現在は○○(国、都市、職業など)に住んでいます。私は○○(趣味、特技、興味など)が好きで、空き時間にはよくそれをしています。よろしくお願いします",
|
"Bio - Tooltip": "ユーザーの自己紹介\n\n私は○○です。私は○○(国、都市、職業など)出身で、現在は○○(国、都市、職業など)に住んでいます。私は○○(趣味、特技、興味など)が好きで、空き時間にはよくそれをしています。よろしくお願いします",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "管理アカウント",
|
"Managed accounts": "管理アカウント",
|
||||||
"Modify password...": "パスワードを変更する...",
|
"Modify password...": "パスワードを変更する...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "新しいメール",
|
"New Email": "新しいメール",
|
||||||
"New Password": "新しいパスワード",
|
"New Password": "新しいパスワード",
|
||||||
"New User": "新しいユーザー",
|
"New User": "新しいユーザー",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "パスワードを入力してください"
|
"input password": "パスワードを入力してください"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "다음 단계",
|
"Next Step": "다음 단계",
|
||||||
"Please input your username!": "사용자 이름을 입력하세요!",
|
"Please input your username!": "사용자 이름을 입력하세요!",
|
||||||
"Reset": "리셋",
|
"Reset": "리셋",
|
||||||
"Retrieve password": "비밀번호를 복구하세요",
|
"Reset password": "비밀번호를 복구하세요",
|
||||||
"Unknown forget type": "미지의 잊혀진 유형",
|
"Unknown forget type": "미지의 잊혀진 유형",
|
||||||
"Verify": "검증하다"
|
"Verify": "검증하다"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "사용 가능한 경우, 사용자 삭제 시 데이터베이스에서 완전히 삭제되지 않습니다. 대신 삭제됨으로 표시됩니다",
|
"Soft deletion - Tooltip": "사용 가능한 경우, 사용자 삭제 시 데이터베이스에서 완전히 삭제되지 않습니다. 대신 삭제됨으로 표시됩니다",
|
||||||
"Tags": "태그",
|
"Tags": "태그",
|
||||||
"Tags - Tooltip": "사용자가 선택할 수 있는 태그 컬렉션",
|
"Tags - Tooltip": "사용자가 선택할 수 있는 태그 컬렉션",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "보기 규칙",
|
"View rule": "보기 규칙",
|
||||||
"Visible": "보이는",
|
"Visible": "보이는",
|
||||||
"Website URL": "웹사이트 URL",
|
"Website URL": "웹사이트 URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "처리 중...",
|
"Processing...": "처리 중...",
|
||||||
"Product": "제품",
|
"Product": "제품",
|
||||||
"Product - Tooltip": "제품 이름",
|
"Product - Tooltip": "제품 이름",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "결과",
|
"Result": "결과",
|
||||||
"Return to Website": "웹 사이트로 돌아가기",
|
"Return to Website": "웹 사이트로 돌아가기",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "지불은 아직 처리 중입니다",
|
"The payment is still under processing": "지불은 아직 처리 중입니다",
|
||||||
"Type - Tooltip": "제품을 구매할 때 사용되는 결제 방법",
|
"Type - Tooltip": "제품을 구매할 때 사용되는 결제 방법",
|
||||||
"You have successfully completed the payment": "당신은 결제를 성공적으로 완료하셨습니다",
|
"You have successfully completed the payment": "당신은 결제를 성공적으로 완료하셨습니다",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "잠시만 기다려주세요...",
|
"please wait for a few seconds...": "잠시만 기다려주세요...",
|
||||||
"the current state is": "현재 상태입니다"
|
"the current state is": "현재 상태입니다"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "제품 편집",
|
"Edit Product": "제품 편집",
|
||||||
"Image": "이미지",
|
"Image": "이미지",
|
||||||
"Image - Tooltip": "제품 이미지",
|
"Image - Tooltip": "제품 이미지",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "새로운 제품",
|
"New Product": "새로운 제품",
|
||||||
"Pay": "결제하다",
|
"Pay": "결제하다",
|
||||||
"PayPal": "페이팔",
|
"PayPal": "페이팔",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "From address - Tooltip",
|
"From address - Tooltip": "From address - Tooltip",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "From name - Tooltip",
|
"From name - Tooltip": "From name - Tooltip",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "호스트",
|
"Host": "호스트",
|
||||||
"Host - Tooltip": "호스트의 이름",
|
"Host - Tooltip": "호스트의 이름",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "링크 복사하기",
|
"Copy Link": "링크 복사하기",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "입력한 것은 송장 세금 ID가 아닙니다!",
|
"The input is not invoice Tax ID!": "입력한 것은 송장 세금 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!": "입력 값은 유효한 이메일이 아닙니다!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "사용자가 연결한 소셜 로그인",
|
"3rd-party logins - Tooltip": "사용자가 연결한 소셜 로그인",
|
||||||
"Address": "주소",
|
"Address": "주소",
|
||||||
"Address - Tooltip": "주거지 주소",
|
"Address - Tooltip": "주거지 주소",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "소속",
|
"Affiliation": "소속",
|
||||||
"Affiliation - Tooltip": "고용주, 회사명 또는 조직명",
|
"Affiliation - Tooltip": "고용주, 회사명 또는 조직명",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "바이오",
|
"Bio": "바이오",
|
||||||
"Bio - Tooltip": "사용자의 자기소개\n\n안녕하세요, 저는 [이름]입니다. 한국을 포함한 여러 나라에서 살아본 적이 있습니다. 저는 [직업/전공]을 공부하고 있으며 [취미/관심사]에 대해 깊게 알고 있습니다. 이 채팅 서비스를 사용하여 새로운 사람들과 함께 대화를 나누기를 원합니다. 감사합니다",
|
"Bio - Tooltip": "사용자의 자기소개\n\n안녕하세요, 저는 [이름]입니다. 한국을 포함한 여러 나라에서 살아본 적이 있습니다. 저는 [직업/전공]을 공부하고 있으며 [취미/관심사]에 대해 깊게 알고 있습니다. 이 채팅 서비스를 사용하여 새로운 사람들과 함께 대화를 나누기를 원합니다. 감사합니다",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "관리 계정",
|
"Managed accounts": "관리 계정",
|
||||||
"Modify password...": "비밀번호 수정하기...",
|
"Modify password...": "비밀번호 수정하기...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "새 이메일",
|
"New Email": "새 이메일",
|
||||||
"New Password": "새로운 비밀번호",
|
"New Password": "새로운 비밀번호",
|
||||||
"New User": "새로운 사용자",
|
"New User": "새로운 사용자",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "비밀번호를 입력해주세요"
|
"input password": "비밀번호를 입력해주세요"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Próxima Etapa",
|
"Next Step": "Próxima Etapa",
|
||||||
"Please input your username!": "Por favor, insira seu nome de usuário!",
|
"Please input your username!": "Por favor, insira seu nome de usuário!",
|
||||||
"Reset": "Redefinir",
|
"Reset": "Redefinir",
|
||||||
"Retrieve password": "Recuperar senha",
|
"Reset password": "Recuperar senha",
|
||||||
"Unknown forget type": "Tipo de recuperação desconhecido",
|
"Unknown forget type": "Tipo de recuperação desconhecido",
|
||||||
"Verify": "Verificar"
|
"Verify": "Verificar"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Quando ativada, a exclusão de usuários não os removerá completamente do banco de dados. Em vez disso, eles serão marcados como excluídos",
|
"Soft deletion - Tooltip": "Quando ativada, a exclusão de usuários não os removerá completamente do banco de dados. Em vez disso, eles serão marcados como excluídos",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Coleção de tags disponíveis para os usuários escolherem",
|
"Tags - Tooltip": "Coleção de tags disponíveis para os usuários escolherem",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "Ver regra",
|
"View rule": "Ver regra",
|
||||||
"Visible": "Visível",
|
"Visible": "Visível",
|
||||||
"Website URL": "URL do website",
|
"Website URL": "URL do website",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processando...",
|
"Processing...": "Processando...",
|
||||||
"Product": "Produto",
|
"Product": "Produto",
|
||||||
"Product - Tooltip": "Nome do Produto",
|
"Product - Tooltip": "Nome do Produto",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Resultado",
|
"Result": "Resultado",
|
||||||
"Return to Website": "Retornar ao Website",
|
"Return to Website": "Retornar ao Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "O pagamento ainda está sendo processado",
|
"The payment is still under processing": "O pagamento ainda está sendo processado",
|
||||||
"Type - Tooltip": "Método de pagamento utilizado ao comprar o produto",
|
"Type - Tooltip": "Método de pagamento utilizado ao comprar o produto",
|
||||||
"You have successfully completed the payment": "Você concluiu o pagamento com sucesso",
|
"You have successfully completed the payment": "Você concluiu o pagamento com sucesso",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "por favor, aguarde alguns segundos...",
|
"please wait for a few seconds...": "por favor, aguarde alguns segundos...",
|
||||||
"the current state is": "o estado atual é"
|
"the current state is": "o estado atual é"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Editar Produto",
|
"Edit Product": "Editar Produto",
|
||||||
"Image": "Imagem",
|
"Image": "Imagem",
|
||||||
"Image - Tooltip": "Imagem do produto",
|
"Image - Tooltip": "Imagem do produto",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Novo Produto",
|
"New Product": "Novo Produto",
|
||||||
"Pay": "Pagar",
|
"Pay": "Pagar",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Endereço de e-mail do remetente",
|
"From address - Tooltip": "Endereço de e-mail do remetente",
|
||||||
"From name": "Nome do remetente",
|
"From name": "Nome do remetente",
|
||||||
"From name - Tooltip": "Nome do remetente",
|
"From name - Tooltip": "Nome do remetente",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Nome do host",
|
"Host - Tooltip": "Nome do host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copiar Link",
|
"Copy Link": "Copiar Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "A entrada não é um ID fiscal de fatura válido!",
|
"The input is not invoice Tax ID!": "A entrada não é um ID fiscal de fatura válido!",
|
||||||
"The input is not invoice title!": "A entrada não é um título de fatura válido!",
|
"The input is not invoice title!": "A entrada não é um título de fatura válido!",
|
||||||
"The input is not valid Email!": "A entrada não é um Email válido!",
|
"The input is not valid Email!": "A entrada não é um Email válido!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Logins sociais vinculados pelo usuário",
|
"3rd-party logins - Tooltip": "Logins sociais vinculados pelo usuário",
|
||||||
"Address": "Endereço",
|
"Address": "Endereço",
|
||||||
"Address - Tooltip": "Endereço residencial",
|
"Address - Tooltip": "Endereço residencial",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Afiliação",
|
"Affiliation": "Afiliação",
|
||||||
"Affiliation - Tooltip": "Empregador, como nome da empresa ou organização",
|
"Affiliation - Tooltip": "Empregador, como nome da empresa ou organização",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Biografia",
|
"Bio": "Biografia",
|
||||||
"Bio - Tooltip": "Autoapresentação do usuário",
|
"Bio - Tooltip": "Autoapresentação do usuário",
|
||||||
"Birthday": "Aniversário",
|
"Birthday": "Aniversário",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Contas gerenciadas",
|
"Managed accounts": "Contas gerenciadas",
|
||||||
"Modify password...": "Modificar senha...",
|
"Modify password...": "Modificar senha...",
|
||||||
"Multi-factor authentication": "Autenticação de vários fatores",
|
"Multi-factor authentication": "Autenticação de vários fatores",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Novo E-mail",
|
"New Email": "Novo E-mail",
|
||||||
"New Password": "Nova Senha",
|
"New Password": "Nova Senha",
|
||||||
"New User": "Novo Usuário",
|
"New User": "Novo Usuário",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "Digite a senha"
|
"input password": "Digite a senha"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Следующий шаг",
|
"Next Step": "Следующий шаг",
|
||||||
"Please input your username!": "Пожалуйста, введите своё имя пользователя!",
|
"Please input your username!": "Пожалуйста, введите своё имя пользователя!",
|
||||||
"Reset": "Сбросить",
|
"Reset": "Сбросить",
|
||||||
"Retrieve password": "Восстановить пароль",
|
"Reset password": "Восстановить пароль",
|
||||||
"Unknown forget type": "Неизвестный забытый тип",
|
"Unknown forget type": "Неизвестный забытый тип",
|
||||||
"Verify": "Проверить"
|
"Verify": "Проверить"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Когда включено, удаление пользователей не полностью удаляет их из базы данных. Вместо этого они будут помечены как удаленные",
|
"Soft deletion - Tooltip": "Когда включено, удаление пользователей не полностью удаляет их из базы данных. Вместо этого они будут помечены как удаленные",
|
||||||
"Tags": "Теги",
|
"Tags": "Теги",
|
||||||
"Tags - Tooltip": "Коллекция тегов, доступных для выбора пользователями",
|
"Tags - Tooltip": "Коллекция тегов, доступных для выбора пользователями",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "Правило просмотра",
|
"View rule": "Правило просмотра",
|
||||||
"Visible": "Видимый",
|
"Visible": "Видимый",
|
||||||
"Website URL": "Веб-адрес сайта",
|
"Website URL": "Веб-адрес сайта",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Обработка...",
|
"Processing...": "Обработка...",
|
||||||
"Product": "Продукт",
|
"Product": "Продукт",
|
||||||
"Product - Tooltip": "Название продукта",
|
"Product - Tooltip": "Название продукта",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Результат",
|
"Result": "Результат",
|
||||||
"Return to Website": "Вернуться на веб-сайт",
|
"Return to Website": "Вернуться на веб-сайт",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "Оплата все еще обрабатывается",
|
"The payment is still under processing": "Оплата все еще обрабатывается",
|
||||||
"Type - Tooltip": "Способ оплаты, используемый при покупке товара",
|
"Type - Tooltip": "Способ оплаты, используемый при покупке товара",
|
||||||
"You have successfully completed the payment": "Вы успешно произвели платеж",
|
"You have successfully completed the payment": "Вы успешно произвели платеж",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "Пожалуйста, подождите несколько секунд...",
|
"please wait for a few seconds...": "Пожалуйста, подождите несколько секунд...",
|
||||||
"the current state is": "текущее состояние"
|
"the current state is": "текущее состояние"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Редактировать продукт",
|
"Edit Product": "Редактировать продукт",
|
||||||
"Image": "Изображение",
|
"Image": "Изображение",
|
||||||
"Image - Tooltip": "Изображение продукта",
|
"Image - Tooltip": "Изображение продукта",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Новый продукт",
|
"New Product": "Новый продукт",
|
||||||
"Pay": "Заплатить",
|
"Pay": "Заплатить",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "From address - Tooltip",
|
"From address - Tooltip": "From address - Tooltip",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "From name - Tooltip",
|
"From name - Tooltip": "From name - Tooltip",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Хост",
|
"Host": "Хост",
|
||||||
"Host - Tooltip": "Имя хоста",
|
"Host - Tooltip": "Имя хоста",
|
||||||
"IdP": "ИдП",
|
"IdP": "ИдП",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Копировать ссылку",
|
"Copy Link": "Копировать ссылку",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"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!": "Ввод не является действительным адресом электронной почты!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Социальные логины, связанные пользователем",
|
"3rd-party logins - Tooltip": "Социальные логины, связанные пользователем",
|
||||||
"Address": "Адрес",
|
"Address": "Адрес",
|
||||||
"Address - Tooltip": "Адрес проживания",
|
"Address - Tooltip": "Адрес проживания",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Принадлежность",
|
"Affiliation": "Принадлежность",
|
||||||
"Affiliation - Tooltip": "Работодатель, такой как название компании или организации",
|
"Affiliation - Tooltip": "Работодатель, такой как название компании или организации",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Био",
|
"Bio": "Био",
|
||||||
"Bio - Tooltip": "Само представление пользователя",
|
"Bio - Tooltip": "Само представление пользователя",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Управляемые аккаунты",
|
"Managed accounts": "Управляемые аккаунты",
|
||||||
"Modify password...": "Изменить пароль...",
|
"Modify password...": "Изменить пароль...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Новое электронное письмо",
|
"New Email": "Новое электронное письмо",
|
||||||
"New Password": "Новый пароль",
|
"New Password": "Новый пароль",
|
||||||
"New User": "Новый пользователь",
|
"New User": "Новый пользователь",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "введите пароль"
|
"input password": "введите пароль"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
1209
web/src/locales/sk/data.json
Normal file
1209
web/src/locales/sk/data.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Next Step",
|
"Next Step": "Next Step",
|
||||||
"Please input your username!": "Please input your username!",
|
"Please input your username!": "Please input your username!",
|
||||||
"Reset": "Reset",
|
"Reset": "Reset",
|
||||||
"Retrieve password": "Retrieve password",
|
"Reset password": "Reset password",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Verify"
|
"Verify": "Verify"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Visible",
|
"Visible": "Visible",
|
||||||
"Website URL": "Website URL",
|
"Website URL": "Website URL",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Sonraki adım",
|
"Next Step": "Sonraki adım",
|
||||||
"Please input your username!": "Lütfen kullanıcı adınızı girin",
|
"Please input your username!": "Lütfen kullanıcı adınızı girin",
|
||||||
"Reset": "Sıfırla",
|
"Reset": "Sıfırla",
|
||||||
"Retrieve password": "Şifre kurtar",
|
"Reset password": "Şifre kurtar",
|
||||||
"Unknown forget type": "Unknown forget type",
|
"Unknown forget type": "Unknown forget type",
|
||||||
"Verify": "Doğrula"
|
"Verify": "Doğrula"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
"Soft deletion - Tooltip": "When enabled, deleting users will not completely remove them from the database. Instead, they will be marked as deleted",
|
||||||
"Tags": "Tags",
|
"Tags": "Tags",
|
||||||
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
"Tags - Tooltip": "Collection of tags available for users to choose from",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "View rule",
|
"View rule": "View rule",
|
||||||
"Visible": "Görünür",
|
"Visible": "Görünür",
|
||||||
"Website URL": "Web Sitesi URL'si",
|
"Website URL": "Web Sitesi URL'si",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Processing...",
|
"Processing...": "Processing...",
|
||||||
"Product": "Product",
|
"Product": "Product",
|
||||||
"Product - Tooltip": "Product Name",
|
"Product - Tooltip": "Product Name",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Result",
|
"Result": "Result",
|
||||||
"Return to Website": "Return to Website",
|
"Return to Website": "Return to Website",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "The payment is still under processing",
|
"The payment is still under processing": "The payment is still under processing",
|
||||||
"Type - Tooltip": "Payment method used when purchasing the product",
|
"Type - Tooltip": "Payment method used when purchasing the product",
|
||||||
"You have successfully completed the payment": "You have successfully completed the payment",
|
"You have successfully completed the payment": "You have successfully completed the payment",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "please wait for a few seconds...",
|
"please wait for a few seconds...": "please wait for a few seconds...",
|
||||||
"the current state is": "the current state is"
|
"the current state is": "the current state is"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Edit Product",
|
"Edit Product": "Edit Product",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Image - Tooltip": "Image of product",
|
"Image - Tooltip": "Image of product",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "New Product",
|
"New Product": "New Product",
|
||||||
"Pay": "Pay",
|
"Pay": "Pay",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Email address of \"From\"",
|
"From address - Tooltip": "Email address of \"From\"",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "Name of \"From\"",
|
"From name - Tooltip": "Name of \"From\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Host - Tooltip": "Name of host",
|
"Host - Tooltip": "Name of host",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Copy Link",
|
"Copy Link": "Copy Link",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "The input is not invoice Tax ID!",
|
"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 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 Email!": "The input is not valid Email!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
"3rd-party logins - Tooltip": "Social logins linked by the user",
|
||||||
"Address": "Address",
|
"Address": "Address",
|
||||||
"Address - Tooltip": "Residential address",
|
"Address - Tooltip": "Residential address",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
"Affiliation - Tooltip": "Employer, such as company name or organization name",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "Bio",
|
"Bio": "Bio",
|
||||||
"Bio - Tooltip": "Self introduction of the user",
|
"Bio - Tooltip": "Self introduction of the user",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Managed accounts",
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "New Email",
|
"New Email": "New Email",
|
||||||
"New Password": "New Password",
|
"New Password": "New Password",
|
||||||
"New User": "New User",
|
"New User": "New User",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "şifreyi girin"
|
"input password": "şifreyi girin"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -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": "Виберіть файл HTML",
|
"Please select a HTML file": "Виберіть файл HTML",
|
||||||
@ -165,7 +166,7 @@
|
|||||||
"Next Step": "Наступний крок",
|
"Next Step": "Наступний крок",
|
||||||
"Please input your username!": "Будь ласка, введіть своє ім'я користувача!",
|
"Please input your username!": "Будь ласка, введіть своє ім'я користувача!",
|
||||||
"Reset": "Скинути",
|
"Reset": "Скинути",
|
||||||
"Retrieve password": "Отримати пароль",
|
"Reset password": "Отримати пароль",
|
||||||
"Unknown forget type": "Невідомий забутий тип",
|
"Unknown forget type": "Невідомий забутий тип",
|
||||||
"Verify": "Підтвердити"
|
"Verify": "Підтвердити"
|
||||||
},
|
},
|
||||||
@ -229,6 +230,7 @@
|
|||||||
"Email": "Електронна пошта",
|
"Email": "Електронна пошта",
|
||||||
"Email - Tooltip": "Дійсна електронна пошта",
|
"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 - Tooltip": "Увімкнути темний логотип",
|
||||||
@ -311,6 +313,7 @@
|
|||||||
"Phone": "Телефон",
|
"Phone": "Телефон",
|
||||||
"Phone - Tooltip": "Номер телефону",
|
"Phone - Tooltip": "Номер телефону",
|
||||||
"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": "Теги, до яких належить користувач, за умовчанням \"звичайний користувач\"",
|
"User type - Tooltip": "Теги, до яких належить користувач, за умовчанням \"звичайний користувач\"",
|
||||||
"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, електронна пошта або телефон",
|
"LDAP username, Email or phone": "Ім’я користувача LDAP, електронна пошта або телефон",
|
||||||
"Loading": "Завантаження",
|
"Loading": "Завантаження",
|
||||||
"Logging out...": "Вихід...",
|
"Logging out...": "Вихід...",
|
||||||
"Login button": "Кнопка входу",
|
|
||||||
"MetaMask plugin not detected": "Плагін MetaMask не виявлено",
|
"MetaMask plugin not detected": "Плагін MetaMask не виявлено",
|
||||||
"Model loading failure": "Помилка завантаження моделі",
|
"Model loading failure": "Помилка завантаження моделі",
|
||||||
"No account?": "Немає облікового запису?",
|
"No account?": "Немає облікового запису?",
|
||||||
@ -498,6 +501,7 @@
|
|||||||
"Sign in with Face ID": "Увійдіть за допомогою Face ID",
|
"Sign in with Face ID": "Увійдіть за допомогою Face ID",
|
||||||
"Sign in with WebAuthn": "Увійдіть за допомогою WebAuthn",
|
"Sign in with WebAuthn": "Увійдіть за допомогою WebAuthn",
|
||||||
"Sign in with {type}": "Увійдіть за допомогою {type}",
|
"Sign in with {type}": "Увійдіть за допомогою {type}",
|
||||||
|
"Signin button": "Signin button",
|
||||||
"Signing in...": "Вхід...",
|
"Signing in...": "Вхід...",
|
||||||
"Successfully logged in with WebAuthn credentials": "Успішно ввійшли за допомогою облікових даних WebAuthn",
|
"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": "Камера зараз використовується іншою веб-сторінкою",
|
||||||
@ -572,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Якщо ввімкнено, видалення користувачів не призведе до їх повного видалення з бази даних. ",
|
"Soft deletion - Tooltip": "Якщо ввімкнено, видалення користувачів не призведе до їх повного видалення з бази даних. ",
|
||||||
"Tags": "Теги",
|
"Tags": "Теги",
|
||||||
"Tags - Tooltip": "Колекція тегів, доступна для вибору користувачами",
|
"Tags - Tooltip": "Колекція тегів, доступна для вибору користувачами",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "Переглянути правило",
|
"View rule": "Переглянути правило",
|
||||||
"Visible": "Видно",
|
"Visible": "Видно",
|
||||||
"Website URL": "адреса вебсайту",
|
"Website URL": "адреса вебсайту",
|
||||||
@ -615,6 +621,7 @@
|
|||||||
"Processing...": "Обробка...",
|
"Processing...": "Обробка...",
|
||||||
"Product": "Продукт",
|
"Product": "Продукт",
|
||||||
"Product - Tooltip": "Назва продукту",
|
"Product - Tooltip": "Назва продукту",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Результат",
|
"Result": "Результат",
|
||||||
"Return to Website": "Повернутися на сайт",
|
"Return to Website": "Повернутися на сайт",
|
||||||
"The payment has been canceled": "Платіж скасовано",
|
"The payment has been canceled": "Платіж скасовано",
|
||||||
@ -623,6 +630,8 @@
|
|||||||
"The payment is still under processing": "Платіж ще обробляється",
|
"The payment is still under processing": "Платіж ще обробляється",
|
||||||
"Type - Tooltip": "Спосіб оплати, який використовується при покупці товару",
|
"Type - Tooltip": "Спосіб оплати, який використовується при покупці товару",
|
||||||
"You have successfully completed the payment": "Ви успішно завершили оплату",
|
"You have successfully completed the payment": "Ви успішно завершили оплату",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "зачекайте кілька секунд...",
|
"please wait for a few seconds...": "зачекайте кілька секунд...",
|
||||||
"the current state is": "поточний стан є"
|
"the current state is": "поточний стан є"
|
||||||
},
|
},
|
||||||
@ -685,6 +694,8 @@
|
|||||||
"Edit Product": "Редагувати товар",
|
"Edit Product": "Редагувати товар",
|
||||||
"Image": "Зображення",
|
"Image": "Зображення",
|
||||||
"Image - Tooltip": "Зображення товару",
|
"Image - Tooltip": "Зображення товару",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Новий продукт",
|
"New Product": "Новий продукт",
|
||||||
"Pay": "платити",
|
"Pay": "платити",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -774,6 +785,8 @@
|
|||||||
"From address - Tooltip": "Електронна адреса \"Від\"",
|
"From address - Tooltip": "Електронна адреса \"Від\"",
|
||||||
"From name": "Від імені",
|
"From name": "Від імені",
|
||||||
"From name - Tooltip": "Назва \"Від\"",
|
"From name - Tooltip": "Назва \"Від\"",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Хост",
|
"Host": "Хост",
|
||||||
"Host - Tooltip": "Ім'я хоста",
|
"Host - Tooltip": "Ім'я хоста",
|
||||||
"IdP": "IDP",
|
"IdP": "IDP",
|
||||||
@ -893,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Спрацьовує",
|
"Is triggered": "Спрацьовує",
|
||||||
"Object": "Об'єкт",
|
"Object": "Об'єкт",
|
||||||
"Response": "Відповідь"
|
"Response": "Відповідь",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Копіювати посилання",
|
"Copy Link": "Копіювати посилання",
|
||||||
@ -941,6 +955,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 - Tooltip": "Умови використання, з якими користувачі повинні ознайомитися та погодитися під час реєстрації",
|
||||||
"Text 1": "Текст 1",
|
"Text 1": "Текст 1",
|
||||||
@ -948,6 +963,7 @@
|
|||||||
"Text 3": "Текст 3",
|
"Text 3": "Текст 3",
|
||||||
"Text 4": "Текст 4",
|
"Text 4": "Текст 4",
|
||||||
"Text 5": "Текст 5",
|
"Text 5": "Текст 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"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!": "Введена недійсна адреса електронної пошти!",
|
||||||
@ -1068,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Соціальні входи, пов’язані користувачем",
|
"3rd-party logins - Tooltip": "Соціальні входи, пов’язані користувачем",
|
||||||
"Address": "Адреса",
|
"Address": "Адреса",
|
||||||
"Address - Tooltip": "Адреса місця проживання",
|
"Address - Tooltip": "Адреса місця проживання",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Приналежність",
|
"Affiliation": "Приналежність",
|
||||||
"Affiliation - Tooltip": "Роботодавець, наприклад назва компанії чи організації",
|
"Affiliation - Tooltip": "Роботодавець, наприклад назва компанії чи організації",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "біографія",
|
"Bio": "біографія",
|
||||||
"Bio - Tooltip": "Самостійне представлення користувача",
|
"Bio - Tooltip": "Самостійне представлення користувача",
|
||||||
"Birthday": "день народження",
|
"Birthday": "день народження",
|
||||||
@ -1120,6 +1139,8 @@
|
|||||||
"Managed accounts": "Керовані облікові записи",
|
"Managed accounts": "Керовані облікові записи",
|
||||||
"Modify password...": "Змінити пароль...",
|
"Modify password...": "Змінити пароль...",
|
||||||
"Multi-factor authentication": "Багатофакторна аутентифікація",
|
"Multi-factor authentication": "Багатофакторна аутентифікація",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Нова електронна пошта",
|
"New Email": "Нова електронна пошта",
|
||||||
"New Password": "Новий пароль",
|
"New Password": "Новий пароль",
|
||||||
"New User": "Новий користувач",
|
"New User": "Новий користувач",
|
||||||
@ -1162,9 +1183,11 @@
|
|||||||
"Values": "Цінності",
|
"Values": "Цінності",
|
||||||
"Verification code sent": "Код підтвердження надіслано",
|
"Verification code sent": "Код підтвердження надіслано",
|
||||||
"WebAuthn credentials": "Облікові дані WebAuthn",
|
"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": "введіть пароль"
|
"input password": "введіть пароль"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Приймач"
|
"Receiver": "Приймач"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "Bước tiếp theo",
|
"Next Step": "Bước tiếp theo",
|
||||||
"Please input your username!": "Vui lòng nhập tên đăng nhập của bạn!",
|
"Please input your username!": "Vui lòng nhập tên đăng nhập của bạn!",
|
||||||
"Reset": "Đặt lại",
|
"Reset": "Đặt lại",
|
||||||
"Retrieve password": "Truy xuất mật khẩu",
|
"Reset password": "Truy xuất mật khẩu",
|
||||||
"Unknown forget type": "Loại quên chưa biết",
|
"Unknown forget type": "Loại quên chưa biết",
|
||||||
"Verify": "Xác thực"
|
"Verify": "Xác thực"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "Khi được bật, việc xóa người dùng sẽ không hoàn toàn loại bỏ họ khỏi cơ sở dữ liệu. Thay vào đó, họ sẽ được đánh dấu là đã bị xóa",
|
"Soft deletion - Tooltip": "Khi được bật, việc xóa người dùng sẽ không hoàn toàn loại bỏ họ khỏi cơ sở dữ liệu. Thay vào đó, họ sẽ được đánh dấu là đã bị xóa",
|
||||||
"Tags": "Thẻ",
|
"Tags": "Thẻ",
|
||||||
"Tags - Tooltip": "Bộ sưu tập các thẻ có sẵn cho người dùng lựa chọn",
|
"Tags - Tooltip": "Bộ sưu tập các thẻ có sẵn cho người dùng lựa chọn",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "Xem quy tắc",
|
"View rule": "Xem quy tắc",
|
||||||
"Visible": "Rõ ràng",
|
"Visible": "Rõ ràng",
|
||||||
"Website URL": "Địa chỉ trang web",
|
"Website URL": "Địa chỉ trang web",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "Đang xử lý...",
|
"Processing...": "Đang xử lý...",
|
||||||
"Product": "Sản phẩm",
|
"Product": "Sản phẩm",
|
||||||
"Product - Tooltip": "Tên sản phẩm",
|
"Product - Tooltip": "Tên sản phẩm",
|
||||||
|
"Recharged successfully": "Recharged successfully",
|
||||||
"Result": "Kết quả",
|
"Result": "Kết quả",
|
||||||
"Return to Website": "Trở lại trang web",
|
"Return to Website": "Trở lại trang web",
|
||||||
"The payment has been canceled": "The payment has been canceled",
|
"The payment has been canceled": "The payment has been canceled",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "Thanh toán vẫn đang được xử lý",
|
"The payment is still under processing": "Thanh toán vẫn đang được xử lý",
|
||||||
"Type - Tooltip": "Phương thức thanh toán được sử dụng khi mua sản phẩm",
|
"Type - Tooltip": "Phương thức thanh toán được sử dụng khi mua sản phẩm",
|
||||||
"You have successfully completed the payment": "Bạn đã hoàn thành thanh toán thành công",
|
"You have successfully completed the payment": "Bạn đã hoàn thành thanh toán thành công",
|
||||||
|
"You have successfully recharged": "You have successfully recharged",
|
||||||
|
"Your current balance is": "Your current balance is",
|
||||||
"please wait for a few seconds...": "Vui lòng đợi trong vài giây...",
|
"please wait for a few seconds...": "Vui lòng đợi trong vài giây...",
|
||||||
"the current state is": "tình trạng hiện tại là"
|
"the current state is": "tình trạng hiện tại là"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "Sửa sản phẩm",
|
"Edit Product": "Sửa sản phẩm",
|
||||||
"Image": "Ảnh",
|
"Image": "Ảnh",
|
||||||
"Image - Tooltip": "Hình ảnh sản phẩm",
|
"Image - Tooltip": "Hình ảnh sản phẩm",
|
||||||
|
"Is recharge": "Is recharge",
|
||||||
|
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
|
||||||
"New Product": "Sản phẩm mới",
|
"New Product": "Sản phẩm mới",
|
||||||
"Pay": "Trả tiền",
|
"Pay": "Trả tiền",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "From address - Tooltip",
|
"From address - Tooltip": "From address - Tooltip",
|
||||||
"From name": "From name",
|
"From name": "From name",
|
||||||
"From name - Tooltip": "From name - Tooltip",
|
"From name - Tooltip": "From name - Tooltip",
|
||||||
|
"Get phone number": "Get phone number",
|
||||||
|
"Get phone number - Tooltip": "If sync phone number is enabled, you should enable google people api first and add scope https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "Chủ nhà",
|
"Host": "Chủ nhà",
|
||||||
"Host - Tooltip": "Tên của người chủ chỗ ở",
|
"Host - Tooltip": "Tên của người chủ chỗ ở",
|
||||||
"IdP": "IdP",
|
"IdP": "IdP",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "Is triggered",
|
"Is triggered": "Is triggered",
|
||||||
"Object": "Object",
|
"Object": "Object",
|
||||||
"Response": "Response"
|
"Response": "Response",
|
||||||
|
"Status code": "Status code"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "Sao chép liên kết",
|
"Copy Link": "Sao chép liên kết",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "Text 3",
|
"Text 3": "Text 3",
|
||||||
"Text 4": "Text 4",
|
"Text 4": "Text 4",
|
||||||
"Text 5": "Text 5",
|
"Text 5": "Text 5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "The input Email doesn't match the signup item regex!",
|
||||||
"The input is not invoice Tax ID!": "Đầu vào không phải là Mã số thuế của hóa đơn!",
|
"The input is not invoice Tax ID!": "Đầu vào không phải là Mã số thuế của hóa đơn!",
|
||||||
"The input is not invoice title!": "Đầu vào không phải là tiêu đề hóa đơn!",
|
"The input is not invoice title!": "Đầu vào không phải là tiêu đề hóa đơn!",
|
||||||
"The input is not valid Email!": "Đầu vào không phải là địa chỉ Email hợp lệ!",
|
"The input is not valid Email!": "Đầu vào không phải là địa chỉ Email hợp lệ!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "Đăng nhập xã hội liên kết bởi người dùng",
|
"3rd-party logins - Tooltip": "Đăng nhập xã hội liên kết bởi người dùng",
|
||||||
"Address": "Địa chỉ",
|
"Address": "Địa chỉ",
|
||||||
"Address - Tooltip": "Địa chỉ cư trú",
|
"Address - Tooltip": "Địa chỉ cư trú",
|
||||||
|
"Address line": "Address line",
|
||||||
"Affiliation": "Liên kết",
|
"Affiliation": "Liên kết",
|
||||||
"Affiliation - Tooltip": "Nhà tuyển dụng, chẳng hạn như tên công ty hoặc tổ chức",
|
"Affiliation - Tooltip": "Nhà tuyển dụng, chẳng hạn như tên công ty hoặc tổ chức",
|
||||||
|
"Balance": "Balance",
|
||||||
|
"Balance - Tooltip": "User's balance",
|
||||||
"Bio": "bản vẻ đời sống",
|
"Bio": "bản vẻ đời sống",
|
||||||
"Bio - Tooltip": "Tự giới thiệu của người dùng",
|
"Bio - Tooltip": "Tự giới thiệu của người dùng",
|
||||||
"Birthday": "Birthday",
|
"Birthday": "Birthday",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "Quản lý tài khoản",
|
"Managed accounts": "Quản lý tài khoản",
|
||||||
"Modify password...": "Sửa đổi mật khẩu...",
|
"Modify password...": "Sửa đổi mật khẩu...",
|
||||||
"Multi-factor authentication": "Multi-factor authentication",
|
"Multi-factor authentication": "Multi-factor authentication",
|
||||||
|
"Need update password": "Need update password",
|
||||||
|
"Need update password - Tooltip": "Force user update password after login",
|
||||||
"New Email": "Email mới",
|
"New Email": "Email mới",
|
||||||
"New Password": "Mật khẩu mới",
|
"New Password": "Mật khẩu mới",
|
||||||
"New User": "Người dùng mới",
|
"New User": "Người dùng mới",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "Nhập mật khẩu"
|
"input password": "Nhập mật khẩu"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "Is used",
|
||||||
"Receiver": "Receiver"
|
"Receiver": "Receiver"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
@ -166,7 +166,7 @@
|
|||||||
"Next Step": "下一步",
|
"Next Step": "下一步",
|
||||||
"Please input your username!": "请输入您的用户名!",
|
"Please input your username!": "请输入您的用户名!",
|
||||||
"Reset": "重置",
|
"Reset": "重置",
|
||||||
"Retrieve password": "找回密码",
|
"Reset password": "重置密码",
|
||||||
"Unknown forget type": "未知的忘记密码类型",
|
"Unknown forget type": "未知的忘记密码类型",
|
||||||
"Verify": "验证"
|
"Verify": "验证"
|
||||||
},
|
},
|
||||||
@ -576,6 +576,8 @@
|
|||||||
"Soft deletion - Tooltip": "启用后,删除一个用户时不会在数据库彻底清除,只会标记为已删除状态",
|
"Soft deletion - Tooltip": "启用后,删除一个用户时不会在数据库彻底清除,只会标记为已删除状态",
|
||||||
"Tags": "标签集合",
|
"Tags": "标签集合",
|
||||||
"Tags - Tooltip": "可供用户选择的标签集合",
|
"Tags - Tooltip": "可供用户选择的标签集合",
|
||||||
|
"Use Email as username": "Use Email as username",
|
||||||
|
"Use Email as username - Tooltip": "Use Email as username if the username field is not visible at signup",
|
||||||
"View rule": "查看规则",
|
"View rule": "查看规则",
|
||||||
"Visible": "是否可见",
|
"Visible": "是否可见",
|
||||||
"Website URL": "主页地址",
|
"Website URL": "主页地址",
|
||||||
@ -619,6 +621,7 @@
|
|||||||
"Processing...": "正在处理...",
|
"Processing...": "正在处理...",
|
||||||
"Product": "商品",
|
"Product": "商品",
|
||||||
"Product - Tooltip": "商品名称",
|
"Product - Tooltip": "商品名称",
|
||||||
|
"Recharged successfully": "充值成功",
|
||||||
"Result": "结果",
|
"Result": "结果",
|
||||||
"Return to Website": "返回原网站",
|
"Return to Website": "返回原网站",
|
||||||
"The payment has been canceled": "付款已取消",
|
"The payment has been canceled": "付款已取消",
|
||||||
@ -627,6 +630,8 @@
|
|||||||
"The payment is still under processing": "支付正在处理",
|
"The payment is still under processing": "支付正在处理",
|
||||||
"Type - Tooltip": "商品购买时的支付方式",
|
"Type - Tooltip": "商品购买时的支付方式",
|
||||||
"You have successfully completed the payment": "支付成功",
|
"You have successfully completed the payment": "支付成功",
|
||||||
|
"You have successfully recharged": "您已成功充值",
|
||||||
|
"Your current balance is": "您现在的余额为",
|
||||||
"please wait for a few seconds...": "请稍后...",
|
"please wait for a few seconds...": "请稍后...",
|
||||||
"the current state is": "当前状态为"
|
"the current state is": "当前状态为"
|
||||||
},
|
},
|
||||||
@ -689,6 +694,8 @@
|
|||||||
"Edit Product": "编辑商品",
|
"Edit Product": "编辑商品",
|
||||||
"Image": "图片",
|
"Image": "图片",
|
||||||
"Image - Tooltip": "商品图片",
|
"Image - Tooltip": "商品图片",
|
||||||
|
"Is recharge": "充值",
|
||||||
|
"Is recharge - Tooltip": "当前商品是否为充值商品",
|
||||||
"New Product": "添加商品",
|
"New Product": "添加商品",
|
||||||
"Pay": "支付方式",
|
"Pay": "支付方式",
|
||||||
"PayPal": "PayPal",
|
"PayPal": "PayPal",
|
||||||
@ -778,6 +785,8 @@
|
|||||||
"From address - Tooltip": "邮件里发件人的邮箱地址",
|
"From address - Tooltip": "邮件里发件人的邮箱地址",
|
||||||
"From name": "发件人名称",
|
"From name": "发件人名称",
|
||||||
"From name - Tooltip": "邮件里发件人的显示名称",
|
"From name - Tooltip": "邮件里发件人的显示名称",
|
||||||
|
"Get phone number": "获取手机号码",
|
||||||
|
"Get phone number - Tooltip": "如果启用获取手机号码,你需要先启用peopleApi并添加范围https://www.googleapis.com/auth/user.phonenumbers.read",
|
||||||
"Host": "主机",
|
"Host": "主机",
|
||||||
"Host - Tooltip": "主机名",
|
"Host - Tooltip": "主机名",
|
||||||
"IdP": "身份提供商",
|
"IdP": "身份提供商",
|
||||||
@ -897,7 +906,8 @@
|
|||||||
"record": {
|
"record": {
|
||||||
"Is triggered": "是否触发",
|
"Is triggered": "是否触发",
|
||||||
"Object": "实体",
|
"Object": "实体",
|
||||||
"Response": "响应"
|
"Response": "响应",
|
||||||
|
"Status code": "状态码"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"Copy Link": "复制链接",
|
"Copy Link": "复制链接",
|
||||||
@ -953,6 +963,7 @@
|
|||||||
"Text 3": "文本3",
|
"Text 3": "文本3",
|
||||||
"Text 4": "文本4",
|
"Text 4": "文本4",
|
||||||
"Text 5": "文本5",
|
"Text 5": "文本5",
|
||||||
|
"The input Email doesn't match the signup item regex!": "您输入的邮箱地址与注册项的regex表达式不匹配!",
|
||||||
"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!": "您输入的电子邮箱格式有误!",
|
||||||
@ -1073,8 +1084,11 @@
|
|||||||
"3rd-party logins - Tooltip": "用户所绑定的社会化登录",
|
"3rd-party logins - Tooltip": "用户所绑定的社会化登录",
|
||||||
"Address": "地址",
|
"Address": "地址",
|
||||||
"Address - Tooltip": "居住地址",
|
"Address - Tooltip": "居住地址",
|
||||||
|
"Address line": "地址",
|
||||||
"Affiliation": "工作单位",
|
"Affiliation": "工作单位",
|
||||||
"Affiliation - Tooltip": "工作单位,如公司、组织名称",
|
"Affiliation - Tooltip": "工作单位,如公司、组织名称",
|
||||||
|
"Balance": "余额",
|
||||||
|
"Balance - Tooltip": "用户的余额",
|
||||||
"Bio": "自我介绍",
|
"Bio": "自我介绍",
|
||||||
"Bio - Tooltip": "用户的自我介绍",
|
"Bio - Tooltip": "用户的自我介绍",
|
||||||
"Birthday": "生日",
|
"Birthday": "生日",
|
||||||
@ -1125,6 +1139,8 @@
|
|||||||
"Managed accounts": "托管账户",
|
"Managed accounts": "托管账户",
|
||||||
"Modify password...": "编辑密码...",
|
"Modify password...": "编辑密码...",
|
||||||
"Multi-factor authentication": "多因素认证",
|
"Multi-factor authentication": "多因素认证",
|
||||||
|
"Need update password": "需要更新密码",
|
||||||
|
"Need update password - Tooltip": "强制用户在登录后更新密码",
|
||||||
"New Email": "新邮箱",
|
"New Email": "新邮箱",
|
||||||
"New Password": "新密码",
|
"New Password": "新密码",
|
||||||
"New User": "添加用户",
|
"New User": "添加用户",
|
||||||
@ -1171,6 +1187,7 @@
|
|||||||
"input password": "输入密码"
|
"input password": "输入密码"
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
|
"Is used": "已使用",
|
||||||
"Receiver": "接收者"
|
"Receiver": "接收者"
|
||||||
},
|
},
|
||||||
"webhook": {
|
"webhook": {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user