Compare commits

...

50 Commits

Author SHA1 Message Date
Yang Luo
d8cb82f67a feat: upgrade CI Node.js version to 20 2024-07-09 13:09:40 +08:00
赵尧鹏
cad2e1bcc3 feat: don't drop empty table for adapters (#3043)
* fix: solve the problem of update operation returning 'unaffected'

* feat: remove the action for Dropping empty adapter data table
2024-07-09 11:35:22 +08:00
赵尧鹏
52cc2e4fa7 feat: fix bug in permission's owner edit (#3041) 2024-07-06 11:24:08 +08:00
Leon Koth
8077a2ccba feat: fix bug for access key and secret login (#3022)
* fix: get username for keys

* chore: move user nil check
2024-06-27 21:24:54 +08:00
Eric Luo
4cb8e4a514 feat: Revert "feat: fix OIDC address field" (#3020)
This reverts commit 2f48d45773.
2024-06-25 16:14:26 +08:00
Husile
2f48d45773 feat: fix OIDC address field (#3013)
* feat:add fields of sync-database

* feat:add fields of sync-database

* feat: add several fields related to the OIDC specification address

* feat: add the field Address to Address structure in UserWithoutThirdIdp

* fix: delete redundant fields

* fix: add Address struct and delete redundant fields
2024-06-25 11:54:34 +08:00
Grégoire
cff0c7a273 feat: support "Use Email as username" in org (#3002)
Signed-off-by: Grégoire Bélorgey <gregoire@jianda.fr>
2024-06-22 16:52:11 +08:00
DacongDA
793a7d6cda feat: add free charge price mode for product buy page (#3015)
* feat: add free charge price mode for product buy page

* fix: improve code format
2024-06-22 14:05:53 +08:00
ailiujiarui
4cc2120fed feat: fix the top Navbar UI is broken issue (#3000) 2024-06-09 17:05:04 +08:00
Yang Luo
93b0f52f26 feat: Revert "feat: fix cannot create "/files" folder issue in local file storage provider in Docker" (#2997)
This reverts commit e228045e37.
2024-06-06 11:09:02 +08:00
DacongDA
e228045e37 feat: fix cannot create "/files" folder issue in local file storage provider in Docker (#2994) 2024-06-06 10:49:56 +08:00
DacongDA
6b8c24e1f0 feat: fix password not encrypted issue in SetPassword() API (#2990)
* fix: fix password not encrypted in set password and password type not changed

* Update user.go

---------

Co-authored-by: Yang Luo <hsluoyz@qq.com>
2024-06-04 13:32:13 +08:00
DacongDA
8a79bb64dd feat: test SMTP connection with browser parameters (#2986) 2024-06-04 01:34:36 +08:00
DacongDA
e5f9aab28f feat: support resetting password on first login (#2980)
* feat: support reset password in first login

* feat: disable needUpdatePassword when user haven't email and phone and mfa
2024-06-02 01:00:55 +08:00
Yang Luo
7d05b69aac feat: remove useless code 2024-05-28 20:33:55 +08:00
DacongDA
868e66e866 feat: fix QQ login error when using mobile browser (#2971) 2024-05-27 01:07:15 +08:00
Husile
40ad3c9234 feat: support MFA fields in syncer (#2966)
* feat:add fields of sync-database

* feat:add fields of sync-database
2024-05-27 01:06:59 +08:00
Alex Babel
e2cd0604c2 feat: add back arm64 support in Docker image (#2969) 2024-05-26 01:22:49 +08:00
Yang Luo
78c3065fbb feat: fix address field bug in user edit page 2024-05-24 17:19:27 +08:00
DacongDA
af2a9f0374 feat: get phone number and country from Google OAuth provider (#2965)
* feat: get phone number and country from Google OAuth provider

* feat: fix i18n
2024-05-23 00:42:36 +08:00
DacongDA
bfcfb56336 feat: add address line 1 and 2 in web UI (#2961) 2024-05-19 23:55:38 +08:00
DacongDA
c48306d117 feat: check signup item email regex in signup page (#2960)
* feat: check email regex in frontend

* Update SignupPage.js

---------

Co-authored-by: Yang Luo <hsluoyz@qq.com>
2024-05-19 22:07:34 +08:00
DacongDA
6efec6b4b5 feat: support "label" field for signin item table (#2956) 2024-05-19 03:07:36 +08:00
DacongDA
2daf26aa88 feat: use lowercase username when isUsernameLowered is enabled (#2952)
* feat: auto trim username during login and lowercase when isUsernameLowered enabled in conf

* fix: fix linter error

* fix: fix linter error

* fix: fix linter error
2024-05-17 11:43:19 +08:00
DacongDA
21c151bcf8 feat: fix password not updated bug when updating syncer (#2945) 2024-05-13 00:12:35 +08:00
DacongDA
b6b0b7d318 feat: support checking whether send-webhook API has error (#2944)
* feat: add webhook response for record

* refactor: refactor SendWebhook and use readall to read response body

* fix: improve code format

* fix: improve code format

* fix: improve code format
2024-05-12 20:30:15 +08:00
Yang Luo
0ecc1d599f feat: fix bug in AddUsersInBatch() 2024-05-11 16:59:33 +08:00
Yang Luo
3456fc6695 fix: update go-sms-sender to v0.23.0 2024-05-10 14:05:53 +08:00
DacongDA
c302dc7b8e fix: fix bug when init plan and pricing and record (#2934)
* fix: fix potential bugs in init data

* fix: improve code format

* fix: fix bug when init plan and pricing and record
2024-05-07 23:33:01 +08:00
DacongDA
d24ddd4f1c feat: fix potential bugs in init_data.go (#2932)
* fix: fix potential bugs in init data

* fix: improve code format
2024-05-07 23:11:08 +08:00
Yang Luo
572616d390 fix: fix bug in ProviderItem.CountryCodes 2024-05-07 17:17:45 +08:00
Yang Luo
2187310dbc feat: fix bug in initDefinedOrganization() 2024-05-06 13:57:08 +08:00
DacongDA
26345bb21b feat: add sms provider sendcloud (#2927) 2024-05-06 13:38:55 +08:00
DacongDA
e0455df504 feat: improve record content masking (#2923)
* feat: hide password in record

* feat: improve code format

* feat: improve code format
2024-05-05 12:42:09 +08:00
DacongDA
1dfbbf0e90 feat: fix bug that fails to import built-in org via init_data.json (#2922) 2024-05-05 01:06:15 +08:00
Yang Luo
d43d58dee2 feat: fix getProviders() owner bug in product edit page 2024-05-01 18:04:50 +08:00
Yang Luo
9eb4b12041 fix: rename to countryCodes for UI 2024-05-01 11:44:21 +08:00
Yang Luo
3a45a4ee77 fix: rename to countryCodes 2024-05-01 09:47:44 +08:00
Yang Luo
43393f034b feat: fix the Email provider fails to match bug in GetProviderByCategoryAndRule() 2024-05-01 09:44:19 +08:00
Yang Luo
bafa80513b fix: improve ProviderTable column UI 2024-05-01 00:46:48 +08:00
Yang Luo
8d08140421 fix: fix typo in initBuiltInPermission() 2024-05-01 00:41:16 +08:00
DacongDA
3d29e27d54 feat: support multiple SMS providers for different regions (#2914)
* feat: support using different sms provider for different region

* feat: add multiple support for select and remove log

* feat: revert change for countryCode in loginPage

* feat: revert change for countryCode in user_util.go

* feat: revert change for countryCode in auth.go

* Update application_item.go

* Update CountryCodeSelect.js

* Update ProviderTable.js

---------

Co-authored-by: Yang Luo <hsluoyz@qq.com>
2024-05-01 00:40:47 +08:00
filwaline
199f1d4d10 feat: fix Auto-login causing AuthCodeWithPKCE Failures (#2911) 2024-04-30 12:14:50 +08:00
DacongDA
227e938db6 feat: fix error behavior of custom oauth/saml provider in login page in big icon mode (#2900) 2024-04-26 23:33:41 +08:00
Yang Luo
739cfd84ed feat: cannot empty SigninMethodTable now 2024-04-26 21:23:23 +08:00
DacongDA
8dbb041a34 feat: fix empty custom CSS for new rows in signin items table (#2897) 2024-04-24 15:19:30 +08:00
Yang Luo
af2d26daf2 Add object.IsAppUser() 2024-04-24 01:10:38 +08:00
DacongDA
90d502ab2b feat: add custom css style for signup page and enhance css edit (#2880)
* feat: add custom css style for signup page and enhance css edit in signintable

* feat: change cssStyle to customCss

* feat: auto hide <style> label, fix display problem on providers, remove auto add providers in signup page

* fix: fix indent in signin items customCss and fix providers display in signup items

* fix: fix login replace logical
2024-04-21 11:56:18 +08:00
MyColorfulDays
d51af3378e fix: fix init data not saved to database (#2885) (#2886) 2024-04-21 11:55:06 +08:00
Yang Luo
87e2b97813 feat: translate Ukrainian language i18n 2024-04-20 02:14:23 +08:00
113 changed files with 2935 additions and 1532 deletions

View File

@@ -35,7 +35,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
cache: 'yarn'
cache-dependency-path: ./web/yarn.lock
- run: yarn install && CI=false yarn run build
@@ -101,7 +101,7 @@ jobs:
working-directory: ./
- uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
cache: 'yarn'
cache-dependency-path: ./web/yarn.lock
- run: yarn install
@@ -138,7 +138,7 @@ jobs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
- name: Fetch Previous version
id: get-previous-tag
@@ -194,7 +194,7 @@ jobs:
with:
context: .
target: STANDARD
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
push: true
tags: casbin/casdoor:${{steps.get-current-tag.outputs.tag }},casbin/casdoor:latest
@@ -204,7 +204,7 @@ jobs:
with:
context: .
target: ALLINONE
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
push: true
tags: casbin/casdoor-all-in-one:${{steps.get-current-tag.outputs.tag }},casbin/casdoor-all-in-one:latest

View File

@@ -1,10 +1,10 @@
FROM node:18.19.0 AS FRONT
FROM --platform=$BUILDPLATFORM node:18.19.0 AS FRONT
WORKDIR /web
COPY ./web .
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
COPY . .
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
LABEL MAINTAINER="https://casdoor.org/"
ARG USER=casdoor
ARG TARGETOS
ARG TARGETARCH
ENV BUILDX_ARCH="${TARGETOS:-linux}_${TARGETARCH:-amd64}"
RUN sed -i 's/https/http/' /etc/apk/repositories
RUN apk add --update sudo
@@ -28,7 +31,7 @@ RUN adduser -D $USER -u 1000 \
USER 1000
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/conf/app.conf ./conf/app.conf
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
LABEL MAINTAINER="https://casdoor.org/"
ARG TARGETOS
ARG TARGETARCH
ENV BUILDX_ARCH="${TARGETOS:-linux}_${TARGETARCH:-amd64}"
RUN apt update
RUN apt install -y ca-certificates && update-ca-certificates
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/docker-entrypoint.sh /docker-entrypoint.sh
COPY --from=BACK /go/src/casdoor/conf/app.conf ./conf/app.conf

View File

@@ -8,4 +8,6 @@ else
echo "Google is blocked, Go proxy is enabled: GOPROXY=https://goproxy.cn,direct"
export GOPROXY="https://goproxy.cn,direct"
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 .

View File

@@ -169,7 +169,11 @@ func (c *ApiController) Signup() {
username := authForm.Username
if !application.IsSignupItemVisible("Username") {
username = id
if organization.UseEmailAsUsername && application.IsSignupItemVisible("Email") {
username = authForm.Email
} else {
username = id
}
}
initScore, err := organization.GetInitScore()

View File

@@ -117,7 +117,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
if form.Type == ResponseTypeLogin {
c.SetSessionUsername(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 {
clientId := c.Input().Get("clientId")
responseType := c.Input().Get("responseType")
@@ -139,7 +139,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
}
resp = codeToResponse(code)
resp.Data2 = user.NeedUpdatePassword
if application.EnableSigninSession || application.HasPromptPage() {
// The prompt page needs the user to be signed in
c.SetSessionUsername(userId)
@@ -152,6 +152,8 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
nonce := c.Input().Get("nonce")
token, _ := object.GetTokenByUser(application, user, scope, nonce, c.Ctx.Request.Host)
resp = tokenToResponse(token)
resp.Data2 = user.NeedUpdatePassword
}
} else if form.Type == ResponseTypeSaml { // saml flow
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)
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() {
// The prompt page needs the user to be signed in

View File

@@ -73,7 +73,7 @@ func (c *ApiController) IsAdminOrSelf(user2 *object.User) bool {
func (c *ApiController) isGlobalAdmin() (bool, *object.User) {
username := c.GetSessionUsername()
if strings.HasPrefix(username, "app/") {
if object.IsAppUser(username) {
// e.g., "app/app-casnode"
return true, nil
}

View File

@@ -17,6 +17,7 @@ package controllers
import (
"encoding/json"
"fmt"
"strconv"
"github.com/beego/beego/utils/pagination"
"github.com/casdoor/casdoor/object"
@@ -164,6 +165,16 @@ func (c *ApiController) BuyProduct() {
host := c.Ctx.Request.Host
providerName := c.Input().Get("providerName")
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`
pricingName := c.Input().Get("pricingName")
@@ -189,7 +200,7 @@ func (c *ApiController) BuyProduct() {
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 {
c.ResponseError(err.Error())
return

View File

@@ -27,11 +27,12 @@ import (
)
type EmailForm struct {
Title string `json:"title"`
Content string `json:"content"`
Sender string `json:"sender"`
Receivers []string `json:"receivers"`
Provider string `json:"provider"`
Title string `json:"title"`
Content string `json:"content"`
Sender string `json:"sender"`
Receivers []string `json:"receivers"`
Provider string `json:"provider"`
ProviderObject object.Provider `json:"providerObject"`
}
type SmsForm struct {
@@ -74,7 +75,6 @@ func (c *ApiController) SendEmail() {
c.ResponseError(err.Error())
return
}
} 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
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
if len(emailForm.Receivers) == 1 && emailForm.Receivers[0] == "TestSmtpServer" {
err = object.DailSmtpServer(provider)
@@ -120,7 +127,7 @@ func (c *ApiController) SendEmail() {
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
content = strings.Replace(content, "%s", code, 1)
userString := "Hi"
if !strings.HasPrefix(userId, "app/") {
if !object.IsAppUser(userId) {
var user *object.User
user, err = object.GetUser(userId)
if err != nil {

View File

@@ -20,6 +20,7 @@ import (
"strings"
"github.com/beego/beego/utils/pagination"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"
)
@@ -293,6 +294,11 @@ func (c *ApiController) UpdateUser() {
return
}
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
if isUsernameLowered {
user.Name = strings.ToLower(user.Name)
}
isAdmin := c.IsAdmin()
if pass, err := object.CheckPermissionForUpdateUser(oldUser, &user, isAdmin, c.GetAcceptLanguage()); !pass {
c.ResponseError(err)
@@ -503,8 +509,21 @@ func (c *ApiController) SetPassword() {
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
_, 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 {
c.ResponseError(err.Error())
return

View File

@@ -96,7 +96,7 @@ func (c *ApiController) RequireSignedInUser() (*object.User, bool) {
return nil, false
}
if strings.HasPrefix(userId, "app/") {
if object.IsAppUser(userId) {
tmpUserId := c.Input().Get("userId")
if tmpUserId != "" {
userId = tmpUserId
@@ -142,7 +142,7 @@ func (c *ApiController) IsOrgAdmin() (bool, bool) {
return false, true
}
if strings.HasPrefix(userId, "app/") {
if object.IsAppUser(userId) {
return true, true
}

View File

@@ -295,7 +295,7 @@ func (c *ApiController) SendVerificationCode() {
vform.CountryCode = mfaProps.CountryCode
}
provider, err = application.GetSmsProvider(vform.Method)
provider, err = application.GetSmsProvider(vform.Method, vform.CountryCode)
if err != nil {
c.ResponseError(err.Error())
return

6
go.mod
View File

@@ -9,12 +9,12 @@ require (
github.com/beego/beego v1.12.12
github.com/beevik/etree v1.1.0
github.com/casbin/casbin/v2 v2.77.2
github.com/casdoor/go-sms-sender v0.20.0
github.com/casdoor/go-sms-sender v0.24.0
github.com/casdoor/gomail/v2 v2.0.1
github.com/casdoor/notify v0.45.0
github.com/casdoor/oss v1.6.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/denisenkom/go-mssqldb v0.9.0
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
@@ -45,7 +45,7 @@ require (
github.com/robfig/cron/v3 v3.0.1
github.com/russellhaering/gosaml2 v0.9.0
github.com/russellhaering/goxmldsig v1.2.0
github.com/sendgrid/sendgrid-go v3.14.0+incompatible // indirect
github.com/sendgrid/sendgrid-go v3.14.0+incompatible
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed

10
go.sum
View File

@@ -1003,6 +1003,8 @@ github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0I
github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg=
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
github.com/apistd/uni-go-sdk v0.0.2 h1:7kqETCOz/rz8AQU55XGzxDFGoFeMgeZL5fGwvxKBZrc=
github.com/apistd/uni-go-sdk v0.0.2/go.mod h1:eIqYos4IbHgE/rB75r05ypNLahooEMJCrbjXq322b74=
github.com/appleboy/go-fcm v0.1.5/go.mod h1:MSxZ4LqGRsnywOjnlXJXMqbjZrG4vf+0oHitfC9HRH0=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@@ -1083,8 +1085,8 @@ github.com/casbin/casbin/v2 v2.77.2 h1:yQinn/w9x8AswiwqwtrXz93VU48R1aYTXdHEx4RI3
github.com/casbin/casbin/v2 v2.77.2/go.mod h1:mzGx0hYW9/ksOSpw3wNjk3NRAroq5VMFYUQ6G43iGPk=
github.com/casdoor/go-reddit/v2 v2.1.0 h1:kIbfdJ7AA7H0uTQ8s0q4GGZqSS5V9wVE74RrXyD9XPs=
github.com/casdoor/go-reddit/v2 v2.1.0/go.mod h1:eagkvwlZ4Hcsuc/uQsLHYEulz5jN65SVSwV/AIE7zsc=
github.com/casdoor/go-sms-sender v0.20.0 h1:yLbCakV04DzzehhgBklOrSeCFjMwpfKBeemz9b+Y8OM=
github.com/casdoor/go-sms-sender v0.20.0/go.mod h1:cQs7qqohMJBgIVZebOCB8ko09naG1vzFJEH59VNIscs=
github.com/casdoor/go-sms-sender v0.24.0 h1:LNLsce3EG/87I3JS6UiajF3LlQmdIiCgebEu0IE4wSM=
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/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q=
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/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk=
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.3.0/go.mod h1:frnNtH5GA0wxzAQLyZxxfL0RSsSub9GQPi2Ybe86ocE=
github.com/casvisor/casvisor-go-sdk v1.4.0 h1:hbZEGGJ1cwdHFAxeXrMoNw6yha6Oyg2F0qQhBNCN/dg=
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.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "Der Benutzer %s existiert nicht",
"don't support captchaProvider: ": "Unterstütze captchaProvider nicht:",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Es gibt einen LDAP-Server"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "Der Anbieter: %s wurde nicht gefunden"
},
"verification": {
"Code has not been sent yet!": "Der Code wurde noch nicht versendet!",
"Invalid captcha provider.": "Ungültiger Captcha-Anbieter.",
"Phone number is invalid in your region %s": "Die Telefonnummer ist in Ihrer Region %s ungültig",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing-Test fehlgeschlagen.",
"Unable to get the email modify rule.": "Nicht in der Lage, die E-Mail-Änderungsregel zu erhalten.",
"Unable to get the phone modify rule.": "Nicht in der Lage, die Telefon-Änderungsregel zu erhalten.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "El usuario: %s no existe",
"don't support captchaProvider: ": "No apoyo a captchaProvider",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "El servidor LDAP existe"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "El proveedor: %s no se encuentra"
},
"verification": {
"Code has not been sent yet!": "¡El código aún no ha sido enviado!",
"Invalid captcha provider.": "Proveedor de captcha no válido.",
"Phone number is invalid in your region %s": "El número de teléfono es inválido en tu región %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "El test de Turing falló.",
"Unable to get the email modify rule.": "No se puede obtener la regla de modificación de correo electrónico.",
"Unable to get the phone modify rule.": "No se pudo obtener la regla de modificación del teléfono.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "L'utilisateur : %s n'existe pas",
"don't support captchaProvider: ": "ne prend pas en charge captchaProvider: ",
"this operation is not allowed in demo mode": "cette opération nest pas autorisée en mode démo"
"this operation is not allowed in demo mode": "cette opération nest pas autorisée en mode démo",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Le serveur LDAP existe"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "Le fournisseur : %s n'a pas été trouvé"
},
"verification": {
"Code has not been sent yet!": "Le code n'a pas encore été envoyé !",
"Invalid captcha provider.": "Fournisseur de captcha invalide.",
"Phone number is invalid in your region %s": "Le numéro de téléphone n'est pas valide dans votre région %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Le test de Turing a échoué.",
"Unable to get the email modify rule.": "Incapable d'obtenir la règle de modification de courriel.",
"Unable to get the phone modify rule.": "Impossible d'obtenir la règle de modification de téléphone.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "Pengguna: %s tidak ada",
"don't support captchaProvider: ": "Jangan mendukung captchaProvider:",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Server ldap ada"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "Penyedia: %s tidak ditemukan"
},
"verification": {
"Code has not been sent yet!": "Kode belum dikirimkan!",
"Invalid captcha provider.": "Penyedia captcha tidak valid.",
"Phone number is invalid in your region %s": "Nomor telepon tidak valid di wilayah anda %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Tes Turing gagal.",
"Unable to get the email modify rule.": "Tidak dapat memperoleh aturan modifikasi email.",
"Unable to get the phone modify rule.": "Tidak dapat memodifikasi aturan telepon.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "そのユーザー:%sは存在しません",
"don't support captchaProvider: ": "captchaProviderをサポートしないでください",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "LDAPサーバーは存在します"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "プロバイダー:%sが見つかりません"
},
"verification": {
"Code has not been sent yet!": "まだコードが送信されていません!",
"Invalid captcha provider.": "無効なCAPTCHAプロバイダー。",
"Phone number is invalid in your region %s": "電話番号はあなたの地域で無効です %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "チューリングテストは失敗しました。",
"Unable to get the email modify rule.": "電子メール変更規則を取得できません。",
"Unable to get the phone modify rule.": "電話の変更ルールを取得できません。",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "사용자 %s는 존재하지 않습니다",
"don't support captchaProvider: ": "CaptchaProvider를 지원하지 마세요",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "LDAP 서버가 존재합니다"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "제공자: %s를 찾을 수 없습니다"
},
"verification": {
"Code has not been sent yet!": "코드는 아직 전송되지 않았습니다!",
"Invalid captcha provider.": "잘못된 captcha 제공자입니다.",
"Phone number is invalid in your region %s": "전화 번호가 당신의 지역 %s에서 유효하지 않습니다",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "튜링 테스트 실패.",
"Unable to get the email modify rule.": "이메일 수정 규칙을 가져올 수 없습니다.",
"Unable to get the phone modify rule.": "전화 수정 규칙을 가져올 수 없습니다.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "Пользователь %s не существует",
"don't support captchaProvider: ": "неподдерживаемый captchaProvider: ",
"this operation is not allowed in demo mode": "эта операция не разрешена в демо-режиме"
"this operation is not allowed in demo mode": "эта операция не разрешена в демо-режиме",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "LDAP-сервер существует"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "Поставщик: %s не найден"
},
"verification": {
"Code has not been sent yet!": "Код еще не был отправлен!",
"Invalid captcha provider.": "Недействительный поставщик CAPTCHA.",
"Phone number is invalid in your region %s": "Номер телефона недействителен в вашем регионе %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Тест Тьюринга не удался.",
"Unable to get the email modify rule.": "Невозможно получить правило изменения электронной почты.",
"Unable to get the phone modify rule.": "Невозможно получить правило изменения телефона.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Telefon numaranızın bulunduğu bölgeye hizmet veremiyoruz",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "The provider: %s is not found"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Invalid captcha provider.": "Invalid captcha provider.",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "The organization: %s should have one application at least",
"The user: %s doesn't exist": "Người dùng: %s không tồn tại",
"don't support captchaProvider: ": "không hỗ trợ captchaProvider: ",
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode",
"this operation requires administrator to perform": "this operation requires administrator to perform"
},
"ldap": {
"Ldap server exist": "Máy chủ LDAP tồn tại"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "Nhà cung cấp: %s không được tìm thấy"
},
"verification": {
"Code has not been sent yet!": "Mã chưa được gửi đến!",
"Invalid captcha provider.": "Nhà cung cấp captcha không hợp lệ.",
"Phone number is invalid in your region %s": "Số điện thoại không hợp lệ trong vùng của bạn %s",
"The verification code has not been sent yet!": "The verification code has not been sent yet!",
"The verification code has not been sent yet, or has already been used!": "The verification code has not been sent yet, or has already been used!",
"Turing test failed.": "Kiểm định Turing thất bại.",
"Unable to get the email modify rule.": "Không thể lấy quy tắc sửa đổi email.",
"Unable to get the phone modify rule.": "Không thể thay đổi quy tắc trên điện thoại.",

View File

@@ -81,7 +81,8 @@
"The organization: %s should have one application at least": "组织: %s 应该拥有至少一个应用",
"The user: %s doesn't exist": "用户: %s不存在",
"don't support captchaProvider: ": "不支持验证码提供商: ",
"this operation is not allowed in demo mode": "demo模式下不允许该操作"
"this operation is not allowed in demo mode": "demo模式下不允许该操作",
"this operation requires administrator to perform": "只有管理员才能进行此操作"
},
"ldap": {
"Ldap server exist": "LDAP服务器已存在"
@@ -145,9 +146,10 @@
"The provider: %s is not found": "未找到提供商: %s"
},
"verification": {
"Code has not been sent yet!": "验证码还未发送",
"Invalid captcha provider.": "非法的验证码提供商",
"Phone number is invalid in your region %s": "您所在地区的电话号码无效 %s",
"The verification code has not been sent yet!": "验证码未发送!",
"The verification code has not been sent yet, or has already been used!": "验证码未发送或已被使用!",
"Turing test failed.": "验证码还未发送",
"Unable to get the email modify rule.": "无法获取邮箱修改规则",
"Unable to get the phone modify rule.": "无法获取手机号修改规则",

View File

@@ -25,6 +25,7 @@ import (
"time"
"github.com/casdoor/casdoor/util"
"github.com/nyaruka/phonenumbers"
"golang.org/x/oauth2"
)
@@ -130,6 +131,23 @@ type GoogleUserInfo struct {
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) {
if strings.HasPrefix(token.AccessToken, GoogleIdTokenKey) {
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")
}
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{
Id: googleUserInfo.Id,
Username: googleUserInfo.Email,
DisplayName: googleUserInfo.Name,
Email: googleUserInfo.Email,
AvatarUrl: googleUserInfo.Picture,
Phone: phoneNumber,
CountryCode: countryCode,
}
return &userInfo, nil
}

View File

@@ -35,6 +35,7 @@ type SignupItem struct {
Visible bool `json:"visible"`
Required bool `json:"required"`
Prompted bool `json:"prompted"`
CustomCss string `json:"customCss"`
Label string `json:"label"`
Placeholder string `json:"placeholder"`
Regex string `json:"regex"`
@@ -45,6 +46,7 @@ type SigninItem struct {
Name string `json:"name"`
Visible bool `json:"visible"`
Label string `json:"label"`
CustomCss string `json:"customCss"`
Placeholder string `json:"placeholder"`
Rule string `json:"rule"`
IsCustom bool `json:"isCustom"`
@@ -208,7 +210,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem := &SigninItem{
Name: "Back button",
Visible: true,
Label: "\n<style>\n .back-button {\n top: 65px;\n left: 15px;\n position: absolute;\n }\n</style>\n",
CustomCss: ".back-button {\n top: 65px;\n left: 15px;\n position: absolute;\n}\n.back-inner-button{}",
Placeholder: "",
Rule: "None",
}
@@ -216,7 +218,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Languages",
Visible: true,
Label: "\n<style>\n .login-languages {\n top: 55px;\n right: 5px;\n position: absolute;\n }\n</style>\n",
CustomCss: ".login-languages {\n top: 55px;\n right: 5px;\n position: absolute;\n}",
Placeholder: "",
Rule: "None",
}
@@ -224,7 +226,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Logo",
Visible: true,
Label: "\n<style>\n .login-logo-box {\n }\n</style>\n",
CustomCss: ".login-logo-box {}",
Placeholder: "",
Rule: "None",
}
@@ -232,7 +234,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Signin methods",
Visible: true,
Label: "\n<style>\n .signin-methods {\n }\n</style>\n",
CustomCss: ".signin-methods {}",
Placeholder: "",
Rule: "None",
}
@@ -240,7 +242,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Username",
Visible: true,
Label: "\n<style>\n .login-username {\n }\n</style>\n",
CustomCss: ".login-username {}\n.login-username-input{}",
Placeholder: "",
Rule: "None",
}
@@ -248,7 +250,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Password",
Visible: true,
Label: "\n<style>\n .login-password {\n }\n</style>\n",
CustomCss: ".login-password {}\n.login-password-input{}",
Placeholder: "",
Rule: "None",
}
@@ -256,7 +258,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Agreement",
Visible: true,
Label: "\n<style>\n .login-agreement {\n }\n</style>\n",
CustomCss: ".login-agreement {}",
Placeholder: "",
Rule: "None",
}
@@ -264,7 +266,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Forgot password?",
Visible: true,
Label: "\n<style>\n .login-forget-password {\n display: inline-flex;\n justify-content: space-between;\n width: 320px;\n margin-bottom: 25px;\n }\n</style>\n",
CustomCss: ".login-forget-password {\n display: inline-flex;\n justify-content: space-between;\n width: 320px;\n margin-bottom: 25px;\n}",
Placeholder: "",
Rule: "None",
}
@@ -272,7 +274,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Login button",
Visible: true,
Label: "\n<style>\n .login-button-box {\n margin-bottom: 5px;\n }\n .login-button {\n width: 100%;\n }\n</style>\n",
CustomCss: ".login-button-box {\n margin-bottom: 5px;\n}\n.login-button {\n width: 100%;\n}",
Placeholder: "",
Rule: "None",
}
@@ -280,7 +282,7 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Signup link",
Visible: true,
Label: "\n<style>\n .login-signup-link {\n margin-bottom: 24px;\n display: flex;\n justify-content: end;\n}\n</style>\n",
CustomCss: ".login-signup-link {\n margin-bottom: 24px;\n display: flex;\n justify-content: end;\n}",
Placeholder: "",
Rule: "None",
}
@@ -288,12 +290,18 @@ func extendApplicationWithSigninItems(application *Application) (err error) {
signinItem = &SigninItem{
Name: "Providers",
Visible: true,
Label: "\n<style>\n .provider-img {\n width: 30px;\n margin: 5px;\n }\n .provider-big-img {\n margin-bottom: 10px;\n }\n</style>\n",
CustomCss: ".provider-img {\n width: 30px;\n margin: 5px;\n}\n.provider-big-img {\n margin-bottom: 10px;\n}",
Placeholder: "",
Rule: "None",
}
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
}
@@ -404,8 +412,8 @@ func GetApplicationByUser(user *User) (*Application, error) {
}
func GetApplicationByUserId(userId string) (application *Application, err error) {
owner, name := util.GetOwnerAndNameFromId(userId)
if owner == "app" {
_, name := util.GetOwnerAndNameFromId(userId)
if IsAppUser(userId) {
application, err = getApplication("admin", name)
return
}
@@ -669,11 +677,7 @@ func AddApplication(application *Application) (bool, error) {
return affected != 0, nil
}
func DeleteApplication(application *Application) (bool, error) {
if application.Name == "app-built-in" {
return false, nil
}
func deleteApplication(application *Application) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{application.Owner, application.Name}).Delete(&Application{})
if err != nil {
return false, err
@@ -682,6 +686,14 @@ func DeleteApplication(application *Application) (bool, error) {
return affected != 0, nil
}
func DeleteApplication(application *Application) (bool, error) {
if application.Name == "app-built-in" {
return false, nil
}
return deleteApplication(application)
}
func (application *Application) GetId() string {
return fmt.Sprintf("%s/%s", application.Owner, application.Name)
}

View File

@@ -38,7 +38,20 @@ func (application *Application) GetProviderByCategory(category string) (*Provide
return nil, nil
}
func (application *Application) GetProviderByCategoryAndRule(category string, method string) (*Provider, error) {
func isProviderItemCountryCodeMatched(providerItem *ProviderItem, countryCode string) bool {
if len(providerItem.CountryCodes) == 0 {
return true
}
for _, countryCode2 := range providerItem.CountryCodes {
if countryCode2 == "" || countryCode2 == "All" || countryCode2 == "all" || countryCode2 == countryCode {
return true
}
}
return false
}
func (application *Application) GetProviderByCategoryAndRule(category string, method string, countryCode string) (*Provider, error) {
providers, err := GetProviders(application.Organization)
if err != nil {
return nil, err
@@ -54,7 +67,13 @@ func (application *Application) GetProviderByCategoryAndRule(category string, me
}
for _, providerItem := range application.Providers {
if providerItem.Rule == method || (providerItem.Rule == "all" || providerItem.Rule == "" || providerItem.Rule == "None") {
if providerItem.Provider != nil && providerItem.Provider.Category == "SMS" {
if !isProviderItemCountryCodeMatched(providerItem, countryCode) {
continue
}
}
if providerItem.Rule == method || providerItem.Rule == "" || providerItem.Rule == "All" || providerItem.Rule == "all" || providerItem.Rule == "None" {
if provider, ok := m[providerItem.Name]; ok {
return provider, nil
}
@@ -65,11 +84,11 @@ func (application *Application) GetProviderByCategoryAndRule(category string, me
}
func (application *Application) GetEmailProvider(method string) (*Provider, error) {
return application.GetProviderByCategoryAndRule("Email", method)
return application.GetProviderByCategoryAndRule("Email", method, "All")
}
func (application *Application) GetSmsProvider(method string) (*Provider, error) {
return application.GetProviderByCategoryAndRule("SMS", method)
func (application *Application) GetSmsProvider(method string, countryCode string) (*Provider, error) {
return application.GetProviderByCategoryAndRule("SMS", method, countryCode)
}
func (application *Application) GetStorageProvider() (*Provider, error) {

View File

@@ -410,7 +410,7 @@ func CheckUserPermission(requestUserId, userId string, strict bool, lang string)
}
hasPermission := false
if strings.HasPrefix(requestUserId, "app/") {
if IsAppUser(requestUserId) {
hasPermission = true
} else {
requestUser, err := GetUser(requestUserId)

View File

@@ -154,6 +154,15 @@ func AddGroups(groups []*Group) (bool, error) {
return affected != 0, nil
}
func deleteGroup(group *Group) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{group.Owner, group.Name}).Delete(&Group{})
if err != nil {
return false, err
}
return affected != 0, nil
}
func DeleteGroup(group *Group) (bool, error) {
_, err := ormer.Engine.Get(group)
if err != nil {
@@ -172,12 +181,7 @@ func DeleteGroup(group *Group) (bool, error) {
return false, errors.New("group has users")
}
affected, err := ormer.Engine.ID(core.PK{group.Owner, group.Name}).Delete(&Group{})
if err != nil {
return false, err
}
return affected != 0, nil
return deleteGroup(group)
}
func checkGroupName(name string) error {

View File

@@ -71,7 +71,7 @@ func getBuiltInAccountItems() []*AccountItem {
{Name: "Permissions", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"},
{Name: "Groups", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
{Name: "3rd-party logins", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
{Name: "Properties", Visible: false, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Properties", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Is admin", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Is forbidden", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
{Name: "Is deleted", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
@@ -108,6 +108,7 @@ func initBuiltInOrganization() bool {
AccountItems: getBuiltInAccountItems(),
EnableSoftDeletion: false,
IsProfilePublic: false,
UseEmailAsUsername: false,
}
_, err = AddOrganization(organization)
if err != nil {
@@ -409,7 +410,7 @@ func initBuiltInPermission() {
Groups: []string{},
Roles: []string{},
Domains: []string{},
Model: "model-built-in",
Model: "user-model-built-in",
Adapter: "",
ResourceType: "Application",
Resources: []string{"app-built-in"},

View File

@@ -266,7 +266,13 @@ func initDefinedOrganization(organization *Organization) {
}
if existed != nil {
return
affected, err := deleteOrganization(organization)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete organization")
}
}
organization.CreatedTime = util.GetCurrentTime()
organization.AccountItems = getBuiltInAccountItems()
@@ -284,7 +290,13 @@ func initDefinedApplication(application *Application) {
}
if existed != nil {
return
affected, err := deleteApplication(application)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete application")
}
}
application.CreatedTime = util.GetCurrentTime()
_, err = AddApplication(application)
@@ -299,11 +311,19 @@ func initDefinedUser(user *User) {
panic(err)
}
if existed != nil {
return
affected, err := deleteUser(user)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete user")
}
}
user.CreatedTime = util.GetCurrentTime()
user.Id = util.GenerateId()
user.Properties = make(map[string]string)
if user.Properties == nil {
user.Properties = make(map[string]string)
}
_, err = AddUser(user)
if err != nil {
panic(err)
@@ -317,7 +337,13 @@ func initDefinedCert(cert *Cert) {
}
if existed != nil {
return
affected, err := DeleteCert(cert)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete cert")
}
}
cert.CreatedTime = util.GetCurrentTime()
_, err = AddCert(cert)
@@ -333,7 +359,13 @@ func initDefinedLdap(ldap *Ldap) {
}
if existed != nil {
return
affected, err := DeleteLdap(ldap)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete ldap")
}
}
_, err = AddLdap(ldap)
if err != nil {
@@ -348,7 +380,13 @@ func initDefinedProvider(provider *Provider) {
}
if existed != nil {
return
affected, err := DeleteProvider(provider)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete provider")
}
}
_, err = AddProvider(provider)
if err != nil {
@@ -363,7 +401,13 @@ func initDefinedModel(model *Model) {
}
if existed != nil {
return
affected, err := DeleteModel(model)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete provider")
}
}
model.CreatedTime = util.GetCurrentTime()
_, err = AddModel(model)
@@ -379,7 +423,13 @@ func initDefinedPermission(permission *Permission) {
}
if existed != nil {
return
affected, err := deletePermission(permission)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete permission")
}
}
permission.CreatedTime = util.GetCurrentTime()
_, err = AddPermission(permission)
@@ -395,7 +445,13 @@ func initDefinedPayment(payment *Payment) {
}
if existed != nil {
return
affected, err := DeletePayment(payment)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete payment")
}
}
payment.CreatedTime = util.GetCurrentTime()
_, err = AddPayment(payment)
@@ -411,7 +467,13 @@ func initDefinedProduct(product *Product) {
}
if existed != nil {
return
affected, err := DeleteProduct(product)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete product")
}
}
product.CreatedTime = util.GetCurrentTime()
_, err = AddProduct(product)
@@ -427,7 +489,13 @@ func initDefinedResource(resource *Resource) {
}
if existed != nil {
return
affected, err := DeleteResource(resource)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete resource")
}
}
resource.CreatedTime = util.GetCurrentTime()
_, err = AddResource(resource)
@@ -443,7 +511,13 @@ func initDefinedRole(role *Role) {
}
if existed != nil {
return
affected, err := deleteRole(role)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete role")
}
}
role.CreatedTime = util.GetCurrentTime()
_, err = AddRole(role)
@@ -459,7 +533,13 @@ func initDefinedSyncer(syncer *Syncer) {
}
if existed != nil {
return
affected, err := DeleteSyncer(syncer)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete role")
}
}
syncer.CreatedTime = util.GetCurrentTime()
_, err = AddSyncer(syncer)
@@ -475,7 +555,13 @@ func initDefinedToken(token *Token) {
}
if existed != nil {
return
affected, err := DeleteToken(token)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete token")
}
}
token.CreatedTime = util.GetCurrentTime()
_, err = AddToken(token)
@@ -491,7 +577,13 @@ func initDefinedWebhook(webhook *Webhook) {
}
if existed != nil {
return
affected, err := DeleteWebhook(webhook)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete webhook")
}
}
webhook.CreatedTime = util.GetCurrentTime()
_, err = AddWebhook(webhook)
@@ -506,7 +598,13 @@ func initDefinedGroup(group *Group) {
panic(err)
}
if existed != nil {
return
affected, err := deleteGroup(group)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete group")
}
}
group.CreatedTime = util.GetCurrentTime()
_, err = AddGroup(group)
@@ -521,7 +619,13 @@ func initDefinedAdapter(adapter *Adapter) {
panic(err)
}
if existed != nil {
return
affected, err := DeleteAdapter(adapter)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete adapter")
}
}
adapter.CreatedTime = util.GetCurrentTime()
_, err = AddAdapter(adapter)
@@ -536,7 +640,13 @@ func initDefinedEnforcer(enforcer *Enforcer) {
panic(err)
}
if existed != nil {
return
affected, err := DeleteEnforcer(enforcer)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete enforcer")
}
}
enforcer.CreatedTime = util.GetCurrentTime()
_, err = AddEnforcer(enforcer)
@@ -551,7 +661,13 @@ func initDefinedPlan(plan *Plan) {
panic(err)
}
if existed != nil {
return
affected, err := DeletePlan(plan)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete plan")
}
}
plan.CreatedTime = util.GetCurrentTime()
_, err = AddPlan(plan)
@@ -561,12 +677,18 @@ func initDefinedPlan(plan *Plan) {
}
func initDefinedPricing(pricing *Pricing) {
existed, err := getPlan(pricing.Owner, pricing.Name)
existed, err := getPricing(pricing.Owner, pricing.Name)
if err != nil {
panic(err)
}
if existed != nil {
return
affected, err := DeletePricing(pricing)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete pricing")
}
}
pricing.CreatedTime = util.GetCurrentTime()
_, err = AddPricing(pricing)
@@ -581,7 +703,13 @@ func initDefinedInvitation(invitation *Invitation) {
panic(err)
}
if existed != nil {
return
affected, err := DeleteInvitation(invitation)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete invitation")
}
}
invitation.CreatedTime = util.GetCurrentTime()
_, err = AddInvitation(invitation, "en")
@@ -591,6 +719,7 @@ func initDefinedInvitation(invitation *Invitation) {
}
func initDefinedRecord(record *casvisorsdk.Record) {
record.Id = 0
record.CreatedTime = util.GetCurrentTime()
_ = AddRecord(record)
}
@@ -609,7 +738,13 @@ func initDefinedSubscription(subscription *Subscription) {
panic(err)
}
if existed != nil {
return
affected, err := DeleteSubscription(subscription)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete subscription")
}
}
subscription.CreatedTime = util.GetCurrentTime()
_, err = AddSubscription(subscription)
@@ -624,7 +759,13 @@ func initDefinedTransaction(transaction *Transaction) {
panic(err)
}
if existed != nil {
return
affected, err := DeleteTransaction(transaction)
if err != nil {
panic(err)
}
if !affected {
panic("Fail to delete transaction")
}
}
transaction.CreatedTime = util.GetCurrentTime()
_, err = AddTransaction(transaction)

View File

@@ -72,6 +72,7 @@ type Organization struct {
InitScore int `json:"initScore"`
EnableSoftDeletion bool `json:"enableSoftDeletion"`
IsProfilePublic bool `json:"isProfilePublic"`
UseEmailAsUsername bool `json:"useEmailAsUsername"`
MfaItems []*MfaItem `xorm:"varchar(300)" json:"mfaItems"`
AccountItems []*AccountItem `xorm:"varchar(5000)" json:"accountItems"`
@@ -241,11 +242,7 @@ func AddOrganization(organization *Organization) (bool, error) {
return affected != 0, nil
}
func DeleteOrganization(organization *Organization) (bool, error) {
if organization.Name == "built-in" {
return false, nil
}
func deleteOrganization(organization *Organization) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{organization.Owner, organization.Name}).Delete(&Organization{})
if err != nil {
return false, err
@@ -254,6 +251,14 @@ func DeleteOrganization(organization *Organization) (bool, error) {
return affected != 0, nil
}
func DeleteOrganization(organization *Organization) (bool, error) {
if organization.Name == "built-in" {
return false, nil
}
return deleteOrganization(organization)
}
func GetOrganizationByUser(user *User) (*Organization, error) {
if user == nil {
return nil, nil

View File

@@ -39,6 +39,8 @@ type Payment struct {
Currency string `xorm:"varchar(100)" json:"currency"`
Price float64 `json:"price"`
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
IsRecharge bool `xorm:"bool" json:"isRecharge"`
// Payer Info
User string `xorm:"varchar(100)" json:"user"`
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
}
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)
return payment, nil, err
}
if payment.IsRecharge {
err = updateUserBalance(payment.Owner, payment.User, payment.Price)
return payment, notifyResult, err
}
return payment, notifyResult, nil
}

View File

@@ -181,15 +181,15 @@ func UpdatePermission(id string, permission *Permission) (bool, error) {
return false, err
}
if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
isEmpty, _ := ormer.Engine.IsTableEmpty(oldPermission.Adapter)
if isEmpty {
err = ormer.Engine.DropTables(oldPermission.Adapter)
if err != nil {
return false, err
}
}
}
// if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
// isEmpty, _ := ormer.Engine.IsTableEmpty(oldPermission.Adapter)
// if isEmpty {
// err = ormer.Engine.DropTables(oldPermission.Adapter)
// if err != nil {
// return false, err
// }
// }
// }
err = addGroupingPolicies(permission)
if err != nil {
@@ -286,13 +286,22 @@ func AddPermissionsInBatch(permissions []*Permission) (bool, error) {
return affected, nil
}
func DeletePermission(permission *Permission) (bool, error) {
func deletePermission(permission *Permission) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{permission.Owner, permission.Name}).Delete(&Permission{})
if err != nil {
return false, err
}
if affected != 0 {
return affected != 0, nil
}
func DeletePermission(permission *Permission) (bool, error) {
affected, err := deletePermission(permission)
if err != nil {
return false, err
}
if affected {
err = removeGroupingPolicies(permission)
if err != nil {
return false, err
@@ -303,18 +312,18 @@ func DeletePermission(permission *Permission) (bool, error) {
return false, err
}
if permission.Adapter != "" && permission.Adapter != "permission_rule" {
isEmpty, _ := ormer.Engine.IsTableEmpty(permission.Adapter)
if isEmpty {
err = ormer.Engine.DropTables(permission.Adapter)
if err != nil {
return false, err
}
}
}
// if permission.Adapter != "" && permission.Adapter != "permission_rule" {
// isEmpty, _ := ormer.Engine.IsTableEmpty(permission.Adapter)
// if isEmpty {
// err = ormer.Engine.DropTables(permission.Adapter)
// if err != nil {
// return false, err
// }
// }
// }
}
return affected != 0, nil
return affected, nil
}
func getPermissionsByUser(userId string) ([]*Permission, error) {

View File

@@ -133,7 +133,7 @@ func AddPlan(plan *Plan) (bool, error) {
}
func DeletePlan(plan *Plan) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{plan.Owner, plan.Name}).Delete(plan)
affected, err := ormer.Engine.ID(core.PK{plan.Owner, plan.Name}).Delete(Plan{})
if err != nil {
return false, err
}

View File

@@ -140,7 +140,7 @@ func AddPricing(pricing *Pricing) (bool, error) {
}
func DeletePricing(pricing *Pricing) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{pricing.Owner, pricing.Name}).Delete(pricing)
affected, err := ormer.Engine.ID(core.PK{pricing.Owner, pricing.Name}).Delete(Pricing{})
if err != nil {
return false, err
}

View File

@@ -39,6 +39,7 @@ type Product struct {
Price float64 `json:"price"`
Quantity int `json:"quantity"`
Sold int `json:"sold"`
IsRecharge bool `json:"isRecharge"`
Providers []string `xorm:"varchar(255)" json:"providers"`
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
@@ -160,7 +161,7 @@ func (product *Product) getProvider(providerName string) (*Provider, error) {
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)
if err != nil {
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)
}
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)
if err != nil {
return nil, nil, err
@@ -246,6 +255,7 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
Currency: product.Currency,
Price: product.Price,
ReturnUrl: product.ReturnUrl,
IsRecharge: product.IsRecharge,
User: user.Name,
PayUrl: payResp.PayUrl,
@@ -256,6 +266,10 @@ func BuyProduct(id string, user *User, providerName, pricingName, planName, host
if provider.Type == "Dummy" {
payment.State = pp.PaymentStatePaid
err = updateUserBalance(user.Owner, user.Name, payment.Price)
if err != nil {
return nil, nil, err
}
}
affected, err := AddPayment(payment)
@@ -304,8 +318,9 @@ func CreateProductForPlan(plan *Plan) *Product {
Price: plan.Price,
Currency: plan.Currency,
Quantity: 999,
Sold: 0,
Quantity: 999,
Sold: 0,
IsRecharge: false,
Providers: plan.PaymentProviders,
State: "Published",

View File

@@ -50,7 +50,7 @@ type Provider struct {
Host string `xorm:"varchar(100)" json:"host"`
Port int `json:"port"`
DisableSsl bool `json:"disableSsl"` // If the provider type is WeChat, DisableSsl means EnableQRCode
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"`
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"`

View File

@@ -18,13 +18,14 @@ type ProviderItem struct {
Owner string `json:"owner"`
Name string `json:"name"`
CanSignUp bool `json:"canSignUp"`
CanSignIn bool `json:"canSignIn"`
CanUnlink bool `json:"canUnlink"`
Prompted bool `json:"prompted"`
SignupGroup string `json:"signupGroup"`
Rule string `json:"rule"`
Provider *Provider `json:"provider"`
CanSignUp bool `json:"canSignUp"`
CanSignIn bool `json:"canSignIn"`
CanUnlink bool `json:"canUnlink"`
CountryCodes []string `json:"countryCodes"`
Prompted bool `json:"prompted"`
SignupGroup string `json:"signupGroup"`
Rule string `json:"rule"`
Provider *Provider `json:"provider"`
}
func (application *Application) GetProviderItem(providerName string) *ProviderItem {

View File

@@ -17,6 +17,7 @@ package object
import (
"encoding/json"
"fmt"
"regexp"
"strings"
"github.com/beego/beego/context"
@@ -25,10 +26,14 @@ import (
"github.com/casvisor/casvisor-go-sdk/casvisorsdk"
)
var logPostOnly bool
var (
logPostOnly bool
passwordRegex *regexp.Regexp
)
func init() {
logPostOnly = conf.GetConfigBool("logPostOnly")
passwordRegex = regexp.MustCompile("\"password\":\".+\"")
}
type Record struct {
@@ -40,6 +45,10 @@ type Response struct {
Msg string `json:"msg"`
}
func maskPassword(recordString string) string {
return passwordRegex.ReplaceAllString(recordString, "\"password\":\"***\"")
}
func NewRecord(ctx *context.Context) (*casvisorsdk.Record, error) {
ip := strings.Replace(util.GetIPFromRequest(ctx.Request), ": ", "", -1)
action := strings.Replace(ctx.Request.URL.Path, "/api/", "", -1)
@@ -51,6 +60,7 @@ func NewRecord(ctx *context.Context) (*casvisorsdk.Record, error) {
object := ""
if ctx.Input.RequestBody != nil && len(ctx.Input.RequestBody) != 0 {
object = string(ctx.Input.RequestBody)
object = maskPassword(object)
}
respBytes, err := json.Marshal(ctx.Input.Data()["json"])
@@ -80,12 +90,18 @@ func NewRecord(ctx *context.Context) (*casvisorsdk.Record, error) {
Action: action,
Language: languageCode,
Object: object,
StatusCode: 200,
Response: fmt.Sprintf("{status:\"%s\", msg:\"%s\"}", resp.Status, resp.Msg),
IsTriggered: false,
}
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 {
if logPostOnly {
if record.Method == "GET" {
@@ -98,6 +114,7 @@ func AddRecord(record *casvisorsdk.Record) bool {
}
record.Owner = record.Organization
record.Object = maskPassword(record.Object)
errWebhook := SendWebhooks(record)
if errWebhook == nil {
@@ -107,7 +124,7 @@ func AddRecord(record *casvisorsdk.Record) bool {
}
if casvisorsdk.GetClient() == nil {
affected, err := ormer.Engine.Insert(record)
affected, err := addRecord(record)
if err != nil {
panic(err)
}
@@ -212,6 +229,40 @@ func getFilteredWebhooks(webhooks []*Webhook, organization string, action string
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 {
webhooks, err := getWebhooksByOrganization("")
if err != nil {
@@ -236,11 +287,16 @@ func SendWebhooks(record *casvisorsdk.Record) error {
}
}
err = sendWebhook(webhook, record, user)
statusCode, respBody, err := sendWebhook(webhook, record, user)
if err != nil {
errs = append(errs, err)
continue
}
err = addWebhookRecord(webhook, record, statusCode, respBody, err)
if err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {

View File

@@ -238,6 +238,15 @@ func AddRolesInBatch(roles []*Role) bool {
return affected
}
func deleteRole(role *Role) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
if err != nil {
return false, err
}
return affected != 0, nil
}
func DeleteRole(role *Role) (bool, error) {
roleId := role.GetId()
permissions, err := GetPermissionsByRole(roleId)
@@ -253,12 +262,7 @@ func DeleteRole(role *Role) (bool, error) {
}
}
affected, err := ormer.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
if err != nil {
return false, err
}
return affected != 0, nil
return deleteRole(role)
}
func (role *Role) GetId() string {

View File

@@ -155,7 +155,8 @@ func GetMaskedSyncers(syncers []*Syncer, errs ...error) ([]*Syncer, error) {
func UpdateSyncer(id string, syncer *Syncer) (bool, error) {
owner, name := util.GetOwnerAndNameFromId(id)
if s, err := getSyncer(owner, name); err != nil {
s, err := getSyncer(owner, name)
if err != nil {
return false, err
} else if s == 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()
if syncer.Password == "***" {
session.Omit("password")
syncer.Password = s.Password
}
affected, err := session.Update(syncer)
if err != nil {

View File

@@ -142,9 +142,11 @@ func (syncer *Syncer) syncUsers() error {
}
}
_, err = AddUsersInBatch(newUsers)
if err != nil {
return err
if len(newUsers) != 0 {
_, err = AddUsersInBatch(newUsers)
if err != nil {
return err
}
}
if !syncer.IsReadOnly {

View File

@@ -169,6 +169,12 @@ func (syncer *Syncer) setUserByKeyValue(user *User, key string, value string) {
user.TotpSecret = value
case "SignupApplication":
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["TotpSecret"] = user.TotpSecret
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{}
for _, tableColumn := range syncer.TableColumns {

View File

@@ -203,7 +203,8 @@ type User struct {
LastSigninWrongTime string `xorm:"varchar(100)" json:"lastSigninWrongTime"`
SigninWrongTimes int `json:"signinWrongTimes"`
ManagedAccounts []ManagedAccount `xorm:"managedAccounts blob" json:"managedAccounts"`
ManagedAccounts []ManagedAccount `xorm:"managedAccounts blob" json:"managedAccounts"`
NeedUpdatePassword bool `json:"needUpdatePassword"`
}
type Userinfo struct {
@@ -682,11 +683,11 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
"eveonline", "fitbit", "gitea", "heroku", "influxcloud", "instagram", "intercom", "kakao", "lastfm", "mailru", "meetup",
"microsoftonline", "naver", "nextcloud", "onedrive", "oura", "patreon", "paypal", "salesforce", "shopify", "soundcloud",
"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 {
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")
@@ -877,6 +878,7 @@ func AddUsers(users []*User) (bool, error) {
}
}
user.Name = strings.TrimSpace(user.Name)
if isUsernameLowered {
user.Name = strings.ToLower(user.Name)
}
@@ -919,6 +921,15 @@ func AddUsersInBatch(users []*User) (bool, error) {
return affected, nil
}
func deleteUser(user *User) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
if err != nil {
return false, err
}
return affected != 0, nil
}
func DeleteUser(user *User) (bool, error) {
// Forced offline the user first
_, err := DeleteSession(util.GetSessionId(user.Owner, user.Name, CasdoorApplication))
@@ -926,12 +937,7 @@ func DeleteUser(user *User) (bool, error) {
return false, err
}
affected, err := ormer.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
if err != nil {
return false, err
}
return affected != 0, nil
return deleteUser(user)
}
func GetUserInfo(user *User, scope string, aud string, host string) (*Userinfo, error) {
@@ -1003,7 +1009,7 @@ func (user *User) GetFriendlyName() string {
}
func isUserIdGlobalAdmin(userId string) bool {
return strings.HasPrefix(userId, "built-in/") || strings.HasPrefix(userId, "app/")
return strings.HasPrefix(userId, "built-in/") || IsAppUser(userId)
}
func ExtendUserWithRolesAndPermissions(user *User) (err error) {
@@ -1151,3 +1157,13 @@ func GenerateIdForNewUser(application *Application) (string, error) {
res := strconv.Itoa(lastUserId + 1)
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
}

View File

@@ -21,12 +21,11 @@ import (
"regexp"
"strings"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/i18n"
jsoniter "github.com/json-iterator/go"
"github.com/casdoor/casdoor/idp"
"github.com/casdoor/casdoor/util"
jsoniter "github.com/json-iterator/go"
"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) {
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
if isUsernameLowered {
field = strings.ToLower(field)
}
field = strings.TrimSpace(field)
// check username
user, err := GetUserByField(organization, "name", field)
if err != nil || user != nil {
@@ -405,6 +411,15 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, lang str
item := GetAccountItemByName("Is deleted", organization)
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 {
item := GetAccountItemByName("Score", organization)
@@ -464,3 +479,10 @@ func (user *User) IsAdminUser() bool {
return user.IsAdmin || user.IsGlobalAdmin()
}
func IsAppUser(userId string) bool {
if strings.HasPrefix(userId, "app/") {
return true
}
return false
}

View File

@@ -15,6 +15,7 @@
package object
import (
"io"
"net/http"
"strings"
@@ -22,7 +23,7 @@ import (
"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{}
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)
if err != nil {
return err
return 0, "", err
}
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)
}
_, err = client.Do(req)
return err
resp, err := client.Do(req)
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
}

View File

@@ -35,20 +35,13 @@ type Object struct {
}
func getUsername(ctx *context.Context) (username string) {
defer func() {
if r := recover(); r != nil {
username, _ = getUsernameByClientIdSecret(ctx)
}
}()
username = ctx.Input.Session("username").(string)
if username == "" {
username, ok := ctx.Input.Session("username").(string)
if !ok || username == "" {
username, _ = getUsernameByClientIdSecret(ctx)
}
if username == "" {
username = getUsernameByKeys(ctx)
username, _ = getUsernameByKeys(ctx)
}
return
}

View File

@@ -91,17 +91,22 @@ func getUsernameByClientIdSecret(ctx *context.Context) (string, error) {
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)
user, err := object.GetUserByAccessKey(accessKey)
if err != nil {
panic(err)
return "", err
}
if user != nil && accessSecret == user.AccessSecret {
return user.GetId()
if user == nil {
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 {

View File

@@ -59,7 +59,7 @@ func fastAutoSignin(ctx *context.Context) (string, error) {
scope := ctx.Input.Query("scope")
state := ctx.Input.Query("state")
nonce := ""
codeChallenge := ""
codeChallenge := ctx.Input.Query("code_challenge")
if clientId == "" || responseType != "code" || redirectUri == "" {
return "", nil
}

View File

@@ -414,6 +414,7 @@ class App extends Component {
<Layout id="parent-area">
<ManagementPage
account={this.state.account}
application={this.state.application}
uri={this.state.uri}
themeData={this.state.themeData}
themeAlgorithm={this.state.themeAlgorithm}

View File

@@ -22,6 +22,7 @@ import * as ApplicationBackend from "./backend/ApplicationBackend";
import i18next from "i18next";
import BaseListPage from "./BaseListPage";
import PopconfirmModal from "./common/modal/PopconfirmModal";
import {SignupTableDefaultCssMap} from "./table/SignupTable";
class ApplicationListPage extends BaseListPage {
constructor(props) {
@@ -61,6 +62,8 @@ class ApplicationListPage extends BaseListPage {
{name: "Email", visible: true, required: true, rule: "Normal"},
{name: "Phone", visible: true, required: true, rule: "None"},
{name: "Agreement", visible: true, required: true, rule: "None"},
{name: "Signup button", visible: true, required: true, rule: "None"},
{name: "Providers", visible: true, required: true, rule: "None", customCss: SignupTableDefaultCssMap["Providers"]},
],
grantTypes: ["authorization_code", "password", "client_credentials", "token", "id_token", "refresh_token"],
cert: "cert-built-in",

View File

@@ -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="/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="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...this.props} 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" render={(props) => <SelfForgetPage {...this.props} account={this.props.account} 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/: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} />)} />

View File

@@ -328,6 +328,8 @@ function ManagementPage(props) {
return <Redirect to="/login" />;
} else if (props.account === undefined) {
return null;
} else if (props.account.needUpdatePassword) {
return <Redirect to={"/forget/" + props.application.name} />;
} else {
return component;
}
@@ -409,7 +411,7 @@ function ManagementPage(props) {
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 = () => {
setMenuVisible(false);

View File

@@ -436,6 +436,16 @@ class OrganizationEditPage extends React.Component {
}} />
</Col>
</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()) ? 22 : 2}>
{Setting.getLabel(i18next.t("organization:Account items"), i18next.t("organization:Account items - Tooltip"))} :

View File

@@ -17,6 +17,7 @@ import {Button, Result, Spin} from "antd";
import * as PaymentBackend from "./backend/PaymentBackend";
import * as PricingBackend from "./backend/PricingBackend";
import * as SubscriptionBackend from "./backend/SubscriptionBackend";
import * as UserBackend from "./backend/UserBackend";
import * as Setting from "./Setting";
import i18next from "i18next";
@@ -34,6 +35,7 @@ class PaymentResultPage extends React.Component {
pricing: props.pricing ?? null,
subscription: props.subscription ?? null,
timeout: null,
user: null,
};
}
@@ -41,6 +43,25 @@ class PaymentResultPage extends React.Component {
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() {
if (this.state.timeout !== null) {
clearTimeout(this.state.timeout);
@@ -114,6 +135,12 @@ class PaymentResultPage extends React.Component {
});
}
}
if (payment.state === "Paid") {
if (this.props.account) {
this.getUser();
}
}
} catch (err) {
Setting.showMessage("error", err.message);
return;
@@ -136,6 +163,27 @@ class PaymentResultPage extends React.Component {
}
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 (
<div className="login-content">
{

View File

@@ -487,6 +487,7 @@ class PermissionEditPage extends React.Component {
if (res.status === "ok") {
Setting.showMessage("success", i18next.t("general:Successfully saved"));
this.setState({
organizationName: this.state.permission.owner,
permissionName: this.state.permission.name,
});

View File

@@ -13,7 +13,7 @@
// limitations under the License.
import React from "react";
import {Button, Descriptions, Spin} from "antd";
import {Button, Descriptions, InputNumber, Space, Spin} from "antd";
import i18next from "i18next";
import * as ProductBackend from "./backend/ProductBackend";
import * as PlanBackend from "./backend/PlanBackend";
@@ -36,6 +36,7 @@ class ProductBuyPage extends React.Component {
pricing: props?.pricing ?? null,
plan: null,
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) {
return `${this.getCurrencySymbol(product)}${product?.price} (${this.getCurrencyText(product)})`;
return `${this.getCurrencySymbol(product)}${product?.price} (${Setting.getCurrencyText(product)})`;
}
// Call Weechat Pay via jsapi
@@ -192,7 +183,7 @@ class ProductBuyPage extends React.Component {
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) => {
if (res.status === "ok") {
const payment = res.data;
@@ -295,15 +286,27 @@ class ProductBuyPage extends React.Component {
<Descriptions.Item label={i18next.t("product:Image")} span={3}>
<img src={product?.image} alt={product?.name} height={90} style={{marginBottom: "20px"}} />
</Descriptions.Item>
<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>
{
product.isRecharge ? (
<Descriptions.Item span={3} label={i18next.t("product:Price")}>
<Space>
<InputNumber min={0} value={this.state.customPrice} onChange={(e) => {this.setState({customPrice: e});}} /> {Setting.getCurrencyText(product)}
</Space>
</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}>
{
this.renderPay(product)

View File

@@ -13,7 +13,7 @@
// limitations under the License.
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 Setting from "./Setting";
import i18next from "i18next";
@@ -41,7 +41,7 @@ class ProductEditPage extends React.Component {
UNSAFE_componentWillMount() {
this.getProduct();
this.getOrganizations();
this.getPaymentProviders();
this.getPaymentProviders(this.state.organizationName);
}
getProduct() {
@@ -67,8 +67,8 @@ class ProductEditPage extends React.Component {
});
}
getPaymentProviders() {
ProviderBackend.getProviders(this.props.account.owner)
getPaymentProviders(organizationName) {
ProviderBackend.getProviders(organizationName)
.then((res) => {
if (res.status === "ok") {
this.setState({
@@ -216,14 +216,27 @@ class ProductEditPage extends React.Component {
</Row>
<Row style={{marginTop: "20px"}} >
<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 span={22} >
<InputNumber value={this.state.product.price} disabled={isCreatedByPlan} onChange={value => {
this.updateProductField("price", value);
<Switch checked={this.state.product.isRecharge} onChange={value => {
this.updateProductField("isRecharge", value);
}} />
</Col>
</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"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("product:Quantity"), i18next.t("product:Quantity - Tooltip"))} :

View File

@@ -38,6 +38,7 @@ class ProductListPage extends BaseListPage {
price: 300,
quantity: 99,
sold: 10,
isRecharge: false,
providers: [],
state: "Published",
};

View File

@@ -828,6 +828,20 @@ class ProviderEditPage extends React.Component {
</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 : (
<Row style={{marginTop: "20px"}} >

View File

@@ -151,6 +151,14 @@ class RecordListPage extends BaseListPage {
sorter: true,
...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"),
dataIndex: "response",

View File

@@ -1463,7 +1463,7 @@ export function getUserCommonFields() {
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",
"Language", "Gender", "Birthday", "Education", "Score", "Ranking", "IsDefaultAvatar", "IsOnline", "IsAdmin", "IsForbidden", "IsDeleted", "CreatedIp",
"PreferredMfaType", "TotpSecret", "SignupApplication"];
"PreferredMfaType", "TotpSecret", "SignupApplication", "RecoveryCodes", "MfaPhoneEnabled", "MfaEmailEnabled"];
}
export function getDefaultFooterContent() {
@@ -1516,3 +1516,13 @@ export function getDefaultHtmlEmailContent() {
</body>
</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)";
}
}

View File

@@ -202,7 +202,7 @@ class UserEditPage extends React.Component {
return value;
}
updateUserField(key, value) {
updateUserField(key, value, idx) {
if (this.props.account === null) {
return;
}
@@ -210,7 +210,15 @@ class UserEditPage extends React.Component {
value = this.parseUserField(key, value);
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({
user: user,
});
@@ -501,16 +509,33 @@ class UserEditPage extends React.Component {
);
} else if (accountItem.name === "Address") {
return (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("user:Address"), i18next.t("user:Address - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.user.address} onChange={e => {
this.updateUserField("address", e.target.value);
}} />
</Col>
</Row>
<React.Fragment>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("user:Address"), i18next.t("user:Address - Tooltip"))} :
</Col>
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
<span>{i18next.t("user:Address line") + " 1"}</span> :
</Col>
<Col span={20} >
<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") {
return (
@@ -682,6 +707,19 @@ class UserEditPage extends React.Component {
</Col>
</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") {
return (
<Row style={{marginTop: "20px"}} >
@@ -1001,6 +1039,19 @@ class UserEditPage extends React.Component {
</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>
);
}
}

View File

@@ -153,21 +153,37 @@ class AuthCallback extends React.Component {
// OAuth
const oAuthParams = Util.getOAuthGetParameters(innerParams);
const concatChar = oAuthParams?.redirectUri?.includes("?") ? "&" : "?";
const signinUrl = localStorage.getItem("signinUrl");
AuthBackend.login(body, oAuthParams)
.then((res) => {
if (res.status === "ok") {
const responseType = this.getResponseType();
if (responseType === "login") {
if (res.data2) {
sessionStorage.setItem("signinUrl", signinUrl);
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
return;
}
Setting.showMessage("success", "Logged in successfully");
// Setting.goToLinkSoft(this, "/");
const link = Setting.getFromLink();
Setting.goToLink(link);
} else if (responseType === "code") {
if (res.data2) {
sessionStorage.setItem("signinUrl", signinUrl);
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
return;
}
const code = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
// Setting.showMessage("success", `Authorization code: ${res.data}`);
} else if (responseType === "token" || responseType === "id_token") {
if (res.data2) {
sessionStorage.setItem("signinUrl", signinUrl);
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
return;
}
const token = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
} else if (responseType === "link") {
@@ -181,6 +197,11 @@ class AuthCallback extends React.Component {
relayState: oAuthParams.relayState,
});
} else {
if (res.data2.needUpdatePassword) {
sessionStorage.setItem("signinUrl", signinUrl);
Setting.goToLinkSoft(this, `/forget/${applicationName}`);
return;
}
const SAMLResponse = res.data;
const redirectUri = res.data2.redirectUrl;
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);

View File

@@ -35,8 +35,8 @@ class ForgetPage extends React.Component {
classes: props,
applicationName: props.applicationName ?? props.match.params?.applicationName,
msg: null,
name: "",
username: "",
name: props.account ? props.account.name : "",
username: props.account ? props.account.name : "",
phone: "",
email: "",
dest: "",
@@ -44,7 +44,6 @@ class ForgetPage extends React.Component {
verifyType: "", // "email", "phone"
current: 0,
};
this.form = React.createRef();
}
@@ -205,6 +204,7 @@ class ForgetPage extends React.Component {
initialValues={{
application: application.name,
organization: application.organization,
username: this.state.name,
}}
style={{width: "300px"}}
size="large"
@@ -488,7 +488,7 @@ class ForgetPage extends React.Component {
<Row>
<Col span={24}>
<div style={{textAlign: "center", fontSize: "28px"}}>
{i18next.t("forget:Retrieve password")}
{i18next.t("forget:Reset password")}
</div>
</Col>
</Row>

View File

@@ -68,6 +68,8 @@ class LoginPage extends React.Component {
this.state.applicationName = props.match?.params?.casApplicationName;
}
localStorage.setItem("signinUrl", window.location.href);
this.form = React.createRef();
}
@@ -300,6 +302,12 @@ class LoginPage extends React.Component {
return;
}
if (resp.data2) {
sessionStorage.setItem("signinUrl", window.location.href);
Setting.goToLinkSoft(ths, `/forget/${application.name}`);
return;
}
if (Setting.hasPromptPage(application)) {
AuthBackend.getAccount()
.then((res) => {
@@ -442,15 +450,27 @@ class LoginPage extends React.Component {
const responseType = values["type"];
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"));
this.props.onLoginSuccess();
} else if (responseType === "code") {
this.postCodeLoginAction(res);
} 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 accessToken = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}#${amendatoryResponseType}=${accessToken}&state=${oAuthParams.state}&token_type=bearer`);
} 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") {
this.setState({
samlResponse: res.data,
@@ -532,7 +552,7 @@ class LoginPage extends React.Component {
if (signinItem.name === "Logo") {
return (
<div className="login-logo-box">
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{
Setting.renderHelmet(application)
}
@@ -543,8 +563,8 @@ class LoginPage extends React.Component {
);
} else if (signinItem.name === "Back button") {
return (
<div>
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div className="back-button">
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{
this.renderBackButton()
}
@@ -562,24 +582,26 @@ class LoginPage extends React.Component {
return (
<div className="login-languages">
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<LanguageSelect languages={application.organizationObj.languages} />
</div>
);
} else if (signinItem.name === "Signin methods") {
return (
<div>
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{this.renderMethodChoiceBox()}
</div>
)
;
} else if (signinItem.name === "Username") {
return (
<div className="login-username">
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div>
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<Form.Item
name="username"
className="login-username"
label={signinItem.label ? signinItem.label : null}
rules={[
{
required: true,
@@ -637,6 +659,7 @@ class LoginPage extends React.Component {
<Input
id="input"
className="login-username-input"
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder={this.getPlaceholder()}
onChange={e => {
@@ -651,14 +674,14 @@ class LoginPage extends React.Component {
} else if (signinItem.name === "Password") {
return (
<div>
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
{this.renderPasswordOrCodeInput()}
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{this.renderPasswordOrCodeInput(signinItem)}
</div>
);
} else if (signinItem.name === "Forgot password?") {
return (
<div>
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<div className="login-forget-password">
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
<Checkbox style={{float: "left"}}>
@@ -666,7 +689,7 @@ class LoginPage extends React.Component {
</Checkbox>
</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>
@@ -676,7 +699,7 @@ class LoginPage extends React.Component {
} else if (signinItem.name === "Login button") {
return (
<Form.Item className="login-button-box">
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<Button
type="primary"
htmlType="submit"
@@ -685,7 +708,7 @@ class LoginPage extends React.Component {
{
this.state.loginMethod === "webAuthn" ? i18next.t("login:Sign in with WebAuthn") :
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>
{
@@ -720,7 +743,7 @@ class LoginPage extends React.Component {
return (
<div>
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
<Form.Item>
{
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
@@ -735,13 +758,13 @@ class LoginPage extends React.Component {
);
} else if (signinItem.name.startsWith("Text ") || signinItem?.isCustom) {
return (
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
<div dangerouslySetInnerHTML={{__html: signinItem.customCss}} />
);
} else if (signinItem.name === "Signup link") {
return (
<div style={{width: "100%"}} className="login-signup-link">
<div dangerouslySetInnerHTML={{__html: signinItem.label}} />
{this.renderFooter(application)}
<div dangerouslySetInnerHTML={{__html: ("<style>" + signinItem.customCss?.replaceAll("<style>", "").replaceAll("</style>", "") + "</style>")}} />
{this.renderFooter(application, signinItem)}
</div>
);
}
@@ -838,7 +861,7 @@ class LoginPage extends React.Component {
{application.displayName}
</span>
</a>
:
:
</div>
<br />
{
@@ -894,17 +917,20 @@ class LoginPage extends React.Component {
/>;
}
renderFooter(application) {
renderFooter(application, signinItem) {
return (
<div>
{
!application.enableSignUp ? null : (
<React.Fragment>
{i18next.t("login:No account?")}&nbsp;
{
Setting.renderSignupLink(application, i18next.t("login:sign up now"))
}
</React.Fragment>
signinItem.label ? Setting.renderSignupLink(application, signinItem.label) :
(
<React.Fragment>
{i18next.t("login:No account?")}
{
Setting.renderSignupLink(application, i18next.t("login:sign up now"))
}
</React.Fragment>
)
)
}
</div>
@@ -1020,17 +1046,20 @@ class LoginPage extends React.Component {
});
}
renderPasswordOrCodeInput() {
renderPasswordOrCodeInput(signinItem) {
const application = this.getApplicationObj();
if (this.state.loginMethod === "password" || this.state.loginMethod === "ldap") {
return (
<Col span={24}>
<div className="login-password">
<div>
<Form.Item
name="password"
className="login-password"
label={signinItem.label ? signinItem.label : null}
rules={[{required: true, message: i18next.t("login:Please input your password!")}]}
>
<Input.Password
className="login-password-input"
prefix={<LockOutlined className="site-form-item-icon" />}
type="password"
placeholder={i18next.t("general:Password")}
@@ -1195,8 +1224,7 @@ class LoginPage extends React.Component {
renderBackButton() {
if (this.state.orgChoiceMode === "None" || this.props.preview === "auto") {
return (
<Button type="text" size="large" icon={<ArrowLeftOutlined />}
className="back-button"
<Button className="back-inner-button" type="text" size="large" icon={<ArrowLeftOutlined />}
onClick={() => history.back()}>
</Button>
);

View File

@@ -384,8 +384,7 @@ export function getAuthUrl(application, provider, method, code) {
let endpoint = authInfo[provider.type].endpoint;
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 state = Util.getStateFromQueryParams(application.name, provider.name, method, isShortState);
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") {
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 === "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"
@@ -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 === "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}`;
} 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") {
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") {

View File

@@ -172,23 +172,23 @@ export function renderProviderLogo(provider, application, width, margin, size, l
const customAStyle = {display: "block", height: "55px", color: "#000"};
const customButtonStyle = {display: "flex", alignItems: "center", width: "calc(100% - 10px)", height: "50px", margin: "5px", padding: "0 10px", backgroundColor: "transparent", boxShadow: "0px 1px 3px rgba(0,0,0,0.5)", border: "0px", borderRadius: "3px", cursor: "pointer"};
const customImgStyle = {justfyContent: "space-between"};
const customSpanStyle = {textAlign: "center", lineHeight: "50px", width: "100%", fontSize: "19px"};
const customSpanStyle = {textAlign: "center", width: "100%", fontSize: "19px"};
if (provider.category === "OAuth") {
return (
<a key={provider.displayName} href={Provider.getAuthUrl(application, provider, "signup")} style={customAStyle}>
<button style={customButtonStyle}>
<div style={customButtonStyle}>
<img width={26} src={getProviderLogoURL(provider)} alt={provider.displayName} className="provider-img" style={customImgStyle} />
<span style={customSpanStyle}>{text}</span>
</button>
</div>
</a>
);
} else if (provider.category === "SAML") {
return (
<a key={provider.displayName} onClick={() => goToSamlUrl(provider, location)} style={customAStyle}>
<button style={customButtonStyle}>
<div style={customButtonStyle}>
<img width={26} src={getProviderLogoURL(provider)} alt={provider.displayName} className="provider-img" style={customImgStyle} />
<span style={customSpanStyle}>{text}</span>
</button>
</div>
</a>
);
}

View File

@@ -248,6 +248,7 @@ class SignupPage extends React.Component {
return (
<Form.Item
name="username"
className="signup-username"
label={signupItem.label ? signupItem.label : i18next.t("signup:Username")}
rules={[
{
@@ -257,7 +258,8 @@ class SignupPage extends React.Component {
},
]}
>
<Input placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation.username !== ""} />
<Input className="signup-username-input" placeholder={signupItem.placeholder}
disabled={this.state.invitation !== undefined && this.state.invitation.username !== ""} />
</Form.Item>
);
} else if (signupItem.name === "Display name") {
@@ -266,6 +268,7 @@ class SignupPage extends React.Component {
<React.Fragment>
<Form.Item
name="firstName"
className="signup-first-name"
label={signupItem.label ? signupItem.label : i18next.t("general:First name")}
rules={[
{
@@ -275,10 +278,11 @@ class SignupPage extends React.Component {
},
]}
>
<Input placeholder={signupItem.placeholder} />
<Input className="signup-first-name-input" placeholder={signupItem.placeholder} />
</Form.Item>
<Form.Item
name="lastName"
className="signup-last-name"
label={signupItem.label ? signupItem.label : i18next.t("general:Last name")}
rules={[
{
@@ -288,7 +292,7 @@ class SignupPage extends React.Component {
},
]}
>
<Input placeholder={signupItem.placeholder} />
<Input className="signup-last-name-input" placeholder={signupItem.placeholder} />
</Form.Item>
</React.Fragment>
);
@@ -297,6 +301,7 @@ class SignupPage extends React.Component {
return (
<Form.Item
name="name"
className="signup-name"
label={(signupItem.label ? signupItem.label : (signupItem.rule === "Real name" || signupItem.rule === "First, last") ? i18next.t("general:Real name") : i18next.t("general:Display name"))}
rules={[
{
@@ -306,13 +311,14 @@ class SignupPage extends React.Component {
},
]}
>
<Input placeholder={signupItem.placeholder} />
<Input className="signup-name-input" placeholder={signupItem.placeholder} />
</Form.Item>
);
} else if (signupItem.name === "Affiliation") {
return (
<Form.Item
name="affiliation"
className="signup-affiliation"
label={signupItem.label ? signupItem.label : i18next.t("user:Affiliation")}
rules={[
{
@@ -322,13 +328,14 @@ class SignupPage extends React.Component {
},
]}
>
<Input placeholder={signupItem.placeholder} />
<Input className="signup-affiliation-input" placeholder={signupItem.placeholder} />
</Form.Item>
);
} else if (signupItem.name === "ID card") {
return (
<Form.Item
name="idCard"
className="signup-idcard"
label={signupItem.label ? signupItem.label : i18next.t("user:ID card")}
rules={[
{
@@ -343,13 +350,14 @@ class SignupPage extends React.Component {
},
]}
>
<Input placeholder={signupItem.placeholder} />
<Input className="signup-idcard-input" placeholder={signupItem.placeholder} />
</Form.Item>
);
} else if (signupItem.name === "Country/Region") {
return (
<Form.Item
name="country_region"
className="signup-country-region"
label={signupItem.label ? signupItem.label : i18next.t("user:Country/Region")}
rules={[
{
@@ -358,7 +366,7 @@ class SignupPage extends React.Component {
},
]}
>
<RegionSelect onChange={(value) => {this.setState({region: value});}} />
<RegionSelect className="signup-region-select" onChange={(value) => {this.setState({region: value});}} />
</Form.Item>
);
} else if (signupItem.name === "Email" || signupItem.name === "Phone" || signupItem.name === "Email or Phone" || signupItem.name === "Phone or Email") {
@@ -367,6 +375,7 @@ class SignupPage extends React.Component {
<React.Fragment>
<Form.Item
name="email"
className="signup-email"
label={signupItem.label ? signupItem.label : i18next.t("general:Email")}
rules={[
{
@@ -380,18 +389,27 @@ class SignupPage extends React.Component {
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});
return Promise.resolve();
},
},
]}
>
<Input placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation.email !== ""} onChange={e => this.setState({email: e.target.value})} />
<Input className="signup-email-input" placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation.email !== ""} onChange={e => this.setState({email: e.target.value})} />
</Form.Item>
{
signupItem.rule !== "No verification" &&
<Form.Item
name="emailCode"
className="signup-email-code"
label={signupItem.label ? signupItem.label : i18next.t("code:Email code")}
rules={[{
required: required,
@@ -399,6 +417,7 @@ class SignupPage extends React.Component {
}]}
>
<SendCodeInput
className="signup-email-code-input"
disabled={!this.state.validEmail}
method={"signup"}
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationName(application)]}
@@ -413,7 +432,7 @@ class SignupPage extends React.Component {
const renderPhoneItem = () => {
return (
<React.Fragment>
<Form.Item label={signupItem.label ? signupItem.label : i18next.t("general:Phone")} required={required}>
<Form.Item className="signup-phone" label={signupItem.label ? signupItem.label : i18next.t("general:Phone")} required={required}>
<Input.Group compact>
<Form.Item
name="countryCode"
@@ -457,6 +476,7 @@ class SignupPage extends React.Component {
]}
>
<Input
className="signup-phone-input"
placeholder={signupItem.placeholder}
style={{width: "65%"}}
disabled={this.state.invitation !== undefined && this.state.invitation.phone !== ""}
@@ -469,6 +489,7 @@ class SignupPage extends React.Component {
signupItem.rule !== "No verification" &&
<Form.Item
name="phoneCode"
className="phone-code"
label={signupItem.label ? signupItem.label : i18next.t("code:Phone code")}
rules={[
{
@@ -478,6 +499,7 @@ class SignupPage extends React.Component {
]}
>
<SendCodeInput
className="signup-phone-code-input"
disabled={!this.state.validPhone}
method={"signup"}
onButtonClickArgs={[this.state.phone, "phone", Setting.getApplicationName(application)]}
@@ -535,6 +557,7 @@ class SignupPage extends React.Component {
return (
<Form.Item
name="password"
className="signup-password"
label={signupItem.label ? signupItem.label : i18next.t("general:Password")}
rules={[
{
@@ -552,13 +575,14 @@ class SignupPage extends React.Component {
]}
hasFeedback
>
<Input.Password placeholder={signupItem.placeholder} />
<Input.Password className="signup-password-input" placeholder={signupItem.placeholder} />
</Form.Item>
);
} else if (signupItem.name === "Confirm password") {
return (
<Form.Item
name="confirm"
className="signup-confirm"
label={signupItem.label ? signupItem.label : i18next.t("signup:Confirm")}
dependencies={["password"]}
hasFeedback
@@ -585,6 +609,7 @@ class SignupPage extends React.Component {
return (
<Form.Item
name="invitationCode"
className="signup-invitation-code"
label={signupItem.label ? signupItem.label : i18next.t("application:Invitation code")}
rules={[
{
@@ -593,7 +618,7 @@ class SignupPage extends React.Component {
},
]}
>
<Input placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation !== ""} />
<Input className="signup-invitation-code-input" placeholder={signupItem.placeholder} disabled={this.state.invitation !== undefined && this.state.invitation !== ""} />
</Form.Item>
);
} else if (signupItem.name === "Agreement") {
@@ -602,6 +627,37 @@ class SignupPage extends React.Component {
return (
<div dangerouslySetInnerHTML={{__html: signupItem.label}} />
);
} else if (signupItem.name === "Signup button") {
return (
<Form.Item {...tailFormItemLayout}>
<Button type="primary" htmlType="submit" className="signup-button">
{i18next.t("account:Sign Up")}
</Button>
&nbsp;&nbsp;{i18next.t("signup:Have account?")}&nbsp;
<a className="signup-link" onClick={() => {
const linkInStorage = sessionStorage.getItem("signinUrl");
if (linkInStorage !== null && linkInStorage !== "") {
Setting.goToLinkSoft(this, linkInStorage);
} else {
Setting.redirectToLoginPage(application, this.props.history);
}
}}>
{i18next.t("signup:sign in now")}
</a>
</Form.Item>
);
} else if (signupItem.name === "Providers") {
const showForm = Setting.isPasswordEnabled(application) || Setting.isCodeSigninEnabled(application) || Setting.isWebAuthnEnabled(application) || Setting.isLdapEnabled(application);
if (signupItem.rule === "None" || signupItem.rule === "") {
signupItem.rule = showForm ? "small" : "big";
}
return (
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
return ProviderButton.renderProviderLogo(providerItem.provider, application, null, null, signupItem.rule, this.props.location);
})
);
}
}
@@ -676,27 +732,13 @@ class SignupPage extends React.Component {
>
</Form.Item>
{
application.signupItems?.map(signupItem => this.renderFormItem(application, signupItem))
}
<Form.Item {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">
{i18next.t("account:Sign Up")}
</Button>
&nbsp;&nbsp;{i18next.t("signup:Have account?")}&nbsp;
<a onClick={() => {
const linkInStorage = sessionStorage.getItem("signinUrl");
if (linkInStorage !== null && linkInStorage !== "") {
Setting.goToLinkSoft(this, linkInStorage);
} else {
Setting.redirectToLoginPage(application, this.props.history);
}
}}>
{i18next.t("signup:sign in now")}
</a>
</Form.Item>
{
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small", this.props.location);
application.signupItems?.map((signupItem, idx) => {
return (
<div key={idx}>
<div dangerouslySetInnerHTML={{__html: ("<style>" + signupItem.customCss + "</style>")}} />
{this.renderFormItem(application, signupItem)}
</div>
);
})
}
</Form>
@@ -709,6 +751,20 @@ class SignupPage extends React.Component {
return null;
}
let existSignupButton = false;
application.signupItems?.map(item => {
item.name === "Signup button" ? existSignupButton = true : null;
});
if (!existSignupButton) {
application.signupItems?.push({
customCss: "",
label: "",
name: "Signup button",
placeholder: "",
visible: true,
});
}
if (application.signupHtml !== "") {
return (
<div dangerouslySetInnerHTML={{__html: application.signupHtml}} />

View File

@@ -70,8 +70,8 @@ export function deleteProduct(product) {
}).then(res => res.json());
}
export function buyProduct(owner, name, providerName, pricingName = "", planName = "", userName = "", paymentEnv = "") {
return fetch(`${Setting.ServerUrl}/api/buy-product?id=${owner}/${encodeURIComponent(name)}&providerName=${providerName}&pricingName=${pricingName}&planName=${planName}&userName=${userName}&paymentEnv=${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}&customPrice=${customPrice}`, {
method: "POST",
credentials: "include",
headers: {

View File

@@ -50,6 +50,7 @@ function testEmailProvider(provider, email = "") {
sender: provider.displayName,
receivers: email === "" ? ["TestSmtpServer"] : [email],
provider: provider.name,
providerObject: provider,
};
return fetch(`${Setting.ServerUrl}/api/send-email`, {

View File

@@ -13,11 +13,14 @@
// limitations under the License.
import {Select} from "antd";
import i18next from "i18next";
import * as Setting from "../../Setting";
import React from "react";
const {Option} = Select;
export const CountryCodeSelect = (props) => {
const {onChange, style, disabled, initValue} = props;
const {onChange, style, disabled, initValue, mode} = props;
const countryCodes = props.countryCodes ?? [];
const [value, setValue] = React.useState("");
@@ -42,11 +45,19 @@ export const CountryCodeSelect = (props) => {
style={style}
disabled={disabled}
value={value}
mode={mode}
dropdownMatchSelectWidth={false}
optionLabelProp={"label"}
onChange={handleOnChange}
filterOption={(input, option) => (option?.text ?? "").toLowerCase().includes(input.toLowerCase())}
>
{
props.hasDefault ? (<Option key={"All"} value={"All"} label={i18next.t("organization:All")} text={"organization:All"} >
<div style={{display: "flex", justifyContent: "space-between", marginRight: "10px"}}>
{i18next.t("organization:All")}
</div>
</Option>) : null
}
{
Setting.getCountryCodeData(countryCodes).map((country) => Setting.getCountryCodeOption(country))
}

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Bitte geben Sie Ihre Anwendung ein!",
"Please input your organization!": "Bitte geben Sie Ihre Organisation ein!",
"Please select a HTML file": "Bitte wählen Sie eine HTML-Datei aus",
@@ -165,7 +166,7 @@
"Next Step": "Nächster Schritt",
"Please input your username!": "Bitte gib deinen Benutzernamen ein!",
"Reset": "Zurücksetzen",
"Retrieve password": "Passwort abrufen",
"Reset password": "Passwort abrufen",
"Unknown forget type": "Unbekannter Vergesslichkeitstyp",
"Verify": "überprüfen"
},
@@ -229,6 +230,7 @@
"Email": "E-Mail",
"Email - Tooltip": "Gültige E-Mail-Adresse",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Telefon",
"Phone - Tooltip": "Telefonnummer",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Pläne",
@@ -391,6 +394,7 @@
"User type": "Benutzertyp",
"User type - Tooltip": "Tags, denen der Benutzer angehört, standardmäßig auf \"normaler Benutzer\" festgelegt",
"Users": "Benutzer",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Benutzer unter allen Organisationen",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Laden",
"Logging out...": "Ausloggen...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "Kein Konto?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Melden Sie sich mit WebAuthn an",
"Sign in with {type}": "Melden Sie sich mit {type} an",
"Signin button": "Signin button",
"Signing in...": "Anmelden...",
"Successfully logged in with WebAuthn credentials": "Erfolgreich mit WebAuthn-Anmeldeinformationen angemeldet",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Sichtbar",
"Website URL": "Website-URL",
@@ -615,6 +621,7 @@
"Processing...": "In Bearbeitung...",
"Product": "Produkt",
"Product - Tooltip": "Produktname",
"Recharged successfully": "Recharged successfully",
"Result": "Ergebnis",
"Return to Website": "Zurück zur Website",
"The payment has been canceled": "The payment has been canceled",
@@ -623,6 +630,8 @@
"The payment is still under processing": "Die Zahlung wird immer noch bearbeitet",
"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 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...",
"the current state is": "der aktuelle Zustand ist"
},
@@ -685,6 +694,8 @@
"Edit Product": "Produkt bearbeiten",
"Image": "Bild",
"Image - Tooltip": "Bild des Produkts",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "Neues Produkt",
"Pay": "Zahlen",
"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": "Name des Hosts",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"resource": {
"Copy Link": "Kopiere den Link",
@@ -941,6 +955,7 @@
"Please select your country code!": "Bitte wählen Sie Ihren Ländercode aus!",
"Please select your country/region!": "Bitte wählen Sie Ihr Land/Ihre Region aus!",
"Regex": "Regex",
"Signup button": "Signup button",
"Terms of Use": "Nutzungsbedingungen",
"Terms of Use - Tooltip": "Nutzungsbedingungen, die Benutzer während der Registrierung lesen und akzeptieren müssen",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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 title!": "Der Eingabewert ist nicht die Rechnungsbezeichnung!",
"The input is not valid Email!": "Die Eingabe ist keine gültige E-Mail-Adresse!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Drittanbieter-Anmeldungen, die mit dem Benutzer verknüpft sind",
"Address": "Adresse",
"Address - Tooltip": "Wohnadresse",
"Address line": "Address line",
"Affiliation": "Zugehörigkeit",
"Affiliation - Tooltip": "Arbeitgeber, wie Firmenname oder Organisationsname",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Selbstvorstellung des Nutzers",
"Birthday": "Birthday",
@@ -1120,6 +1139,8 @@
"Managed accounts": "Verwaltete Konten",
"Modify password...": "Passwort ändern...",
"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 Password": "Neues Passwort",
"New User": "Neuer Benutzer",
@@ -1162,9 +1183,11 @@
"Values": "Werte",
"Verification code sent": "Bestätigungscode gesendet",
"WebAuthn credentials": "WebAuthn-Anmeldeinformationen",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "Eingabe des Passworts"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "¡Por favor, ingrese su solicitud!",
"Please input your organization!": "¡Por favor, ingrese su organización!",
"Please select a HTML file": "Por favor, seleccione un archivo HTML",
@@ -165,7 +166,7 @@
"Next Step": "Siguiente paso",
"Please input your username!": "¡Por favor, ingrese su nombre de usuario!",
"Reset": "Restablecer",
"Retrieve password": "Recuperar contraseña",
"Reset password": "Reset password",
"Unknown forget type": "Tipo de olvido desconocido",
"Verify": "Verificar"
},
@@ -229,6 +230,7 @@
"Email": "Correo electrónico",
"Email - Tooltip": "Dirección de correo electrónico válida",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Teléfono",
"Phone - Tooltip": "Número de teléfono",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Planes",
@@ -391,6 +394,7 @@
"User type": "Tipo de usuario",
"User type - Tooltip": "Etiquetas a las que el usuario pertenece, con una configuración predeterminada en \"usuario-normal\"",
"Users": "Usuarios",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Usuarios bajo todas las organizaciones",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Cargando",
"Logging out...": "Cerrando sesión...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "¿No tienes cuenta?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Iniciar sesión con WebAuthn",
"Sign in with {type}": "Inicia sesión con {tipo}",
"Signin button": "Signin button",
"Signing in...": "Iniciando sesión...",
"Successfully logged in with WebAuthn credentials": "Inició sesión correctamente con las credenciales de WebAuthn",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Etiquetas",
"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",
"Visible": "Visible - Visible",
"Website URL": "URL del sitio web",
@@ -615,6 +621,7 @@
"Processing...": "Procesando...",
"Product": "Producto",
"Product - Tooltip": "Nombre del producto",
"Recharged successfully": "Recharged successfully",
"Result": "Resultado",
"Return to Website": "Regresar al sitio web",
"The payment has been canceled": "The payment has been canceled",
@@ -623,6 +630,8 @@
"The payment is still under processing": "El pago aún está en proceso",
"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 recharged": "You have successfully recharged",
"Your current balance is": "Your current balance is",
"please wait for a few seconds...": "Por favor espera unos segundos...",
"the current state is": "el estado actual es"
},
@@ -685,6 +694,8 @@
"Edit Product": "Editar Producto",
"Image": "Imagen",
"Image - Tooltip": "Imagen del producto",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "Nuevo producto",
"Pay": "Pagar",
"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": "Anfitrión",
"Host - Tooltip": "Nombre del anfitrión",
"IdP": "IdP = Proveedor de Identidad",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"resource": {
"Copy Link": "Copiar enlace",
@@ -941,6 +955,7 @@
"Please select your country code!": "¡Por favor seleccione su código de país!",
"Please select your country/region!": "¡Por favor seleccione su país/región!",
"Regex": "Regex",
"Signup button": "Signup button",
"Terms of Use": "Términos de uso",
"Terms of Use - Tooltip": "Términos de uso que los usuarios necesitan leer y aceptar durante el registro",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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 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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Accesos sociales ligados por el usuario",
"Address": "Dirección",
"Address - Tooltip": "Dirección residencial",
"Address line": "Address line",
"Affiliation": "Afiliació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 - Tooltip": "Introducción personal del usuario",
"Birthday": "Birthday",
@@ -1120,6 +1139,8 @@
"Managed accounts": "Cuentas gestionadas",
"Modify password...": "Modificar contraseña...",
"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 Password": "Nueva contraseña",
"New User": "Nuevo Usuario",
@@ -1162,9 +1183,11 @@
"Values": "Valores",
"Verification code sent": "Código de verificación enviado",
"WebAuthn credentials": "Credenciales de WebAuthn",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "Ingresar contraseña"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Inscription uniquement",
"Org choice mode": "Choix du mode de l'organisation",
"Org choice mode - Tooltip": "Choix du mode de l'organisation - Info-bulle",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Veuillez saisir votre application !",
"Please input your organization!": "Veuillez saisir votre organisation !",
"Please select a HTML file": "Veuillez sélectionner un fichier HTML",
@@ -165,7 +166,7 @@
"Next Step": "Étape suivante",
"Please input your username!": "Veuillez saisir votre identifiant !",
"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",
"Verify": "Vérifier"
},
@@ -229,6 +230,7 @@
"Email": "E-mail",
"Email - Tooltip": "Adresse e-mail valide",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Activer",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Téléphone",
"Phone - Tooltip": "Numéro de téléphone",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Offre",
"Plan - Tooltip": "Offre - Infobulle",
"Plans": "Offres",
@@ -391,6 +394,7 @@
"User type": "Type de compte",
"User type - Tooltip": "Étiquettes associées au compte, avec une valeur par défaut \"normal-user\"",
"Users": "Comptes",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Comptes sous toutes les organisations",
"Verifications": "Verifications",
"Webhooks": "Crochets web",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Chargement",
"Logging out...": "Déconnexion...",
"Login button": "Login button",
"MetaMask plugin not detected": "Le plugin MetaMask n'a pas été détecté",
"Model loading failure": "Model loading failure",
"No account?": "Pas de compte ?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Connectez-vous avec WebAuthn",
"Sign in with {type}": "Connectez-vous avec {type}",
"Signin button": "Signin button",
"Signing in...": "Connexion en cours...",
"Successfully logged in with WebAuthn credentials": "Connexion avec les identifiants WebAuthn réussie",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Étiquettes",
"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é",
"Visible": "Visible",
"Website URL": "URL du site web",
@@ -615,6 +621,7 @@
"Processing...": "Traitement...",
"Product": "Produit",
"Product - Tooltip": "Nom du produit",
"Recharged successfully": "Recharged successfully",
"Result": "Résultat",
"Return to Website": "Retourner sur le site web",
"The payment has been canceled": "Le paiement a été annulé",
@@ -623,6 +630,8 @@
"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",
"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...",
"the current state is": "l'état actuel est"
},
@@ -685,6 +694,8 @@
"Edit Product": "Modifier le produit",
"Image": "Image",
"Image - Tooltip": "Image du produit",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "Nouveau produit",
"Pay": "Payer",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"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 - 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 - Tooltip": "Nom d'hôte",
"IdP": "IdP (Identité Fournisseur)",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"resource": {
"Copy Link": "Copier le lien",
@@ -941,6 +955,7 @@
"Please select your country code!": "Sélectionnez votre code de pays, s'il vous plaît !",
"Please select your country/region!": "Veuillez sélectionner votre pays/région !",
"Regex": "Regex",
"Signup button": "Signup button",
"Terms of Use": "Conditions d'utilisation",
"Terms of Use - Tooltip": "Conditions d'utilisation qui doivent être lus acceptés lors de l'enregistrement du compte",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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 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 !",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Service de connexions tiers liés au compte",
"Address": "Adresse",
"Address - Tooltip": "Adresse résidentielle",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employeur, tel que le nom de l'entreprise ou de l'organisation",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Biographie du compte",
"Birthday": "Date de naissance",
@@ -1120,6 +1139,8 @@
"Managed accounts": "Comptes gérés",
"Modify password...": "Modifier le mot de passe...",
"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 Password": "Nouveau mot de passe",
"New User": "Nouveau compte",
@@ -1162,9 +1183,11 @@
"Values": "Valeurs",
"Verification code sent": "Code de vérification envoyé",
"WebAuthn credentials": "Identifiants WebAuthn",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "saisir le mot de passe"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Silakan masukkan aplikasi Anda!",
"Please input your organization!": "Silakan masukkan organisasi Anda!",
"Please select a HTML file": "Silahkan pilih file HTML",
@@ -165,7 +166,7 @@
"Next Step": "Langkah selanjutnya",
"Please input your username!": "Silakan masukkan nama pengguna Anda!",
"Reset": "Menyetel-ulang",
"Retrieve password": "Mengambil password",
"Reset password": "Mengambil password",
"Unknown forget type": "Tipe yang tidak diketahui terlupakan",
"Verify": "Memverifikasi"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Alamat email yang valid",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Telepon",
"Phone - Tooltip": "Nomor telepon",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Rencana",
@@ -391,6 +394,7 @@
"User type": "Jenis pengguna",
"User type - Tooltip": "Tag yang dimiliki oleh pengguna, defaultnya adalah \"normal-user\"",
"Users": "Pengguna-pengguna",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Pengguna di bawah semua organisasi",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Memuat",
"Logging out...": "Keluar...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "Tidak memiliki akun?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Masuk dengan WebAuthn",
"Sign in with {type}": "Masuk dengan {type}",
"Signin button": "Signin button",
"Signing in...": "Masuk...",
"Successfully logged in with WebAuthn credentials": "Berhasil masuk dengan kredensial WebAuthn",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,6 +576,8 @@
"Soft deletion - Tooltip": "Ketika diaktifkan, menghapus pengguna tidak akan sepenuhnya menghapus mereka dari database. Sebaliknya, mereka akan ditandai sebagai dihapus",
"Tags": "Tag-tag",
"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",
"Visible": "Terlihat",
"Website URL": "URL situs web",
@@ -615,6 +621,7 @@
"Processing...": "Pemrosesan...",
"Product": "Produk",
"Product - Tooltip": "Nama Produk",
"Recharged successfully": "Recharged successfully",
"Result": "Hasil",
"Return to Website": "Kembali ke Situs Web",
"The payment has been canceled": "The payment has been canceled",
@@ -623,6 +630,8 @@
"The payment is still under processing": "Pembayaran masih dalam proses",
"Type - Tooltip": "Metode pembayaran yang digunakan saat membeli produk",
"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...",
"the current state is": "keadaan saat ini adalah"
},
@@ -685,6 +694,8 @@
"Edit Product": "Edit Produk",
"Image": "Gambar",
"Image - Tooltip": "Gambar produk",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "Produk Baru",
"Pay": "Bayar",
"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": "Tuan rumah",
"Host - Tooltip": "Nama tuan rumah",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"resource": {
"Copy Link": "Salin Tautan",
@@ -941,6 +955,7 @@
"Please select your country code!": "Tolong pilih kode negara Anda!",
"Please select your country/region!": "Silakan pilih negara/region Anda!",
"Regex": "Regex",
"Signup button": "Signup button",
"Terms of Use": "Syarat Penggunaan",
"Terms of Use - Tooltip": "Syarat penggunaan yang harus dibaca dan disetujui oleh pengguna selama proses registrasi",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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 title!": "Masukan bukan judul faktur!",
"The input is not valid Email!": "Input yang dimasukkan bukan sesuai dengan format Email yang valid!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Masuk sosial yang terhubung oleh pengguna",
"Address": "Alamat",
"Address - Tooltip": "Alamat tempat tinggal",
"Address line": "Address line",
"Affiliation": "Afiliasi",
"Affiliation - Tooltip": "Pemberi Kerja, seperti nama perusahaan atau nama organisasi",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio: Biografi",
"Bio - Tooltip": "Pengenalan diri dari pengguna",
"Birthday": "Birthday",
@@ -1120,6 +1139,8 @@
"Managed accounts": "Akun yang dikelola",
"Modify password...": "Mengubah kata sandi...",
"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 Password": "Kata Sandi Baru",
"New User": "Pengguna Baru",
@@ -1162,9 +1183,11 @@
"Values": "Nilai-nilai",
"Verification code sent": "Kode verifikasi telah dikirim",
"WebAuthn credentials": "Kredensial WebAuthn",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "masukkan kata sandi"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "あなたの申請を入力してください!",
"Please input your organization!": "あなたの組織を入力してください!",
"Please select a HTML file": "HTMLファイルを選択してください",
@@ -165,7 +166,7 @@
"Next Step": "次のステップ",
"Please input your username!": "ユーザー名を入力してください!",
"Reset": "リセット",
"Retrieve password": "パスワードの取得",
"Reset password": "パスワードの取得",
"Unknown forget type": "未知の忘却タイプ",
"Verify": "検証"
},
@@ -229,6 +230,7 @@
"Email": "電子メール",
"Email - Tooltip": "有効な電子メールアドレス",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "電話",
"Phone - Tooltip": "電話番号",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "プラン",
@@ -391,6 +394,7 @@
"User type": "ユーザータイプ",
"User type - Tooltip": "ユーザーが属するタグは、デフォルトでは「通常ユーザー」となります",
"Users": "ユーザー",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "すべての組織のユーザー",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "ローディング",
"Logging out...": "ログアウト中...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "アカウントがありませんか?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "WebAuthnでサインインしてください",
"Sign in with {type}": "{type}でサインインしてください",
"Signin button": "Signin button",
"Signing in...": "サインイン中...",
"Successfully logged in with WebAuthn credentials": "WebAuthnの認証情報で正常にログインしました",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,6 +576,8 @@
"Soft deletion - Tooltip": "有効になっている場合、ユーザーを削除しても完全にデータベースから削除されません。代わりに、削除されたとマークされます",
"Tags": "タグ",
"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": "ビュールール",
"Visible": "見える",
"Website URL": "ウェブサイトのURL",
@@ -615,6 +621,7 @@
"Processing...": "処理中... ",
"Product": "製品",
"Product - Tooltip": "製品名",
"Recharged successfully": "Recharged successfully",
"Result": "結果",
"Return to Website": "ウェブサイトに戻る",
"The payment has been canceled": "The payment has been canceled",
@@ -623,6 +630,8 @@
"The payment is still under processing": "支払いはまだ処理中です",
"Type - Tooltip": "製品を購入する際に使用される支払方法",
"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...": "数秒お待ちください...",
"the current state is": "現在の状態は"
},
@@ -685,6 +694,8 @@
"Edit Product": "製品を編集",
"Image": "画像",
"Image - Tooltip": "製品のイメージ",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "新製品",
"Pay": "支払う",
"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 - Tooltip": "ホストの名前",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"resource": {
"Copy Link": "コピー リンク",
@@ -941,6 +955,7 @@
"Please select your country code!": "あなたの国コードを選択してください!",
"Please select your country/region!": "あなたの国/地域を選択してください!",
"Regex": "Regex",
"Signup button": "Signup button",
"Terms of Use": "利用規約",
"Terms of Use - Tooltip": "ユーザーが登録する際に読んで同意する必要がある利用規約",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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 title!": "インプットは請求書タイトルではありません!",
"The input is not valid Email!": "入力されたものは有効なメールではありません",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "ユーザーによってリンクされたソーシャルログイン",
"Address": "住所",
"Address - Tooltip": "住所",
"Address line": "Address line",
"Affiliation": "所属",
"Affiliation - Tooltip": "企業名や団体名などの雇用主",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "バイオ技術",
"Bio - Tooltip": "ユーザーの自己紹介\n\n私は○○です。私は○○国、都市、職業など出身で、現在は○○国、都市、職業などに住んでいます。私は○○趣味、特技、興味などが好きで、空き時間にはよくそれをしています。よろしくお願いします",
"Birthday": "Birthday",
@@ -1120,6 +1139,8 @@
"Managed accounts": "管理アカウント",
"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 Password": "新しいパスワード",
"New User": "新しいユーザー",
@@ -1162,9 +1183,11 @@
"Values": "価値観",
"Verification code sent": "確認コードを送信しました",
"WebAuthn credentials": "WebAuthnの資格情報",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "パスワードを入力してください"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "당신의 신청서를 입력해주세요!",
"Please input your organization!": "귀하의 조직을 입력해 주세요!",
"Please select a HTML file": "HTML 파일을 선택해 주세요",
@@ -165,7 +166,7 @@
"Next Step": "다음 단계",
"Please input your username!": "사용자 이름을 입력하세요!",
"Reset": "리셋",
"Retrieve password": "비밀번호를 복구하세요",
"Reset password": "비밀번호를 복구하세요",
"Unknown forget type": "미지의 잊혀진 유형",
"Verify": "검증하다"
},
@@ -229,6 +230,7 @@
"Email": "이메일",
"Email - Tooltip": "유효한 이메일 주소",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "전화기",
"Phone - Tooltip": "전화 번호",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "플랜",
@@ -391,6 +394,7 @@
"User type": "사용자 유형",
"User type - Tooltip": "사용자가 속한 태그는 기본적으로 \"보통 사용자\"로 설정됩니다",
"Users": "사용자",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "모든 조직의 사용자",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "로딩 중입니다",
"Logging out...": "로그아웃 중...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "계정이 없나요?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "WebAuthn으로 로그인하세요",
"Sign in with {type}": "{type}로 로그인하세요",
"Signin button": "Signin button",
"Signing in...": "로그인 중...",
"Successfully logged in with WebAuthn credentials": "WebAuthn 자격 증명으로 로그인 성공적으로 수행했습니다",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,6 +576,8 @@
"Soft deletion - Tooltip": "사용 가능한 경우, 사용자 삭제 시 데이터베이스에서 완전히 삭제되지 않습니다. 대신 삭제됨으로 표시됩니다",
"Tags": "태그",
"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": "보기 규칙",
"Visible": "보이는",
"Website URL": "웹사이트 URL",
@@ -615,6 +621,7 @@
"Processing...": "처리 중...",
"Product": "제품",
"Product - Tooltip": "제품 이름",
"Recharged successfully": "Recharged successfully",
"Result": "결과",
"Return to Website": "웹 사이트로 돌아가기",
"The payment has been canceled": "The payment has been canceled",
@@ -623,6 +630,8 @@
"The payment is still under processing": "지불은 아직 처리 중입니다",
"Type - Tooltip": "제품을 구매할 때 사용되는 결제 방법",
"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...": "잠시만 기다려주세요...",
"the current state is": "현재 상태입니다"
},
@@ -685,6 +694,8 @@
"Edit Product": "제품 편집",
"Image": "이미지",
"Image - Tooltip": "제품 이미지",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "새로운 제품",
"Pay": "결제하다",
"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 - Tooltip": "호스트의 이름",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"resource": {
"Copy Link": "링크 복사하기",
@@ -941,6 +955,7 @@
"Please select your country code!": "국가 코드를 선택해 주세요!",
"Please select your country/region!": "국가 / 지역을 선택해주세요!",
"Regex": "Regex",
"Signup button": "Signup button",
"Terms of Use": "사용 약관",
"Terms of Use - Tooltip": "등록 중 사용자가 읽어야 하고 동의해야하는 이용 약관",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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 title!": "입력값은 송장 제목이 아닙니다!",
"The input is not valid Email!": "입력 값은 유효한 이메일이 아닙니다!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "사용자가 연결한 소셜 로그인",
"Address": "주소",
"Address - Tooltip": "주거지 주소",
"Address line": "Address line",
"Affiliation": "소속",
"Affiliation - Tooltip": "고용주, 회사명 또는 조직명",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "바이오",
"Bio - Tooltip": "사용자의 자기소개\n\n안녕하세요, 저는 [이름]입니다. 한국을 포함한 여러 나라에서 살아본 적이 있습니다. 저는 [직업/전공]을 공부하고 있으며 [취미/관심사]에 대해 깊게 알고 있습니다. 이 채팅 서비스를 사용하여 새로운 사람들과 함께 대화를 나누기를 원합니다. 감사합니다",
"Birthday": "Birthday",
@@ -1120,6 +1139,8 @@
"Managed accounts": "관리 계정",
"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 Password": "새로운 비밀번호",
"New User": "새로운 사용자",
@@ -1162,9 +1183,11 @@
"Values": "가치들",
"Verification code sent": "인증 코드가 전송되었습니다",
"WebAuthn credentials": "웹 인증 자격증명",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "비밀번호를 입력해주세요"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

View File

@@ -80,6 +80,7 @@
"Only signup": "Only signup",
"Org choice mode": "Org choice mode",
"Org choice mode - Tooltip": "Org choice mode - Tooltip",
"Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"": "Please enable \\\"Signin session\\\" first before enabling \\\"Auto signin\\\"",
"Please input your application!": "Please input your application!",
"Please input your organization!": "Please input your organization!",
"Please select a HTML file": "Please select a HTML file",
@@ -165,7 +166,7 @@
"Next Step": "Next Step",
"Please input your username!": "Please input your username!",
"Reset": "Reset",
"Retrieve password": "Retrieve password",
"Reset password": "Reset password",
"Unknown forget type": "Unknown forget type",
"Verify": "Verify"
},
@@ -229,6 +230,7 @@
"Email": "Email",
"Email - Tooltip": "Valid email address",
"Email only": "Email only",
"Email or Phone": "Email or Phone",
"Enable": "Enable",
"Enable dark logo": "Enable dark logo",
"Enable dark logo - Tooltip": "Enable dark logo",
@@ -311,6 +313,7 @@
"Phone": "Phone",
"Phone - Tooltip": "Phone number",
"Phone only": "Phone only",
"Phone or Email": "Phone or Email",
"Plan": "Plan",
"Plan - Tooltip": "Plan - Tooltip",
"Plans": "Plans",
@@ -391,6 +394,7 @@
"User type": "User type",
"User type - Tooltip": "Tags that the user belongs to, defaulting to \"normal-user\"",
"Users": "Users",
"Users - Tooltip": "Users - Tooltip",
"Users under all organizations": "Users under all organizations",
"Verifications": "Verifications",
"Webhooks": "Webhooks",
@@ -473,7 +477,6 @@
"LDAP username, Email or phone": "LDAP username, Email or phone",
"Loading": "Loading",
"Logging out...": "Logging out...",
"Login button": "Login button",
"MetaMask plugin not detected": "MetaMask plugin not detected",
"Model loading failure": "Model loading failure",
"No account?": "No account?",
@@ -498,6 +501,7 @@
"Sign in with Face ID": "Sign in with Face ID",
"Sign in with WebAuthn": "Sign in with WebAuthn",
"Sign in with {type}": "Sign in with {type}",
"Signin button": "Signin button",
"Signing in...": "Signing in...",
"Successfully logged in with WebAuthn credentials": "Successfully logged in with WebAuthn credentials",
"The camera is currently in use by another webpage": "The camera is currently in use by another webpage",
@@ -572,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",
"Tags": "Tags",
"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",
"Visible": "Visible",
"Website URL": "Website URL",
@@ -615,6 +621,7 @@
"Processing...": "Processing...",
"Product": "Product",
"Product - Tooltip": "Product Name",
"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": "Payment method used when purchasing the product",
"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 of product",
"Is recharge": "Is recharge",
"Is recharge - Tooltip": "Whether the current product is to recharge balance",
"New Product": "New Product",
"Pay": "Pay",
"PayPal": "PayPal",
@@ -774,6 +785,8 @@
"From address - Tooltip": "Email address of \"From\"",
"From name": "From name",
"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 - Tooltip": "Name of host",
"IdP": "IdP",
@@ -893,7 +906,8 @@
"record": {
"Is triggered": "Is triggered",
"Object": "Object",
"Response": "Response"
"Response": "Response",
"Status code": "Status code"
},
"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 that users need to read and agree to during registration",
"Text 1": "Text 1",
@@ -948,6 +963,7 @@
"Text 3": "Text 3",
"Text 4": "Text 4",
"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!",
@@ -1068,8 +1084,11 @@
"3rd-party logins - Tooltip": "Social logins linked by the user",
"Address": "Address",
"Address - Tooltip": "Residential address",
"Address line": "Address line",
"Affiliation": "Affiliation",
"Affiliation - Tooltip": "Employer, such as company name or organization name",
"Balance": "Balance",
"Balance - Tooltip": "User's balance",
"Bio": "Bio",
"Bio - Tooltip": "Self introduction of the user",
"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 credentials",
"You have changed the username, please save your change first before modifying the password": "You have changed the username, please save your change first before modifying the password",
"input password": "input password"
},
"verification": {
"Is used": "Is used",
"Receiver": "Receiver"
},
"webhook": {

Some files were not shown because too many files have changed in this diff Show More