Compare commits

...

26 Commits

Author SHA1 Message Date
Yaodong Yu
b99a0c3ca2 feat: optimize the "forget password" page (#1709) 2023-04-06 23:06:18 +08:00
Yaodong Yu
e1842f6b80 feat: fix LDAP server handle filter without CN field as * (#1705)
* fix: set ldap server default filter name as *

* fix: default use built-in organization to bind

* chore: use cache reduce the ci test time
2023-04-04 20:51:28 +08:00
Max Baier
0781a3835d feat: improve i18n to have proper German translation in web/ (#1702) 2023-04-02 10:52:30 +08:00
Yang Luo
98a99f0215 Fix bug in getMemoryUsage() 2023-04-02 10:50:41 +08:00
Yang Luo
681b086de0 Fix session page highlight 2023-04-01 17:36:50 +08:00
Yaodong Yu
cdcc0b39e2 feat: filter not selected provider item (#1701) 2023-04-01 10:22:18 +08:00
Gucheng Wang
8eb68ba817 fix: fix AAD single-tenant mode bug 2023-03-31 19:24:03 +08:00
Yang Luo
8d1ae4ea08 Fix organization page bug 2023-03-31 18:35:57 +08:00
zzjin
9c8ea027ef feat: add the missing userId param docs for get-user API (#1698)
* Add roles to SAML response

* Fix: Add back missing get-user userId param doc.

Signed-off-by: zzjin <tczzjin@gmail.com>

* Update user.go

---------

Signed-off-by: zzjin <tczzjin@gmail.com>
Co-authored-by: Yang Luo <hsluoyz@qq.com>
2023-03-30 18:39:14 +08:00
Yang Luo
aaa56d3354 Add roles to SAML response 2023-03-30 14:43:34 +08:00
Yaodong Yu
b45c49d3a4 feat: fix incorrect preferred_username field mapping in OIDC (#1697) 2023-03-29 22:18:12 +08:00
Yaodong Yu
5b3202cc89 feat: fix phone validation bug in signup page (#1693) 2023-03-27 22:52:49 +08:00
Gucheng Wang
5280f872dc Speed up GetOAuthToken() 2023-03-27 14:05:44 +08:00
Yaodong Yu
fd61b963d5 feat: [SAML + long button crash] fix Disabling "Enable password" leads to white app page when SAML provider is active (#1691)
* fix: saml long button crush

* fix: sue svg

* Update Setting.js

* Update LoginButton.js

* Update ProviderButton.js

---------

Co-authored-by: hsluoyz <hsluoyz@qq.com>
2023-03-26 23:56:43 +08:00
Yaodong Yu
a8937d3046 feat: refactor agreement modal and create folders to classify components (#1686)
* refactor: refactor agreement modal and create folders to classify components

* fix: i18

* fix: i18

* fix: i18n
2023-03-26 18:44:47 +08:00
Yang Luo
32b05047dc Update system info API swagger 2023-03-26 10:19:59 +08:00
hsluoyz
117ee509cf feat: fix name format in application login: GetClientCredentialsToken() (#1639) 2023-03-25 23:02:08 +08:00
Yaodong Yu
daf3d374b5 fix: adjust error result position (#1683) 2023-03-25 09:36:23 +08:00
Yaodong Yu
337ee2faef feat: fix the bug that autoSignin generates two callback AJAX calls (#1682) 2023-03-24 23:17:54 +08:00
Gucheng Wang
989fec72bf Add /api/user API for Flarum's FoF Passport plugin 2023-03-24 01:02:04 +08:00
Gucheng Wang
76eb606335 Support AAD tenant auth URL 2023-03-23 22:37:53 +08:00
Yaodong Yu
c6146a9149 feat: fix bug that login by saml provider can not find application (#1676) 2023-03-23 21:38:33 +08:00
imp2002
f191488338 feat: support popup mode in OAuth (#1668)
* feat: support `popup` mode in OAuth

* feat: sendMessage when popup window closed

* fix: fix param name error
2023-03-22 00:15:17 +08:00
longxu0509
da7336a9a4 feat: support getting versionInfo in docker (#1673)
* feat: support getting versionInfo in docker

* fix: fix build

* fix: fix build

* fix: fix system
2023-03-21 20:46:17 +08:00
Gucheng Wang
b3806070ac Finish Go i18n texts 2023-03-20 01:10:48 +08:00
Gucheng Wang
c7b9a77b4a Remove Go i18n duplicates 2023-03-19 22:09:19 +08:00
100 changed files with 2445 additions and 2039 deletions

View File

@@ -9,18 +9,19 @@ jobs:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_DATABASE: casdoor
MYSQL_ROOT_PASSWORD: 123456
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
image: mysql:5.7
env:
MYSQL_DATABASE: casdoor
MYSQL_ROOT_PASSWORD: 123456
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '^1.16.5'
cache-dependency-path: ./go.mod
- name: Tests
run: |
go test -v $(go list ./...) -tags skipCi
@@ -31,14 +32,12 @@ jobs:
runs-on: ubuntu-latest
needs: [ go-tests ]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
# cache
- uses: c-hive/gha-yarn-cache@v2
with:
directory: ./web
cache: 'yarn'
cache-dependency-path: ./web/yarn.lock
- run: yarn install && CI=false yarn run build
working-directory: ./web
@@ -47,10 +46,11 @@ jobs:
runs-on: ubuntu-latest
needs: [ go-tests ]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '^1.16.5'
cache-dependency-path: ./go.mod
- run: go version
- name: Build
run: |
@@ -63,13 +63,14 @@ jobs:
needs: [ go-tests ]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/setup-go@v4
with:
go-version: '^1.16.5'
cache-dependency-path: ./go.mod
# gen a dummy config file
- run: touch dummy.yml
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
@@ -82,35 +83,35 @@ jobs:
needs: [ go-tests ]
services:
mysql:
image: mysql:5.7
env:
MYSQL_DATABASE: casdoor
MYSQL_ROOT_PASSWORD: 123456
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
image: mysql:5.7
env:
MYSQL_DATABASE: casdoor
MYSQL_ROOT_PASSWORD: 123456
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '^1.16.5'
- uses: actions/setup-node@v2
with:
node-version: 16
- name: back start
cache-dependency-path: ./go.mod
- name: start backend
run: nohup go run ./main.go &
working-directory: ./
- name: front install
run: yarn install
working-directory: ./web
- name: front start
run: nohup yarn start &
working-directory: ./web
- uses: cypress-io/github-action@v4
- uses: actions/setup-node@v3
with:
working-directory: ./web
node-version: 16
cache: 'yarn'
cache-dependency-path: ./web/yarn.lock
- run: yarn install
working-directory: ./web
- uses: cypress-io/github-action@v5
with:
start: yarn start
wait-on: 'http://localhost:7001'
wait-on-timeout: 180
working-directory: ./web
- uses: actions/upload-artifact@v3
if: failure()
@@ -121,7 +122,7 @@ jobs:
if: always()
with:
name: cypress-videos
path: ./web/cypress/videos
path: ./web/cypress/videos
release-and-push:
name: Release And Push
@@ -130,11 +131,11 @@ jobs:
needs: [ frontend, backend, linter, e2e ]
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
fetch-depth: -1
- name: Setup Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 16
@@ -166,10 +167,10 @@ jobs:
elif [ ${old_array[1]} != ${new_array[1]} ]
then
echo ::set-output name=push::'true'
else
echo ::set-output name=push::'false'
fi
- name: Set up QEMU
@@ -192,6 +193,7 @@ jobs:
uses: docker/build-push-action@v3
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true'
with:
context: .
target: STANDARD
platforms: linux/amd64,linux/arm64
push: true
@@ -201,6 +203,7 @@ jobs:
uses: docker/build-push-action@v3
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push' && steps.should_push.outputs.push=='true'
with:
context: .
target: ALLINONE
platforms: linux/amd64,linux/arm64
push: true

View File

@@ -9,7 +9,7 @@ FROM golang:1.17.5 AS BACK
WORKDIR /go/src/casdoor
COPY . .
RUN ./build.sh
RUN go test -v -run TestGetVersionInfo ./util/system_test.go ./util/system.go > version_info.txt
FROM alpine:latest AS STANDARD
LABEL MAINTAINER="https://casdoor.org/"
@@ -34,6 +34,7 @@ WORKDIR /
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
COPY --from=FRONT --chown=$USER:$USER /web/build ./web/build
ENTRYPOINT ["/server"]
@@ -61,6 +62,7 @@ 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
COPY --from=BACK /go/src/casdoor/version_info.txt ./go/src/casdoor/version_info.txt
COPY --from=FRONT /web/build ./web/build
ENTRYPOINT ["/bin/bash"]

View File

@@ -87,6 +87,7 @@ p, *, *, POST, /api/logout, *, *
p, *, *, GET, /api/logout, *, *
p, *, *, GET, /api/get-account, *, *
p, *, *, GET, /api/userinfo, *, *
p, *, *, GET, /api/user, *, *
p, *, *, POST, /api/webhook, *, *
p, *, *, GET, /api/get-webhook-event, *, *
p, *, *, *, /api/login/oauth, *, *
@@ -107,6 +108,7 @@ p, *, *, POST, /api/set-password, *, *
p, *, *, POST, /api/send-verification-code, *, *
p, *, *, GET, /api/get-captcha, *, *
p, *, *, POST, /api/verify-captcha, *, *
p, *, *, POST, /api/verify-code, *, *
p, *, *, POST, /api/reset-email-or-phone, *, *
p, *, *, POST, /api/upload-resource, *, *
p, *, *, GET, /.well-known/openid-configuration, *, *

View File

@@ -50,6 +50,7 @@ type RequestForm struct {
Region string `json:"region"`
Application string `json:"application"`
ClientId string `json:"clientId"`
Provider string `json:"provider"`
Code string `json:"code"`
State string `json:"state"`
@@ -103,7 +104,7 @@ type Captcha struct {
// @router /signup [post]
func (c *ApiController) Signup() {
if c.GetSessionUsername() != "" {
c.ResponseError(c.T("account:Please sign out first before signing up"), c.GetSessionUsername())
c.ResponseError(c.T("account:Please sign out first"), c.GetSessionUsername())
return
}
@@ -211,7 +212,7 @@ func (c *ApiController) Signup() {
affected := object.AddUser(user)
if !affected {
c.ResponseError(c.T("account:Invalid information"), util.StructToJson(user))
c.ResponseError(c.T("account:Failed to add user"), util.StructToJson(user))
return
}
@@ -369,6 +370,43 @@ func (c *ApiController) GetUserinfo() {
c.ServeJSON()
}
// GetUserinfo2
// LaravelResponse
// @Title UserInfo2
// @Tag Account API
// @Description return Laravel compatible user information according to OAuth 2.0
// @Success 200 {object} LaravelResponse The Response object
// @router /user [get]
func (c *ApiController) GetUserinfo2() {
user, ok := c.RequireSignedInUser()
if !ok {
return
}
// this API is used by "Api URL" of Flarum's FoF Passport plugin
// https://github.com/FriendsOfFlarum/passport
type LaravelResponse struct {
Id string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerifiedAt string `json:"email_verified_at"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
response := LaravelResponse{
Id: user.Id,
Name: user.Name,
Email: user.Email,
EmailVerifiedAt: user.CreatedTime,
CreatedAt: user.CreatedTime,
UpdatedAt: user.UpdatedTime,
}
c.Data["json"] = response
c.ServeJSON()
}
// GetCaptcha ...
// @Tag Login API
// @Title GetCaptcha

View File

@@ -237,7 +237,7 @@ func (c *ApiController) Login() {
if form.Username != "" {
if form.Type == ResponseTypeLogin {
if c.GetSessionUsername() != "" {
c.ResponseError(c.T("account:Please sign out first before signing in"), c.GetSessionUsername())
c.ResponseError(c.T("account:Please sign out first"), c.GetSessionUsername())
return
}
}
@@ -246,33 +246,14 @@ func (c *ApiController) Login() {
var msg string
if form.Password == "" {
var verificationCodeType string
var checkResult string
if form.Name != "" {
user = object.GetUserByFields(form.Organization, form.Name)
}
// check result through Email or Phone
var checkDest string
if strings.Contains(form.Username, "@") {
verificationCodeType = "email"
if user != nil && util.GetMaskedEmail(user.Email) == form.Username {
form.Username = user.Email
}
checkDest = form.Username
} else {
verificationCodeType = "phone"
if user != nil && util.GetMaskedPhone(user.Phone) == form.Username {
form.Username = user.Phone
}
}
if user = object.GetUserByFields(form.Organization, form.Username); user == nil {
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
return
}
if verificationCodeType == "phone" {
verificationCodeType := object.GetVerifyType(form.Username)
var checkDest string
if verificationCodeType == object.VerifyTypePhone {
form.CountryCode = user.GetCountryCode(form.CountryCode)
var ok bool
if checkDest, ok = util.GetE164Number(form.Username, form.CountryCode); !ok {
@@ -281,7 +262,8 @@ func (c *ApiController) Login() {
}
}
checkResult = object.CheckSigninCode(user, checkDest, form.Code, c.GetAcceptLanguage())
// check result through Email or Phone
checkResult := object.CheckSigninCode(user, checkDest, form.Code, c.GetAcceptLanguage())
if len(checkResult) != 0 {
c.ResponseError(fmt.Sprintf("%s - %s", verificationCodeType, checkResult))
return
@@ -308,7 +290,7 @@ func (c *ApiController) Login() {
}
if !isHuman {
c.ResponseError(c.T("auth:Turing test failed."))
c.ResponseError(c.T("verification:Turing test failed."))
return
}
}
@@ -334,7 +316,13 @@ func (c *ApiController) Login() {
util.SafeGoroutine(func() { object.AddRecord(record) })
}
} else if form.Provider != "" {
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
var application *object.Application
if form.ClientId != "" {
application = object.GetApplicationByClientId(form.ClientId)
} else {
application = object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
}
if application == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
return
@@ -368,7 +356,7 @@ func (c *ApiController) Login() {
idProvider := idp.GetIdProvider(provider.Type, provider.SubType, clientId, clientSecret, provider.AppId, form.RedirectUri, provider.Domain, provider.CustomAuthUrl, provider.CustomTokenUrl, provider.CustomUserInfoUrl)
if idProvider == nil {
c.ResponseError(fmt.Sprintf(c.T("auth:The provider type: %s is not supported"), provider.Type))
c.ResponseError(fmt.Sprintf(c.T("storage:The provider type: %s is not supported"), provider.Type))
return
}
@@ -410,7 +398,7 @@ func (c *ApiController) Login() {
// Sign in via OAuth (want to sign up but already have account)
if user.IsForbidden {
c.ResponseError(c.T("auth:The user is forbidden to sign in, please contact the administrator"))
c.ResponseError(c.T("check:The user is forbidden to sign in, please contact the administrator"))
}
resp = c.HandleLoggedIn(application, user, &form)

View File

@@ -195,7 +195,7 @@ func (c *ApiController) UploadResource() {
}
}
fileUrl, objectKey, err := object.UploadFileSafe(provider, fullFilePath, fileBuffer)
fileUrl, objectKey, err := object.UploadFileSafe(provider, fullFilePath, fileBuffer, c.GetAcceptLanguage())
if err != nil {
c.ResponseError(err.Error())
return

View File

@@ -21,9 +21,8 @@ import (
// GetSystemInfo
// @Title GetSystemInfo
// @Tag System API
// @Description get user's system info
// @Param id query string true "The id ( owner/name ) of the user"
// @Success 200 {object} object.SystemInfo The Response object
// @Description get system info like CPU and memory usage
// @Success 200 {object} util.SystemInfo The Response object
// @router /get-system-info [get]
func (c *ApiController) GetSystemInfo() {
_, ok := c.RequireAdmin()
@@ -43,14 +42,19 @@ func (c *ApiController) GetSystemInfo() {
// GetVersionInfo
// @Title GetVersionInfo
// @Tag System API
// @Description get local git repo's latest release version info
// @Success 200 {string} local latest version hash of Casdoor
// @Description get version info like Casdoor release version and commit ID
// @Success 200 {object} util.VersionInfo The Response object
// @router /get-version-info [get]
func (c *ApiController) GetVersionInfo() {
versionInfo, err := util.GetVersionInfo()
if err != nil {
c.ResponseError(err.Error())
return
if versionInfo.Version == "" {
versionInfo, err = util.GetVersionInfoFromFile()
if err != nil {
c.ResponseError(err.Error())
return
}
}
c.ResponseOk(versionInfo)

View File

@@ -84,6 +84,7 @@ func (c *ApiController) GetUsers() {
// @Param owner query string false "The owner of the user"
// @Param email query string false "The email of the user"
// @Param phone query string false "The phone of the user"
// @Param userId query string false "The userId of the user"
// @Success 200 {object} object.User The Response object
// @router /get-user [get]
func (c *ApiController) GetUser() {
@@ -94,13 +95,13 @@ func (c *ApiController) GetUser() {
owner := c.Input().Get("owner")
if owner == "" {
owner, _ = util.GetOwnerAndNameFromId(id)
owner = util.GetOwnerFromId(id)
}
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", owner))
if !organization.IsProfilePublic {
requestUserId := c.GetSessionUsername()
hasPermission, err := object.CheckUserPermission(requestUserId, id, owner, false, c.GetAcceptLanguage())
hasPermission, err := object.CheckUserPermission(requestUserId, id, false, c.GetAcceptLanguage())
if !hasPermission {
c.ResponseError(err.Error())
return
@@ -275,14 +276,34 @@ func (c *ApiController) SetPassword() {
userName := c.Ctx.Request.Form.Get("userName")
oldPassword := c.Ctx.Request.Form.Get("oldPassword")
newPassword := c.Ctx.Request.Form.Get("newPassword")
code := c.Ctx.Request.Form.Get("code")
if strings.Contains(newPassword, " ") {
c.ResponseError(c.T("user:New password cannot contain blank space."))
return
}
if len(newPassword) <= 5 {
c.ResponseError(c.T("user:New password must have at least 6 characters"))
return
}
requestUserId := c.GetSessionUsername()
userId := util.GetId(userOwner, userName)
hasPermission, err := object.CheckUserPermission(requestUserId, userId, userOwner, true, c.GetAcceptLanguage())
if !hasPermission {
c.ResponseError(err.Error())
requestUserId := c.GetSessionUsername()
if requestUserId == "" && code == "" {
return
} else if code == "" {
hasPermission, err := object.CheckUserPermission(requestUserId, userId, true, c.GetAcceptLanguage())
if !hasPermission {
c.ResponseError(err.Error())
return
}
} else {
if code != c.GetSession("verifiedCode") {
c.ResponseError("")
return
}
c.SetSession("verifiedCode", "")
}
targetUser := object.GetUser(userId)
@@ -295,16 +316,6 @@ func (c *ApiController) SetPassword() {
}
}
if strings.Contains(newPassword, " ") {
c.ResponseError(c.T("user:New password cannot contain blank space."))
return
}
if len(newPassword) <= 5 {
c.ResponseError(c.T("user:New password must have at least 6 characters"))
return
}
targetUser.Password = newPassword
object.SetUserField(targetUser, "password", targetUser.Password)
c.ResponseOk()

View File

@@ -15,6 +15,7 @@
package controllers
import (
"encoding/json"
"errors"
"fmt"
"strings"
@@ -96,7 +97,7 @@ func (c *ApiController) SendVerificationCode() {
application := object.GetApplication(applicationId)
organization := object.GetOrganization(util.GetId(application.Owner, application.Organization))
if organization == nil {
c.ResponseError(c.T("verification:Organization does not exist"))
c.ResponseError(c.T("check:Organization does not exist"))
return
}
@@ -110,9 +111,9 @@ func (c *ApiController) SendVerificationCode() {
sendResp := errors.New("invalid dest type")
switch destType {
case "email":
case object.VerifyTypeEmail:
if !util.IsEmailValid(dest) {
c.ResponseError(c.T("verification:Email is invalid"))
c.ResponseError(c.T("check:Email is invalid"))
return
}
@@ -132,7 +133,7 @@ func (c *ApiController) SendVerificationCode() {
provider := application.GetEmailProvider()
sendResp = object.SendVerificationCodeToEmail(organization, user, provider, remoteAddr, dest)
case "phone":
case object.VerifyTypePhone:
if method == LoginVerification || method == ForgetVerification {
if user != nil && util.GetMaskedPhone(user.Phone) == dest {
dest = user.Phone
@@ -187,7 +188,7 @@ func (c *ApiController) ResetEmailOrPhone() {
checkDest := dest
organization := object.GetOrganizationByUser(user)
if destType == "phone" {
if destType == object.VerifyTypePhone {
if object.HasUserByField(user.Owner, "phone", dest) {
c.ResponseError(c.T("check:Phone already exists"))
return
@@ -207,7 +208,7 @@ func (c *ApiController) ResetEmailOrPhone() {
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), user.CountryCode))
return
}
} else if destType == "email" {
} else if destType == object.VerifyTypeEmail {
if object.HasUserByField(user.Owner, "email", dest) {
c.ResponseError(c.T("check:Email already exists"))
return
@@ -230,10 +231,10 @@ func (c *ApiController) ResetEmailOrPhone() {
}
switch destType {
case "email":
case object.VerifyTypeEmail:
user.Email = dest
object.SetUserField(user, "email", user.Email)
case "phone":
case object.VerifyTypePhone:
user.Phone = dest
object.SetUserField(user, "phone", user.Phone)
default:
@@ -245,6 +246,60 @@ func (c *ApiController) ResetEmailOrPhone() {
c.ResponseOk()
}
// VerifyCode
// @Tag Account API
// @Title VerifyCode
// @router /api/verify-code [post]
func (c *ApiController) VerifyCode() {
var form RequestForm
err := json.Unmarshal(c.Ctx.Input.RequestBody, &form)
if err != nil {
c.ResponseError(err.Error())
return
}
var user *object.User
if form.Name != "" {
user = object.GetUserByFields(form.Organization, form.Name)
}
var checkDest string
if strings.Contains(form.Username, "@") {
if user != nil && util.GetMaskedEmail(user.Email) == form.Username {
form.Username = user.Email
}
checkDest = form.Username
} else {
if user != nil && util.GetMaskedPhone(user.Phone) == form.Username {
form.Username = user.Phone
}
}
if user = object.GetUserByFields(form.Organization, form.Username); user == nil {
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
return
}
verificationCodeType := object.GetVerifyType(form.Username)
if verificationCodeType == object.VerifyTypePhone {
form.CountryCode = user.GetCountryCode(form.CountryCode)
var ok bool
if checkDest, ok = util.GetE164Number(form.Username, form.CountryCode); !ok {
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), form.CountryCode))
return
}
}
if result := object.CheckVerificationCode(checkDest, form.Code, c.GetAcceptLanguage()); result.Code != object.VerificationSuccess {
c.ResponseError(result.Msg)
return
}
object.DisableVerificationCode(checkDest)
c.SetSession("verifiedCode", form.Code)
c.ResponseOk()
}
// VerifyCaptcha ...
// @Title VerifyCaptcha
// @Tag Verification API

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "Konnte den Benutzer nicht hinzufügen",
"Get init score failed, error: %w": "Init-Score konnte nicht abgerufen werden, Fehler: %w",
"Please sign out first": "Bitte melden Sie sich zuerst ab",
"The application does not allow to sign up new account": "Die Anwendung erlaubt es nicht, sich für ein neues Konto anzumelden"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "Die Challenge-Methode sollte S256 sein",
"Failed to create user, user information is invalid: %s": "Es konnte kein Benutzer erstellt werden, da die Benutzerinformationen ungültig sind: %s",
"Failed to login in: %s": "Konnte nicht anmelden: %s",
"Invalid token": "Ungültiges Token",
"State expected: %s, but got: %s": "Erwarteter Zustand: %s, aber erhalten: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Das Konto für den Anbieter: %s und Benutzernamen: %s (%s) existiert nicht und darf nicht über %%s als neues Konto erstellt werden. Bitte nutzen Sie einen anderen Weg, um sich anzumelden",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Das Konto für den Anbieter %s und Benutzernamen %s (%s) existiert nicht und es ist nicht erlaubt, ein neues Konto anzumelden. Bitte wenden Sie sich an Ihren IT-Support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Das Konto für den Anbieter %s und Benutzernamen %s (%s) ist bereits mit einem anderen Konto verknüpft: %s (%s)",
"The application: %s does not exist": "Die Anwendung: %s existiert nicht",
"The login method: login with password is not enabled for the application": "Die Anmeldeart \"Anmeldung mit Passwort\" ist für die Anwendung nicht aktiviert",
"The provider: %s is not enabled for the application": "Der Anbieter: %s ist nicht für die Anwendung aktiviert",
"Unauthorized operation": "Nicht autorisierte Operation",
"Unknown authentication type (not password or provider), form = %s": "Unbekannter Authentifizierungstyp (nicht Passwort oder Anbieter), Formular = %s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "Service %s und %s stimmen nicht überein"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Affiliation cannot be blank": "Zugehörigkeit darf nicht leer sein",
"DisplayName cannot be blank": "Anzeigename kann nicht leer sein",
"DisplayName is not valid real name": "DisplayName ist kein gültiger Vorname",
"Email already exists": "E-Mail existiert bereits",
"Email cannot be empty": "E-Mail darf nicht leer sein",
"Email is invalid": "E-Mail ist ungültig",
"Empty username.": "Leerer Benutzername.",
"FirstName cannot be blank": "Vorname darf nicht leer sein",
"LastName cannot be blank": "Nachname darf nicht leer sein",
"Ldap user name or password incorrect": "Ldap Benutzername oder Passwort falsch",
"Multiple accounts with same uid, please check your ldap server": "Mehrere Konten mit derselben uid, bitte überprüfen Sie Ihren LDAP-Server",
"Organization does not exist": "Organisation existiert nicht",
"Password must have at least 6 characters": "Das Passwort muss mindestens 6 Zeichen enthalten",
"Phone already exists": "Telefon existiert bereits",
"Phone cannot be empty": "Das Telefon darf nicht leer sein",
"Phone number is invalid": "Die Telefonnummer ist ungültig",
"Session outdated, please login again": "Sitzung abgelaufen, bitte erneut anmelden",
"The user is forbidden to sign in, please contact the administrator": "Dem Benutzer ist der Zugang verboten, bitte kontaktieren Sie den Administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Der Benutzername darf nur alphanumerische Zeichen, Unterstriche oder Bindestriche enthalten, keine aufeinanderfolgenden Bindestriche oder Unterstriche haben und darf nicht mit einem Bindestrich oder Unterstrich beginnen oder enden.",
"Username already exists": "Benutzername existiert bereits",
"Username cannot be an email address": "Benutzername kann keine E-Mail-Adresse sein",
"Username cannot contain white spaces": "Benutzername darf keine Leerzeichen enthalten",
"Username cannot start with a digit": "Benutzername darf nicht mit einer Ziffer beginnen",
"Username is too long (maximum is 39 characters).": "Benutzername ist zu lang (das Maximum beträgt 39 Zeichen).",
"Username must have at least 2 characters": "Benutzername muss mindestens 2 Zeichen lang sein",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Sie haben zu oft das falsche Passwort oder den falschen Code eingegeben. Bitte warten Sie %d Minuten und versuchen Sie es erneut",
"Your region is not allow to signup by phone": "Ihre Region ist nicht berechtigt, sich telefonisch anzumelden",
"password or code is incorrect, you have %d remaining chances": "Das Passwort oder der Code ist falsch. Du hast noch %d Versuche übrig",
"unsupported password type: %s": "Nicht unterstützter Passworttyp: %s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "Fehlender Parameter",
"Please login first": "Bitte zuerst einloggen",
"The user: %s doesn't exist": "Der Benutzer %s existiert nicht",
"don't support captchaProvider: ": "Unterstütze captchaProvider nicht:"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "Es gibt einen LDAP-Server"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "Bitte verlinken Sie zuerst",
"This application has no providers": "Diese Anwendung hat keine Anbieter",
"This application has no providers of type": "Diese Anwendung hat keine Anbieter des Typs",
"This provider can't be unlinked": "Dieser Anbieter kann nicht entkoppelt werden",
"You are not the global admin, you can't unlink other users": "Sie sind nicht der globale Administrator, Sie können keine anderen Benutzer trennen",
"You can't unlink yourself, you are not a member of any application": "Du kannst dich nicht abmelden, du bist kein Mitglied einer Anwendung"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "Nur der Administrator kann das %s ändern.",
"The %s is immutable.": "Das %s ist unveränderlich.",
"Unknown modify rule %s.": "Unbekannte Änderungsregel %s."
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "Ungültige Anwendungs-ID",
"the provider: %s does not exist": "Der Anbieter %s existiert nicht"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "Benutzer ist null für Tag: Avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Benutzername oder vollständiger Dateipfad sind leer: Benutzername = %s, vollständiger Dateipfad = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "Anwendung %s wurde nicht gefunden"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "Der Anbieter %s ist keine Kategorie von SAML"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "Leere Parameter für Email-Formular: %v",
"Invalid Email receivers: %s": "Ungültige E-Mail-Empfänger: %s",
"Invalid phone receivers: %s": "Ungültige Telefonempfänger: %s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "Der Objektschlüssel %s ist nicht erlaubt",
"The provider type: %s is not supported": "Der Anbieter-Typ %s wird nicht unterstützt"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "Leerer clientId oder clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s wird von dieser Anwendung nicht unterstützt",
"Invalid application or wrong clientSecret": "Ungültige Anwendung oder falsches clientSecret",
"Invalid client_id": "Ungültige client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Weiterleitungs-URI: %s ist nicht in der Liste erlaubter Weiterleitungs-URIs vorhanden",
"Token not found, invalid accessToken": "Token nicht gefunden, ungültiger Zugriffs-Token"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "Anzeigename darf nicht leer sein",
"New password cannot contain blank space.": "Das neue Passwort darf keine Leerzeichen enthalten.",
"New password must have at least 6 characters": "Das neue Passwort muss mindestens 6 Zeichen haben"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "Fehler beim Importieren von Benutzern"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "Es wurde keine Anwendung für die Benutzer-ID gefunden: %s",
"No provider for category: %s is found for application: %s": "Kein Anbieter für die Kategorie %s gefunden für die Anwendung: %s",
"The provider: %s is not found": "Der Anbieter: %s wurde nicht gefunden"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"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",
"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.",
"Unknown type": "Unbekannter Typ",
"Wrong parameter": "Falscher Parameter",
"Wrong verification code!": "Falscher Bestätigungscode!",
"You should verify your code in %d min!": "Du solltest deinen Code in %d Minuten verifizieren!",
"the user does not exist, please sign up first": "Der Benutzer existiert nicht, bitte zuerst anmelden"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "Es wurden keine Anmeldeinformationen für diesen Benutzer gefunden",
"Please call WebAuthnSigninBegin first": "Bitte rufen Sie zuerst WebAuthnSigninBegin auf"
}
}

View File

@@ -1,9 +1,8 @@
{
"account": {
"Failed to add user": "Failed to add user",
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"Please sign out first": "Please sign out first",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
},
"auth": {
@@ -17,10 +16,7 @@
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
},
@@ -126,9 +122,7 @@
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"Turing test failed.": "Turing test failed.",
"Unable to get the email modify rule.": "Unable to get the email modify rule.",

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "No se pudo agregar el usuario",
"Get init score failed, error: %w": "Error al obtener el puntaje de inicio, error: %w",
"Please sign out first": "Por favor, cierra sesión primero",
"The application does not allow to sign up new account": "La aplicación no permite registrarse con una cuenta nueva"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "El método de desafío debe ser S256",
"Failed to create user, user information is invalid: %s": "No se pudo crear el usuario, la información del usuario es inválida: %s",
"Failed to login in: %s": "No se ha podido iniciar sesión en: %s",
"Invalid token": "Token inválido",
"State expected: %s, but got: %s": "Estado esperado: %s, pero se obtuvo: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "La cuenta para el proveedor: %s y nombre de usuario: %s (%s) no existe y no está permitido registrarse como una cuenta nueva a través de %%s, por favor use otro método para registrarse",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "La cuenta para el proveedor: %s y el nombre de usuario: %s (%s) no existe y no se permite registrarse como una nueva cuenta, por favor contacte a su soporte de TI",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "La cuenta para proveedor: %s y nombre de usuario: %s (%s) ya está vinculada a otra cuenta: %s (%s)",
"The application: %s does not exist": "La aplicación: %s no existe",
"The login method: login with password is not enabled for the application": "El método de inicio de sesión: inicio de sesión con contraseña no está habilitado para la aplicación",
"The provider: %s is not enabled for the application": "El proveedor: %s no está habilitado para la aplicación",
"Unauthorized operation": "Operación no autorizada",
"Unknown authentication type (not password or provider), form = %s": "Tipo de autenticación desconocido (no es contraseña o proveedor), formulario = %s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "Los servicios %s y %s no coinciden"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"Affiliation cannot be blank": "Afiliación no puede estar en blanco",
"DisplayName cannot be blank": "El nombre de visualización no puede estar en blanco",
"DisplayName is not valid real name": "El nombre de pantalla no es un nombre real válido",
"Email already exists": "El correo electrónico ya existe",
"Email cannot be empty": "El correo electrónico no puede estar vacío",
"Email is invalid": "El correo electrónico no es válido",
"Empty username.": "Nombre de usuario vacío.",
"FirstName cannot be blank": "El nombre no puede estar en blanco",
"LastName cannot be blank": "El apellido no puede estar en blanco",
"Ldap user name or password incorrect": "Nombre de usuario o contraseña de Ldap incorrectos",
"Multiple accounts with same uid, please check your ldap server": "Cuentas múltiples con el mismo uid, por favor revise su servidor ldap",
"Organization does not exist": "La organización no existe",
"Password must have at least 6 characters": "La contraseña debe tener al menos 6 caracteres",
"Phone already exists": "El teléfono ya existe",
"Phone cannot be empty": "Teléfono no puede estar vacío",
"Phone number is invalid": "El número de teléfono no es válido",
"Session outdated, please login again": "Sesión expirada, por favor vuelva a iniciar sesión",
"The user is forbidden to sign in, please contact the administrator": "El usuario no está autorizado a iniciar sesión, por favor contacte al administrador",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "El nombre de usuario solo puede contener caracteres alfanuméricos, guiones bajos o guiones, no puede tener guiones o subrayados consecutivos, y no puede comenzar ni terminar con un guión o subrayado.",
"Username already exists": "El nombre de usuario ya existe",
"Username cannot be an email address": "Nombre de usuario no puede ser una dirección de correo electrónico",
"Username cannot contain white spaces": "Nombre de usuario no puede contener espacios en blanco",
"Username cannot start with a digit": "El nombre de usuario no puede empezar con un dígito",
"Username is too long (maximum is 39 characters).": "El nombre de usuario es demasiado largo (el máximo es de 39 caracteres).",
"Username must have at least 2 characters": "Nombre de usuario debe tener al menos 2 caracteres",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Has ingresado la contraseña o código incorrecto demasiadas veces, por favor espera %d minutos e intenta de nuevo",
"Your region is not allow to signup by phone": "Tu región no está permitida para registrarse por teléfono",
"password or code is incorrect, you have %d remaining chances": "Contraseña o código incorrecto, tienes %d intentos restantes",
"unsupported password type: %s": "Tipo de contraseña no compatible: %s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "Parámetro faltante",
"Please login first": "Por favor, inicia sesión primero",
"The user: %s doesn't exist": "El usuario: %s no existe",
"don't support captchaProvider: ": "No apoyo a captchaProvider"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "El servidor LDAP existe"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "Por favor, enlaza primero",
"This application has no providers": "Esta aplicación no tiene proveedores",
"This application has no providers of type": "Esta aplicación no tiene proveedores del tipo",
"This provider can't be unlinked": "Este proveedor no se puede desvincular",
"You are not the global admin, you can't unlink other users": "No eres el administrador global, no puedes desvincular a otros usuarios",
"You can't unlink yourself, you are not a member of any application": "No puedes desvincularte, no eres miembro de ninguna aplicación"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "Solo el administrador puede modificar los %s.",
"The %s is immutable.": "El %s es inmutable.",
"Unknown modify rule %s.": "Regla de modificación desconocida %s."
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "Identificación de aplicación no válida",
"the provider: %s does not exist": "El proveedor: %s no existe"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "El usuario es nulo para la etiqueta: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Nombre de usuario o ruta completa de archivo está vacío: nombre de usuario = %s, ruta completa de archivo = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "Aplicación %s no encontrada"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "La categoría del proveedor %s no es SAML"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "Parámetros vacíos para el formulario de correo electrónico: %v",
"Invalid Email receivers: %s": "Receptores de correo electrónico no válidos: %s",
"Invalid phone receivers: %s": "Receptores de teléfono no válidos: %s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "El objectKey: %s no está permitido",
"The provider type: %s is not supported": "El tipo de proveedor: %s no es compatible"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "ClienteId o clienteSecret vacío",
"Grant_type: %s is not supported in this application": "El tipo de subvención: %s no es compatible con esta aplicación",
"Invalid application or wrong clientSecret": "Solicitud inválida o clientSecret incorrecto",
"Invalid client_id": "Identificador de cliente no válido",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "El URI de redirección: %s no existe en la lista de URI de redirección permitidos",
"Token not found, invalid accessToken": "Token no encontrado, accessToken inválido"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "El nombre de pantalla no puede estar vacío",
"New password cannot contain blank space.": "La nueva contraseña no puede contener espacios en blanco.",
"New password must have at least 6 characters": "La nueva contraseña debe tener al menos 6 caracteres"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "Error al importar usuarios"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "No se encuentra ninguna aplicación para el Id de usuario: %s",
"No provider for category: %s is found for application: %s": "No se encuentra un proveedor para la categoría: %s para la aplicación: %s",
"The provider: %s is not found": "El proveedor: %s no se encuentra"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"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",
"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.",
"Unknown type": "Tipo desconocido",
"Wrong parameter": "Parámetro incorrecto",
"Wrong verification code!": "¡Código de verificación incorrecto!",
"You should verify your code in %d min!": "¡Deberías verificar tu código en %d minutos!",
"the user does not exist, please sign up first": "El usuario no existe, por favor regístrese primero"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "No se encontraron credenciales para este usuario",
"Please call WebAuthnSigninBegin first": "Por favor, llama primero a WebAuthnSigninBegin"
}
}

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "Échec d'ajout d'utilisateur",
"Get init score failed, error: %w": "Obtention du score initiale échouée, erreur : %w",
"Please sign out first": "Veuillez vous déconnecter en premier",
"The application does not allow to sign up new account": "L'application ne permet pas de créer un nouveau compte"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "La méthode de défi doit être S256",
"Failed to create user, user information is invalid: %s": "Échec de la création de l'utilisateur, les informations utilisateur sont invalides : %s",
"Failed to login in: %s": "Échec de la connexion : %s",
"Invalid token": "Jeton invalide",
"State expected: %s, but got: %s": "État attendu : %s, mais obtenu : %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Le compte pour le fournisseur : %s et le nom d'utilisateur : %s (%s) n'existe pas et n'est pas autorisé à s'inscrire en tant que nouveau compte via %%s, veuillez utiliser une autre méthode pour vous inscrire",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Le compte pour le fournisseur : %s et le nom d'utilisateur : %s (%s) n'existe pas et n'est pas autorisé à s'inscrire comme nouveau compte, veuillez contacter votre support informatique",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Le compte du fournisseur : %s et le nom d'utilisateur : %s (%s) sont déjà liés à un autre compte : %s (%s)",
"The application: %s does not exist": "L'application : %s n'existe pas",
"The login method: login with password is not enabled for the application": "La méthode de connexion : connexion avec mot de passe n'est pas activée pour l'application",
"The provider: %s is not enabled for the application": "Le fournisseur :%s n'est pas activé pour l'application",
"Unauthorized operation": "Opération non autorisée",
"Unknown authentication type (not password or provider), form = %s": "Type d'authentification inconnu (pas de mot de passe ou de fournisseur), formulaire = %s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "Les services %s et %s ne correspondent pas"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"Affiliation cannot be blank": "Affiliation ne peut pas être vide",
"DisplayName cannot be blank": "Le nom d'affichage ne peut pas être vide",
"DisplayName is not valid real name": "DisplayName n'est pas un nom réel valide",
"Email already exists": "E-mail déjà existant",
"Email cannot be empty": "L'e-mail ne peut pas être vide",
"Email is invalid": "L'adresse e-mail est invalide",
"Empty username.": "Nom d'utilisateur vide.",
"FirstName cannot be blank": "Le prénom ne peut pas être laissé vide",
"LastName cannot be blank": "Le nom de famille ne peut pas être vide",
"Ldap user name or password incorrect": "Nom d'utilisateur ou mot de passe LDAP incorrect",
"Multiple accounts with same uid, please check your ldap server": "Plusieurs comptes avec le même identifiant d'utilisateur, veuillez vérifier votre serveur LDAP",
"Organization does not exist": "L'organisation n'existe pas",
"Password must have at least 6 characters": "Le mot de passe doit comporter au moins 6 caractères",
"Phone already exists": "Le téléphone existe déjà",
"Phone cannot be empty": "Le téléphone ne peut pas être vide",
"Phone number is invalid": "Le numéro de téléphone est invalide",
"Session outdated, please login again": "Session expirée, veuillez vous connecter à nouveau",
"The user is forbidden to sign in, please contact the administrator": "L'utilisateur est interdit de se connecter, veuillez contacter l'administrateur",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Le nom d'utilisateur ne peut contenir que des caractères alphanumériques, des traits soulignés ou des tirets, ne peut pas avoir de tirets ou de traits soulignés consécutifs et ne peut pas commencer ou se terminer par un tiret ou un trait souligné.",
"Username already exists": "Nom d'utilisateur existe déjà",
"Username cannot be an email address": "Nom d'utilisateur ne peut pas être une adresse e-mail",
"Username cannot contain white spaces": "Nom d'utilisateur ne peut pas contenir d'espaces blancs",
"Username cannot start with a digit": "Nom d'utilisateur ne peut pas commencer par un chiffre",
"Username is too long (maximum is 39 characters).": "Nom d'utilisateur est trop long (maximum de 39 caractères).",
"Username must have at least 2 characters": "Le nom d'utilisateur doit comporter au moins 2 caractères",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Vous avez entré le mauvais mot de passe ou code plusieurs fois, veuillez attendre %d minutes et réessayer",
"Your region is not allow to signup by phone": "Votre région n'est pas autorisée à s'inscrire par téléphone",
"password or code is incorrect, you have %d remaining chances": "Le mot de passe ou le code est incorrect, il vous reste %d chances",
"unsupported password type: %s": "Type de mot de passe non pris en charge : %s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "Paramètre manquant",
"Please login first": "Veuillez d'abord vous connecter",
"The user: %s doesn't exist": "L'utilisateur : %s n'existe pas",
"don't support captchaProvider: ": "Ne pas prendre en charge la captchaProvider"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "Le serveur LDAP existe"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "Veuillez d'abord faire le lien",
"This application has no providers": "Cette application n'a aucun fournisseur",
"This application has no providers of type": "Cette application ne dispose d'aucun fournisseur de type",
"This provider can't be unlinked": "Ce fournisseur ne peut pas être dissocié",
"You are not the global admin, you can't unlink other users": "Vous n'êtes pas l'administrateur global, vous ne pouvez pas détacher d'autres utilisateurs",
"You can't unlink yourself, you are not a member of any application": "Vous ne pouvez pas vous désolidariser, car vous n'êtes membre d'aucune application"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "Seul l'administrateur peut modifier le %s.",
"The %s is immutable.": "Le %s est immuable.",
"Unknown modify rule %s.": "Règle de modification inconnue %s."
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "Identifiant d'application invalide",
"the provider: %s does not exist": "Le fournisseur : %s n'existe pas"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "L'utilisateur est nul pour la balise : avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Nom d'utilisateur ou chemin complet du fichier est vide : nom d'utilisateur = %s, chemin complet du fichier = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "L'application %s n'a pas été trouvée"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "La catégorie du fournisseur %s n'est pas SAML"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "Paramètres vides pour emailForm : %v",
"Invalid Email receivers: %s": "Destinataires d'e-mail invalides : %s",
"Invalid phone receivers: %s": "Destinataires de téléphone invalide : %s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "La clé d'objet : %s n'est pas autorisée",
"The provider type: %s is not supported": "Le type de fournisseur : %s n'est pas pris en charge"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "clientId ou clientSecret vide",
"Grant_type: %s is not supported in this application": "Type_de_subvention : %s n'est pas pris en charge dans cette application",
"Invalid application or wrong clientSecret": "Application invalide ou clientSecret incorrect",
"Invalid client_id": "Identifiant de client invalide",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "URI de redirection: %s n'existe pas dans la liste des URI de redirection autorisés",
"Token not found, invalid accessToken": "Jeton non trouvé, accessToken invalide"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "Le nom d'affichage ne peut pas être vide",
"New password cannot contain blank space.": "Le nouveau mot de passe ne peut pas contenir d'espace.",
"New password must have at least 6 characters": "Le nouveau mot de passe doit comporter au moins 6 caractères"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "Échec de l'importation des utilisateurs"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "Aucune application n'a été trouvée pour l'identifiant d'utilisateur : %s",
"No provider for category: %s is found for application: %s": "Aucun fournisseur pour la catégorie: %s n'est trouvé pour l'application: %s",
"The provider: %s is not found": "Le fournisseur : %s n'a pas été trouvé"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"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",
"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.",
"Unknown type": "Type inconnu",
"Wrong parameter": "Mauvais paramètre",
"Wrong verification code!": "Mauvais code de vérification !",
"You should verify your code in %d min!": "Vous devriez vérifier votre code en %d min !",
"the user does not exist, please sign up first": "L'utilisateur n'existe pas, veuillez vous inscrire d'abord"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "Aucune référence trouvée pour cet utilisateur",
"Please call WebAuthnSigninBegin first": "Veuillez d'abord appeler WebAuthnSigninBegin"
}
}

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "Gagal menambahkan pengguna",
"Get init score failed, error: %w": "Gagal mendapatkan nilai init, kesalahan: %w",
"Please sign out first": "Silakan keluar terlebih dahulu",
"The application does not allow to sign up new account": "Aplikasi tidak memperbolehkan untuk mendaftar akun baru"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "Metode tantangan harus S256",
"Failed to create user, user information is invalid: %s": "Gagal membuat pengguna, informasi pengguna tidak valid: %s",
"Failed to login in: %s": "Gagal masuk: %s",
"Invalid token": "Token tidak valid",
"State expected: %s, but got: %s": "Diharapkan: %s, tapi diperoleh: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Akun untuk penyedia: %s dan nama pengguna: %s (%s) tidak ada dan tidak diizinkan untuk mendaftar sebagai akun baru melalui %%s, silakan gunakan cara lain untuk mendaftar",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Akun untuk penyedia: %s dan nama pengguna: %s (%s) tidak ada dan tidak diizinkan untuk mendaftar sebagai akun baru, silakan hubungi dukungan IT Anda",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Akun untuk provider: %s dan username: %s (%s) sudah terhubung dengan akun lain: %s (%s)",
"The application: %s does not exist": "Aplikasi: %s tidak ada",
"The login method: login with password is not enabled for the application": "Metode login: login dengan kata sandi tidak diaktifkan untuk aplikasi tersebut",
"The provider: %s is not enabled for the application": "Penyedia: %s tidak diaktifkan untuk aplikasi ini",
"Unauthorized operation": "Operasi tidak sah",
"Unknown authentication type (not password or provider), form = %s": "Jenis otentikasi tidak diketahui (bukan kata sandi atau pemberi), formulir = %s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "Layanan %s dan %s tidak cocok"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"Affiliation cannot be blank": "Keterkaitan tidak boleh kosong",
"DisplayName cannot be blank": "Nama Pengguna tidak boleh kosong",
"DisplayName is not valid real name": "DisplayName bukanlah nama asli yang valid",
"Email already exists": "Email sudah ada",
"Email cannot be empty": "Email tidak boleh kosong",
"Email is invalid": "Email tidak valid",
"Empty username.": "Nama pengguna kosong.",
"FirstName cannot be blank": "Nama depan tidak boleh kosong",
"LastName cannot be blank": "Nama belakang tidak boleh kosong",
"Ldap user name or password incorrect": "Nama pengguna atau kata sandi Ldap salah",
"Multiple accounts with same uid, please check your ldap server": "Beberapa akun dengan uid yang sama, harap periksa server ldap Anda",
"Organization does not exist": "Organisasi tidak ada",
"Password must have at least 6 characters": "Kata sandi harus memiliki minimal 6 karakter",
"Phone already exists": "Telepon sudah ada",
"Phone cannot be empty": "Telepon tidak boleh kosong",
"Phone number is invalid": "Nomor telepon tidak valid",
"Session outdated, please login again": "Sesi kedaluwarsa, silakan masuk lagi",
"The user is forbidden to sign in, please contact the administrator": "Pengguna dilarang masuk, silakan hubungi administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Nama pengguna hanya bisa menggunakan karakter alfanumerik, garis bawah atau tanda hubung, tidak boleh memiliki dua tanda hubung atau garis bawah berurutan, dan tidak boleh diawali atau diakhiri dengan tanda hubung atau garis bawah.",
"Username already exists": "Nama pengguna sudah ada",
"Username cannot be an email address": "Username tidak bisa menjadi alamat email",
"Username cannot contain white spaces": "Username tidak boleh mengandung spasi",
"Username cannot start with a digit": "Username tidak dapat dimulai dengan angka",
"Username is too long (maximum is 39 characters).": "Nama pengguna terlalu panjang (maksimum 39 karakter).",
"Username must have at least 2 characters": "Nama pengguna harus memiliki setidaknya 2 karakter",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Anda telah memasukkan kata sandi atau kode yang salah terlalu banyak kali, mohon tunggu selama %d menit dan coba lagi",
"Your region is not allow to signup by phone": "Wilayah Anda tidak diizinkan untuk mendaftar melalui telepon",
"password or code is incorrect, you have %d remaining chances": "Kata sandi atau kode salah, Anda memiliki %d kesempatan tersisa",
"unsupported password type: %s": "jenis sandi tidak didukung: %s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "Parameter hilang",
"Please login first": "Silahkan login terlebih dahulu",
"The user: %s doesn't exist": "Pengguna: %s tidak ada",
"don't support captchaProvider: ": "Jangan mendukung captchaProvider:"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "Server ldap ada"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "Tolong tautkan terlebih dahulu",
"This application has no providers": "Aplikasi ini tidak memiliki penyedia",
"This application has no providers of type": " Aplikasi ini tidak memiliki penyedia tipe ",
"This provider can't be unlinked": "Pemberi layanan ini tidak dapat dipisahkan",
"You are not the global admin, you can't unlink other users": "Anda bukan admin global, Anda tidak dapat memutuskan tautan pengguna lain",
"You can't unlink yourself, you are not a member of any application": "Anda tidak dapat memutuskan tautan diri sendiri, karena Anda bukan anggota dari aplikasi apa pun"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "Hanya admin yang dapat memodifikasi %s.",
"The %s is immutable.": "%s tidak dapat diubah.",
"Unknown modify rule %s.": "Aturan modifikasi tidak diketahui %s."
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "ID aplikasi tidak valid",
"the provider: %s does not exist": "provider: %s tidak ada"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "Pengguna kosong untuk tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Nama pengguna atau path lengkap file kosong: nama_pengguna = %s, path_lengkap_file = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "Aplikasi %s tidak ditemukan"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "kategori penyedia %s bukan SAML"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "Parameter kosong untuk emailForm: %v",
"Invalid Email receivers: %s": "Penerima email tidak valid: %s",
"Invalid phone receivers: %s": "Penerima telepon tidak valid: %s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "Kunci objek: %s tidak diizinkan",
"The provider type: %s is not supported": "Jenis penyedia: %s tidak didukung"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "Kosong clientId atau clientSecret",
"Grant_type: %s is not supported in this application": "Jenis grant (grant_type) %s tidak didukung dalam aplikasi ini",
"Invalid application or wrong clientSecret": "Aplikasi tidak valid atau clientSecret salah",
"Invalid client_id": "Invalid client_id = ID klien tidak valid",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "URI pengalihan: %s tidak ada dalam daftar URI Pengalihan yang diizinkan",
"Token not found, invalid accessToken": "Token tidak ditemukan, accessToken tidak valid"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "Nama tampilan tidak boleh kosong",
"New password cannot contain blank space.": "Kata sandi baru tidak boleh mengandung spasi kosong.",
"New password must have at least 6 characters": "Kata sandi baru harus memiliki setidaknya 6 karakter"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "Gagal mengimpor pengguna"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "Tidak ditemukan aplikasi untuk userId: %s",
"No provider for category: %s is found for application: %s": "Tidak ditemukan penyedia untuk kategori: %s untuk aplikasi: %s",
"The provider: %s is not found": "Penyedia: %s tidak ditemukan"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"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",
"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.",
"Unknown type": "Tipe tidak diketahui",
"Wrong parameter": "Parameter yang salah",
"Wrong verification code!": "Kode verifikasi salah!",
"You should verify your code in %d min!": "Anda harus memverifikasi kode Anda dalam %d menit!",
"the user does not exist, please sign up first": "Pengguna tidak ada, silakan daftar terlebih dahulu"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "Tidak ditemukan kredensial untuk pengguna ini",
"Please call WebAuthnSigninBegin first": "Harap panggil WebAuthnSigninBegin terlebih dahulu"
}
}

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "ユーザーの追加に失敗しました",
"Get init score failed, error: %w": "イニットスコアの取得に失敗しました。エラー:%w",
"Please sign out first": "最初にサインアウトしてください",
"The application does not allow to sign up new account": "アプリケーションは新しいアカウントの登録を許可しません"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "チャレンジメソッドはS256である必要があります",
"Failed to create user, user information is invalid: %s": "ユーザーの作成に失敗しました。ユーザー情報が無効です:%s",
"Failed to login in: %s": "ログインできませんでした:%s",
"Invalid token": "無効なトークン",
"State expected: %s, but got: %s": "期待される状態: %s、実際には%s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "プロバイダーのアカウント:%s とユーザー名:%s%sが存在せず、新しいアカウントを %%s 経由でサインアップすることはできません。他の方法でサインアップしてください",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "プロバイダー名:%sとユーザー名%s%sのアカウントは存在しません。新しいアカウントとしてサインアップすることはできません。 ITサポートに連絡してください",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "プロバイダのアカウント:%s とユーザー名:%s (%s) は既に別のアカウント:%s (%s) にリンクされています",
"The application: %s does not exist": "アプリケーション: %sは存在しません",
"The login method: login with password is not enabled for the application": "ログイン方法:パスワードでのログインはアプリケーションで有効になっていません",
"The provider: %s is not enabled for the application": "プロバイダー:%sはアプリケーションでは有効化されていません",
"Unauthorized operation": "不正操作",
"Unknown authentication type (not password or provider), form = %s": "不明な認証タイプ(パスワードまたはプロバイダーではない)フォーム=%s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "サービス%sと%sは一致しません"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"Affiliation cannot be blank": "所属は空白にできません",
"DisplayName cannot be blank": "表示名は空白にできません",
"DisplayName is not valid real name": "表示名は有効な実名ではありません",
"Email already exists": "メールは既に存在します",
"Email cannot be empty": "メールが空白にできません",
"Email is invalid": "電子メールは無効です",
"Empty username.": "空のユーザー名。",
"FirstName cannot be blank": "ファーストネームは空白にできません",
"LastName cannot be blank": "姓は空白にできません",
"Ldap user name or password incorrect": "Ldapのユーザー名またはパスワードが間違っています",
"Multiple accounts with same uid, please check your ldap server": "同じuidを持つ複数のアカウントがあります。あなたのLDAPサーバーを確認してください",
"Organization does not exist": "組織は存在しません",
"Password must have at least 6 characters": "パスワードは少なくとも6つの文字が必要です",
"Phone already exists": "電話はすでに存在しています",
"Phone cannot be empty": "電話は空っぽにできません",
"Phone number is invalid": "電話番号が無効です",
"Session outdated, please login again": "セッションが期限切れになりました。再度ログインしてください",
"The user is forbidden to sign in, please contact the administrator": "ユーザーはサインインできません。管理者に連絡してください",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "ユーザー名には英数字、アンダースコア、ハイフンしか含めることができません。連続したハイフンまたはアンダースコアは不可であり、ハイフンまたはアンダースコアで始まるまたは終わることもできません。",
"Username already exists": "ユーザー名はすでに存在しています",
"Username cannot be an email address": "ユーザー名には電子メールアドレスを使用できません",
"Username cannot contain white spaces": "ユーザ名にはスペースを含めることはできません",
"Username cannot start with a digit": "ユーザー名は数字で始めることはできません",
"Username is too long (maximum is 39 characters).": "ユーザー名が長すぎます最大39文字",
"Username must have at least 2 characters": "ユーザー名は少なくとも2文字必要です",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "あなたは間違ったパスワードまたはコードを何度も入力しました。%d 分間待ってから再度お試しください",
"Your region is not allow to signup by phone": "あなたの地域は電話でサインアップすることができません",
"password or code is incorrect, you have %d remaining chances": "パスワードまたはコードが間違っています。あと%d回の試行機会があります",
"unsupported password type: %s": "サポートされていないパスワードタイプ:%s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "不足しているパラメーター",
"Please login first": "最初にログインしてください",
"The user: %s doesn't exist": "そのユーザー:%sは存在しません",
"don't support captchaProvider: ": "captchaProviderをサポートしないでください"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "LDAPサーバーは存在します"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "最初にリンクしてください",
"This application has no providers": "このアプリケーションにはプロバイダーがありません",
"This application has no providers of type": "「このアプリケーションには、タイプのプロバイダーがありません」と翻訳されます",
"This provider can't be unlinked": "このプロバイダーはリンク解除できません",
"You are not the global admin, you can't unlink other users": "あなたはグローバル管理者ではありません、他のユーザーとのリンクを解除することはできません",
"You can't unlink yourself, you are not a member of any application": "あなたは自分自身をアンリンクすることはできません、あなたはどのアプリケーションのメンバーでもありません"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "管理者のみが%sを変更できます。",
"The %s is immutable.": "%sは不変です。",
"Unknown modify rule %s.": "未知の変更ルール%s"
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "アプリケーションIDが無効です",
"the provider: %s does not exist": "プロバイダー%sは存在しません"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "ユーザーはタグ「アバター」に対してnilです",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "ユーザー名または完全なファイルパスが空です:ユーザー名 = %s、完全なファイルパス = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "アプリケーション%sは見つかりません"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "プロバイダ %s のカテゴリはSAMLではありません"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "EmailFormの空のパラメーターv",
"Invalid Email receivers: %s": "無効な電子メール受信者:%s",
"Invalid phone receivers: %s": "電話受信者が無効です:%s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "オブジェクトキー %s は許可されていません",
"The provider type: %s is not supported": "プロバイダータイプ:%sはサポートされていません"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "クライアントIDまたはクライアントシークレットが空です",
"Grant_type: %s is not supported in this application": "grant_type%sはこのアプリケーションでサポートされていません",
"Invalid application or wrong clientSecret": "無効なアプリケーションまたは誤ったクライアントシークレットです",
"Invalid client_id": "client_idが無効です",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "リダイレクトURI%sは許可されたリダイレクトURIリストに存在しません",
"Token not found, invalid accessToken": "トークンが見つかりません。無効なアクセストークンです"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "表示名は空にできません",
"New password cannot contain blank space.": "新しいパスワードにはスペースを含めることはできません。",
"New password must have at least 6 characters": "新しいパスワードは少なくとも6文字必要です"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "ユーザーのインポートに失敗しました"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "ユーザーIDに対するアプリケーションが見つかりません %s",
"No provider for category: %s is found for application: %s": "アプリケーション:%sのカテゴリ%sのプロバイダが見つかりません",
"The provider: %s is not found": "プロバイダー:%sが見つかりません"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"Code has not been sent yet!": "まだコードが送信されていません!",
"Invalid captcha provider.": "無効なCAPTCHAプロバイダー。",
"Phone number is invalid in your region %s": "電話番号はあなたの地域で無効です %s",
"Turing test failed.": "チューリングテストは失敗しました。",
"Unable to get the email modify rule.": "電子メール変更規則を取得できません。",
"Unable to get the phone modify rule.": "電話の変更ルールを取得できません。",
"Unknown type": "不明なタイプ",
"Wrong parameter": "誤ったパラメータ",
"Wrong verification code!": "誤った検証コードです!",
"You should verify your code in %d min!": "あなたは%d分であなたのコードを確認する必要があります",
"the user does not exist, please sign up first": "ユーザーは存在しません。まず登録してください"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "このユーザーの資格情報が見つかりませんでした",
"Please call WebAuthnSigninBegin first": "最初にWebAuthnSigninBeginを呼び出してください"
}
}

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "사용자 추가 실패",
"Get init score failed, error: %w": "초기 점수 획득 실패, 오류: %w",
"Please sign out first": "먼저 로그아웃해주세요",
"The application does not allow to sign up new account": "이 응용 프로그램은 새로운 계정 가입을 허용하지 않습니다"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "도전 방식은 S256이어야 합니다",
"Failed to create user, user information is invalid: %s": "사용자를 만들지 못했습니다. 사용자 정보가 잘못되었습니다: %s",
"Failed to login in: %s": "로그인에 실패했습니다.: %s",
"Invalid token": "유효하지 않은 토큰",
"State expected: %s, but got: %s": "예상한 상태: %s, 실제 상태: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "제공자 계정: %s와 사용자 이름: %s (%s)은(는) 존재하지 않으며 %%s를 통해 새 계정으로 가입하는 것이 허용되지 않습니다. 다른 방법으로 가입하십시오",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "공급자 계정 %s과 사용자 이름 %s (%s)는 존재하지 않으며 새 계정으로 등록할 수 없습니다. IT 지원팀에 문의하십시오",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "공급자 계정 %s과 사용자 이름 %s(%s)는 이미 다른 계정 %s(%s)에 연결되어 있습니다",
"The application: %s does not exist": "해당 애플리케이션(%s)이 존재하지 않습니다",
"The login method: login with password is not enabled for the application": "어플리케이션에서는 암호를 사용한 로그인 방법이 활성화되어 있지 않습니다",
"The provider: %s is not enabled for the application": "제공자 %s은(는) 응용 프로그램에서 활성화되어 있지 않습니다",
"Unauthorized operation": "무단 조작",
"Unknown authentication type (not password or provider), form = %s": "알 수 없는 인증 유형(암호 또는 공급자가 아님), 폼 = %s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "서비스 %s와 %s는 일치하지 않습니다"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"Affiliation cannot be blank": "소속은 비워 둘 수 없습니다",
"DisplayName cannot be blank": "DisplayName는 비어 있을 수 없습니다",
"DisplayName is not valid real name": "DisplayName는 유효한 실제 이름이 아닙니다",
"Email already exists": "이메일이 이미 존재합니다",
"Email cannot be empty": "이메일은 비어 있을 수 없습니다",
"Email is invalid": "이메일이 유효하지 않습니다",
"Empty username.": "빈 사용자 이름.",
"FirstName cannot be blank": "이름은 공백일 수 없습니다",
"LastName cannot be blank": "성은 비어 있을 수 없습니다",
"Ldap user name or password incorrect": "LDAP 사용자 이름 또는 암호가 잘못되었습니다",
"Multiple accounts with same uid, please check your ldap server": "동일한 UID를 가진 여러 계정이 있습니다. LDAP 서버를 확인해주세요",
"Organization does not exist": "조직은 존재하지 않습니다",
"Password must have at least 6 characters": "암호는 적어도 6자 이상이어야 합니다",
"Phone already exists": "전화기는 이미 존재합니다",
"Phone cannot be empty": "전화는 비워 둘 수 없습니다",
"Phone number is invalid": "전화번호가 유효하지 않습니다",
"Session outdated, please login again": "세션이 만료되었습니다. 다시 로그인해주세요",
"The user is forbidden to sign in, please contact the administrator": "사용자는 로그인이 금지되어 있습니다. 관리자에게 문의하십시오",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "사용자 이름은 알파벳, 숫자, 밑줄 또는 하이픈만 포함할 수 있으며, 연속된 하이픈 또는 밑줄을 가질 수 없으며, 하이픈 또는 밑줄로 시작하거나 끝날 수 없습니다.",
"Username already exists": "사용자 이름이 이미 존재합니다",
"Username cannot be an email address": "사용자 이름은 이메일 주소가 될 수 없습니다",
"Username cannot contain white spaces": "사용자 이름에는 공백이 포함될 수 없습니다",
"Username cannot start with a digit": "사용자 이름은 숫자로 시작할 수 없습니다",
"Username is too long (maximum is 39 characters).": "사용자 이름이 너무 깁니다 (최대 39자).",
"Username must have at least 2 characters": "사용자 이름은 적어도 2개의 문자가 있어야 합니다",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "올바르지 않은 비밀번호나 코드를 여러 번 입력했습니다. %d분 동안 기다리신 후 다시 시도해주세요",
"Your region is not allow to signup by phone": "당신의 지역은 전화로 가입할 수 없습니다",
"password or code is incorrect, you have %d remaining chances": "암호 또는 코드가 올바르지 않습니다. %d번의 기회가 남아 있습니다",
"unsupported password type: %s": "지원되지 않는 암호 유형: %s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "누락된 매개변수",
"Please login first": "먼저 로그인 하십시오",
"The user: %s doesn't exist": "사용자 %s는 존재하지 않습니다",
"don't support captchaProvider: ": "CaptchaProvider를 지원하지 마세요"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "LDAP 서버가 존재합니다"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "먼저 링크해주세요",
"This application has no providers": "이 애플리케이션에는 제공자가 없습니다",
"This application has no providers of type": "이 응용 프로그램은 타입의 공급자가 없습니다",
"This provider can't be unlinked": "이 공급자는 연결이 해제될 수 없습니다",
"You are not the global admin, you can't unlink other users": "당신은 전역 관리자가 아니므로 다른 사용자와의 연결을 해제할 수 없습니다",
"You can't unlink yourself, you are not a member of any application": "당신은 어떤 애플리케이션의 회원이 아니기 때문에 스스로 링크를 해제할 수 없습니다"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "관리자만 %s을(를) 수정할 수 있습니다.",
"The %s is immutable.": "%s 는 변경할 수 없습니다.",
"Unknown modify rule %s.": "미확인 수정 규칙 %s."
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "잘못된 애플리케이션 ID입니다",
"the provider: %s does not exist": "제공자 %s가 존재하지 않습니다"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "사용자는 아바타 태그에 대해 nil입니다",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "사용자 이름 또는 전체 파일 경로가 비어 있습니다: 사용자 이름 = %s, 전체 파일 경로 = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "어플리케이션 %s을(를) 찾을 수 없습니다"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "제공 업체 %s의 카테고리는 SAML이 아닙니다"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "이메일 형식의 빈 매개 변수: %v",
"Invalid Email receivers: %s": "잘못된 이메일 수신자: %s",
"Invalid phone receivers: %s": "잘못된 전화 수신자: %s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "객체 키 : %s 는 허용되지 않습니다",
"The provider type: %s is not supported": "제공자 유형: %s은/는 지원되지 않습니다"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "클라이언트 ID 또는 클라이언트 비밀번호가 비어 있습니다",
"Grant_type: %s is not supported in this application": "그랜트 유형: %s은(는) 이 어플리케이션에서 지원되지 않습니다",
"Invalid application or wrong clientSecret": "잘못된 어플리케이션 또는 올바르지 않은 클라이언트 시크릿입니다",
"Invalid client_id": "잘못된 클라이언트 ID입니다",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "허용된 Redirect URI 목록에서 %s이(가) 존재하지 않습니다",
"Token not found, invalid accessToken": "토큰을 찾을 수 없습니다. 잘못된 액세스 토큰입니다"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "디스플레이 이름은 비어 있을 수 없습니다",
"New password cannot contain blank space.": "새 비밀번호에는 공백이 포함될 수 없습니다.",
"New password must have at least 6 characters": "새로운 비밀번호는 최소 6자 이상이어야 합니다"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "사용자 가져오기를 실패했습니다"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "어플리케이션을 찾을 수 없습니다. userId: %s",
"No provider for category: %s is found for application: %s": "어플리케이션 %s에서 %s 카테고리를 위한 공급자가 찾을 수 없습니다",
"The provider: %s is not found": "제공자: %s를 찾을 수 없습니다"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"Code has not been sent yet!": "코드는 아직 전송되지 않았습니다!",
"Invalid captcha provider.": "잘못된 captcha 제공자입니다.",
"Phone number is invalid in your region %s": "전화 번호가 당신의 지역 %s에서 유효하지 않습니다",
"Turing test failed.": "튜링 테스트 실패.",
"Unable to get the email modify rule.": "이메일 수정 규칙을 가져올 수 없습니다.",
"Unable to get the phone modify rule.": "전화 수정 규칙을 가져올 수 없습니다.",
"Unknown type": "알 수 없는 유형",
"Wrong parameter": "잘못된 매개 변수입니다",
"Wrong verification code!": "잘못된 인증 코드입니다!",
"You should verify your code in %d min!": "당신은 %d분 안에 코드를 검증해야 합니다!",
"the user does not exist, please sign up first": "사용자가 존재하지 않습니다. 먼저 회원 가입 해주세요"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "이 사용자의 자격 증명을 찾을 수 없습니다",
"Please call WebAuthnSigninBegin first": "WebAuthnSigninBegin을 먼저 호출해주세요"
}
}

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "Не удалось добавить пользователя",
"Get init score failed, error: %w": "Не удалось получить исходный балл, ошибка: %w",
"Please sign out first": "Пожалуйста, сначала выйдите из системы",
"The application does not allow to sign up new account": "Приложение не позволяет зарегистрироваться новому аккаунту"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "Метод испытаний должен быть S256",
"Failed to create user, user information is invalid: %s": "Не удалось создать пользователя, информация о пользователе недействительна: %s",
"Failed to login in: %s": "Не удалось войти в систему: %s",
"Invalid token": "Недействительный токен",
"State expected: %s, but got: %s": "Ожидался статус: %s, но получен: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Аккаунт провайдера: %s и имя пользователя: %s (%s) не существует и не может быть зарегистрирован через %%s, пожалуйста, используйте другой способ регистрации",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Аккаунт для провайдера: %s и имя пользователя: %s (%s) не существует и не может быть зарегистрирован как новый аккаунт. Пожалуйста, обратитесь в службу поддержки IT",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Аккаунт поставщика: %s и имя пользователя: %s (%s) уже связаны с другим аккаунтом: %s (%s)",
"The application: %s does not exist": "Приложение: %s не существует",
"The login method: login with password is not enabled for the application": "Метод входа: вход с паролем не включен для приложения",
"The provider: %s is not enabled for the application": "Провайдер: %s не включен для приложения",
"Unauthorized operation": "Несанкционированная операция",
"Unknown authentication type (not password or provider), form = %s": "Неизвестный тип аутентификации (не пароль и не провайдер), форма = %s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "Сервисы %s и %s не совпадают"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"Affiliation cannot be blank": "Принадлежность не может быть пустым значением",
"DisplayName cannot be blank": "Имя отображения не может быть пустым",
"DisplayName is not valid real name": "DisplayName не является действительным именем",
"Email already exists": "Электронная почта уже существует",
"Email cannot be empty": "Электронная почта не может быть пустой",
"Email is invalid": "Адрес электронной почты недействительный",
"Empty username.": "Пустое имя пользователя.",
"FirstName cannot be blank": "Имя не может быть пустым",
"LastName cannot be blank": "Фамилия не может быть пустой",
"Ldap user name or password incorrect": "Неправильное имя пользователя или пароль Ldap",
"Multiple accounts with same uid, please check your ldap server": "Множественные учетные записи с тем же UID. Пожалуйста, проверьте свой сервер LDAP",
"Organization does not exist": "Организация не существует",
"Password must have at least 6 characters": "Пароль должен содержать не менее 6 символов",
"Phone already exists": "Телефон уже существует",
"Phone cannot be empty": "Телефон не может быть пустым",
"Phone number is invalid": "Номер телефона является недействительным",
"Session outdated, please login again": "Сессия устарела, пожалуйста, войдите снова",
"The user is forbidden to sign in, please contact the administrator": "Пользователю запрещен вход, пожалуйста, обратитесь к администратору",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Имя пользователя может состоять только из буквенно-цифровых символов, нижних подчеркиваний или дефисов, не может содержать последовательные дефисы или подчеркивания, а также не может начинаться или заканчиваться на дефис или подчеркивание.",
"Username already exists": "Имя пользователя уже существует",
"Username cannot be an email address": "Имя пользователя не может быть адресом электронной почты",
"Username cannot contain white spaces": "Имя пользователя не может содержать пробелы",
"Username cannot start with a digit": "Имя пользователя не может начинаться с цифры",
"Username is too long (maximum is 39 characters).": "Имя пользователя слишком длинное (максимальная длина - 39 символов).",
"Username must have at least 2 characters": "Имя пользователя должно содержать не менее 2 символов",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Вы ввели неправильный пароль или код слишком много раз, пожалуйста, подождите %d минут и попробуйте снова",
"Your region is not allow to signup by phone": "Ваш регион не разрешает регистрацию по телефону",
"password or code is incorrect, you have %d remaining chances": "Неправильный пароль или код, у вас осталось %d попыток",
"unsupported password type: %s": "неподдерживаемый тип пароля: %s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "Отсутствующий параметр",
"Please login first": "Пожалуйста, сначала войдите в систему",
"The user: %s doesn't exist": "Пользователь %s не существует",
"don't support captchaProvider: ": "не поддерживайте captchaProvider:"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "LDAP-сервер существует"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "Пожалуйста, сначала установите ссылку",
"This application has no providers": "Это приложение не имеет провайдеров",
"This application has no providers of type": "Это приложение не имеет провайдеров данного типа",
"This provider can't be unlinked": "Этот провайдер не может быть отсоединен",
"You are not the global admin, you can't unlink other users": "Вы не являетесь глобальным администратором, вы не можете отсоединять других пользователей",
"You can't unlink yourself, you are not a member of any application": "Вы не можете отвязаться, так как вы не являетесь участником никакого приложения"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "Только администратор может изменять %s.",
"The %s is immutable.": "%s неизменяемый.",
"Unknown modify rule %s.": "Неизвестное изменение правила %s."
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "Неверный идентификатор приложения",
"the provider: %s does not exist": "провайдер: %s не существует"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "Пользователь равен нулю для тега: аватар",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Имя пользователя или полный путь к файлу пусты: имя_пользователя = %s, полный_путь_к_файлу = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "Приложение %s не найдено"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "категория провайдера %s не является SAML"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "Пустые параметры для emailForm: %v",
"Invalid Email receivers: %s": "Некорректные получатели электронной почты: %s",
"Invalid phone receivers: %s": "Некорректные получатели телефонных звонков: %s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "Объект «objectKey: %s» не разрешен",
"The provider type: %s is not supported": "Тип поставщика: %s не поддерживается"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "Пустой идентификатор клиента или секрет клиента",
"Grant_type: %s is not supported in this application": "Тип предоставления: %s не поддерживается в данном приложении",
"Invalid application or wrong clientSecret": "Недействительное приложение или неправильный clientSecret",
"Invalid client_id": "Недействительный идентификатор клиента",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "URI перенаправления: %s не существует в списке разрешенных URI перенаправления",
"Token not found, invalid accessToken": "Токен не найден, недействительный accessToken"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "Отображаемое имя не может быть пустым",
"New password cannot contain blank space.": "Новый пароль не может содержать пробелы.",
"New password must have at least 6 characters": "Новый пароль должен содержать не менее 6 символов"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "Не удалось импортировать пользователей"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "Не найдено заявки для пользователя с идентификатором: %s",
"No provider for category: %s is found for application: %s": "Нет поставщика для категории: %s для приложения: %s",
"The provider: %s is not found": "Поставщик: %s не найден"
},
"verification": {
"Code has not been sent yet!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"Code has not been sent yet!": "Код еще не был отправлен!",
"Invalid captcha provider.": "Недействительный поставщик CAPTCHA.",
"Phone number is invalid in your region %s": "Номер телефона недействителен в вашем регионе %s",
"Turing test failed.": "Тест Тьюринга не удался.",
"Unable to get the email modify rule.": "Невозможно получить правило изменения электронной почты.",
"Unable to get the phone modify rule.": "Невозможно получить правило изменения телефона.",
"Unknown type": "Неизвестный тип",
"Wrong parameter": "Неправильный параметр",
"Wrong verification code!": "Неправильный код подтверждения!",
"You should verify your code in %d min!": "Вы должны проверить свой код через %d минут!",
"the user does not exist, please sign up first": "Пользователь не существует, пожалуйста, сначала зарегистрируйтесь"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "Не найдено учетных данных для этого пользователя",
"Please call WebAuthnSigninBegin first": "Пожалуйста, сначала вызовите WebAuthnSigninBegin"
}
}

View File

@@ -1,146 +1,140 @@
{
"account": {
"Get init score failed, error: %w": "Get init score failed, error: %w",
"Invalid information": "Invalid information",
"Please sign out first before signing in": "Please sign out first before signing in",
"Please sign out first before signing up": "Please sign out first before signing up",
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
"Failed to add user": "Không thể thêm người dùng",
"Get init score failed, error: %w": "Lấy điểm khởi đầu thất bại, lỗi: %w",
"Please sign out first": "Vui lòng đăng xuất trước",
"The application does not allow to sign up new account": "Ứng dụng không cho phép đăng ký tài khoản mới"
},
"auth": {
"Challenge method should be S256": "Challenge method should be S256",
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
"Failed to login in: %s": "Failed to login in: %s",
"Invalid token": "Invalid token",
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
"The application: %s does not exist": "The application: %s does not exist",
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
"The provider type: %s is not supported": "The provider type: %s is not supported",
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"Turing test failed.": "Turing test failed.",
"Unauthorized operation": "Unauthorized operation",
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
"Challenge method should be S256": "Phương pháp thách thức nên là S256",
"Failed to create user, user information is invalid: %s": "Không thể to người dùng, thông tin người dùng không hợp lệ: %s",
"Failed to login in: %s": "Đăng nhập không thành công: %s",
"Invalid token": "Mã thông báo không hợp lệ",
"State expected: %s, but got: %s": "Trạng thái dự kiến: %s, nhưng nhận được: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "Tài khoản cho nhà cung cấp: %s và tên người dùng: %s (%s) không tồn tại và không được phép đăng ký làm tài khoản mới qua %%s, vui lòng sử dụng cách khác để đăng ký",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "Tài khoản cho nhà cung cấp: %s và tên người dùng: %s (%s) không tồn tại và không được phép đăng ký như một tài khoản mới, vui lòng liên hệ với bộ phận hỗ trợ công nghệ thông tin của bạn",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "Tài khoản cho nhà cung cấp: %s và tên người dùng: %s (%s) đã được liên kết với tài khoản khác: %s (%s)",
"The application: %s does not exist": "Ứng dụng: %s không tồn tại",
"The login method: login with password is not enabled for the application": "Phương thức đăng nhập: đăng nhập bằng mật khẩu không được kích hoạt cho ứng dụng",
"The provider: %s is not enabled for the application": "Nhà cung cấp: %s không được kích hoạt cho ứng dụng",
"Unauthorized operation": "Hoạt động không được ủy quyền",
"Unknown authentication type (not password or provider), form = %s": "Loại xác thực không xác định (không phải mật khẩu hoặc nhà cung cấp), biểu mẫu = %s"
},
"cas": {
"Service %s and %s do not match": "Service %s and %s do not match"
"Service %s and %s do not match": "Dịch sang tiếng Việt: Dịch vụ %s %s không khớp"
},
"check": {
"Affiliation cannot be blank": "Affiliation cannot be blank",
"DisplayName cannot be blank": "DisplayName cannot be blank",
"DisplayName is not valid real name": "DisplayName is not valid real name",
"Email already exists": "Email already exists",
"Email cannot be empty": "Email cannot be empty",
"Email is invalid": "Email is invalid",
"Empty username.": "Empty username.",
"FirstName cannot be blank": "FirstName cannot be blank",
"LastName cannot be blank": "LastName cannot be blank",
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
"Organization does not exist": "Organization does not exist",
"Password must have at least 6 characters": "Password must have at least 6 characters",
"Phone already exists": "Phone already exists",
"Phone cannot be empty": "Phone cannot be empty",
"Phone number is invalid": "Phone number is invalid",
"Session outdated, please login again": "Session outdated, please login again",
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
"Username already exists": "Username already exists",
"Username cannot be an email address": "Username cannot be an email address",
"Username cannot contain white spaces": "Username cannot contain white spaces",
"Username cannot start with a digit": "Username cannot start with a digit",
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
"Username must have at least 2 characters": "Username must have at least 2 characters",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
"unsupported password type: %s": "unsupported password type: %s"
"Affiliation cannot be blank": "Tình trạng liên kết không thể để trống",
"DisplayName cannot be blank": "Tên hiển thị không thể để trống",
"DisplayName is not valid real name": "DisplayName không phải là tên thật hợp lệ",
"Email already exists": "Email đã tồn tại",
"Email cannot be empty": "Email không thể để trống",
"Email is invalid": "Địa chỉ email không hợp lệ",
"Empty username.": "Tên đăng nhập trống.",
"FirstName cannot be blank": "Tên không được để trống",
"LastName cannot be blank": "Họ không thể để trống",
"Ldap user name or password incorrect": "Tên người dùng hoặc mật khẩu Ldap không chính xác",
"Multiple accounts with same uid, please check your ldap server": "Nhiều tài khoản với cùng một uid, vui lòng kiểm tra máy chủ ldap của bạn",
"Organization does not exist": "Tổ chức không tồn tại",
"Password must have at least 6 characters": "Mật khẩu phải ít nhất 6 ký tự",
"Phone already exists": "Điện thoại đã tồn tại",
"Phone cannot be empty": "Điện thoại không thể để trống",
"Phone number is invalid": "Số điện thoại không hợp lệ",
"Session outdated, please login again": "Phiên làm việc hết hạn, vui lòng đăng nhập lại",
"The user is forbidden to sign in, please contact the administrator": "Người dùng bị cấm đăng nhập, vui lòng liên hệ với quản trị viên",
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "Tên người dùng chỉ có thể chứa các ký tự chữ và số, gạch dưới hoặc gạch ngang, không được có hai ký tự gạch dưới hoặc gạch ngang liền kề và không được bắt đầu hoặc kết thúc bằng dấu gạch dưới hoặc gạch ngang.",
"Username already exists": "Tên đăng nhập đã tồn tại",
"Username cannot be an email address": "Tên người dùng không thể là địa chỉ email",
"Username cannot contain white spaces": "Tên người dùng không thể chứa khoảng trắng",
"Username cannot start with a digit": "Tên người dùng không thể bắt đầu bằng chữ số",
"Username is too long (maximum is 39 characters).": "Tên đăng nhập quá dài (tối đa là 39 ký tự).",
"Username must have at least 2 characters": "Tên đăng nhập phải có ít nhất 2 ký tự",
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "Bạn đã nhập sai mật khẩu hoặc mã quá nhiều lần, vui lòng đợi %d phút và thử lại",
"Your region is not allow to signup by phone": "Vùng của bạn không được phép đăng ký bằng điện thoại",
"password or code is incorrect, you have %d remaining chances": "Mật khẩu hoặc mã không chính xác, bạn còn %d lần cơ hội",
"unsupported password type: %s": "Loại mật khẩu không được hỗ trợ: %s"
},
"general": {
"Missing parameter": "Missing parameter",
"Please login first": "Please login first",
"The user: %s doesn't exist": "The user: %s doesn't exist",
"don't support captchaProvider: ": "don't support captchaProvider: "
"Missing parameter": "Thiếu tham số",
"Please login first": "Vui lòng đăng nhập trước",
"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:"
},
"ldap": {
"Ldap server exist": "Ldap server exist"
"Ldap server exist": "Máy chủ Ldap tồn tại"
},
"link": {
"Please link first": "Please link first",
"This application has no providers": "This application has no providers",
"This application has no providers of type": "This application has no providers of type",
"This provider can't be unlinked": "This provider can't be unlinked",
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
"Please link first": "Vui lòng kết nối trước tiên",
"This application has no providers": "Ứng dụng này không có nhà cung cấp",
"This application has no providers of type": "Ứng dụng này không có nhà cung cấp loại nào",
"This provider can't be unlinked": "Nhà cung cấp này không thể được tách ra",
"You are not the global admin, you can't unlink other users": "Bạn không phải là quản trị viên toàn cầu, bạn không thể hủy liên kết người dùng khác",
"You can't unlink yourself, you are not a member of any application": "Bạn không thể hủy liên kết của mình, bởi vì bạn không phải là thành viên của bất kỳ ứng dụng nào"
},
"organization": {
"Only admin can modify the %s.": "Only admin can modify the %s.",
"The %s is immutable.": "The %s is immutable.",
"Unknown modify rule %s.": "Unknown modify rule %s."
"Only admin can modify the %s.": "Chỉ những người quản trị mới có thể sửa đổi %s.",
"The %s is immutable.": "%s không thể thay đổi được.",
"Unknown modify rule %s.": "Quy tắc thay đổi không xác định %s."
},
"provider": {
"Invalid application id": "Invalid application id",
"the provider: %s does not exist": "the provider: %s does not exist"
"Invalid application id": "Sai ID ứng dụng",
"the provider: %s does not exist": "Nhà cung cấp: %s không tồn tại"
},
"resource": {
"User is nil for tag: avatar": "User is nil for tag: avatar",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
"User is nil for tag: avatar": "Người dùng không có giá trị cho thẻ: hình đại diện",
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Tên người dùng hoặc đường dẫn tệp đầy đủ trống: tên người dùng = %s, đường dẫn tệp đầy đủ = %s"
},
"saml": {
"Application %s not found": "Application %s not found"
"Application %s not found": "Ứng dụng %s không tìm thấy"
},
"saml_sp": {
"provider %s's category is not SAML": "provider %s's category is not SAML"
"provider %s's category is not SAML": "Danh mục của nhà cung cấp %s không phải là SAML"
},
"service": {
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
"Empty parameters for emailForm: %v": "Tham số trống cho emailForm: %v",
"Invalid Email receivers: %s": "Người nhận Email không hợp lệ: %s",
"Invalid phone receivers: %s": "Người nhận điện thoại không hợp lệ: %s"
},
"storage": {
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
"The provider type: %s is not supported": "The provider type: %s is not supported"
"The objectKey: %s is not allowed": "Khóa đối tượng: %s không được phép",
"The provider type: %s is not supported": "Loại nhà cung cấp: %s không được hỗ trợ"
},
"token": {
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
"Invalid client_id": "Invalid client_id",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
"Empty clientId or clientSecret": "ClientId hoặc clientSecret trống",
"Grant_type: %s is not supported in this application": "Loại cấp phép: %s không được hỗ trợ trong ứng dụng này",
"Invalid application or wrong clientSecret": "Đơn đăng ký không hợp lệ hoặc sai clientSecret",
"Invalid client_id": "Client_id không hợp lệ",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Đường dẫn chuyển hướng URI: %s không tồn tại trong danh sách URI được phép chuyển hướng",
"Token not found, invalid accessToken": "Token không tìm thấy, accessToken không hợp lệ"
},
"user": {
"Display name cannot be empty": "Display name cannot be empty",
"New password cannot contain blank space.": "New password cannot contain blank space.",
"New password must have at least 6 characters": "New password must have at least 6 characters"
"Display name cannot be empty": "Tên hiển thị không thể trống",
"New password cannot contain blank space.": "Mật khẩu mới không thể chứa dấu trắng.",
"New password must have at least 6 characters": "Mật khẩu mới phải có ít nhất 6 ký tự"
},
"user_upload": {
"Failed to import users": "Failed to import users"
"Failed to import users": "Không thể nhập người dùng"
},
"util": {
"No application is found for userId: %s": "No application is found for userId: %s",
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
"The provider: %s is not found": "The provider: %s is not found"
"No application is found for userId: %s": "Không tìm thấy ứng dụng cho ID người dùng: %s",
"No provider for category: %s is found for application: %s": "Không tìm thấy nhà cung cấp cho danh mục: %s cho ứng dụng: %s",
"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!": "Code has not been sent yet!",
"Email is invalid": "Email is invalid",
"Invalid captcha provider.": "Invalid captcha provider.",
"Organization does not exist": "Organization does not exist",
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
"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.",
"Unknown type": "Unknown type",
"Wrong parameter": "Wrong parameter",
"Wrong verification code!": "Wrong verification code!",
"You should verify your code in %d min!": "You should verify your code in %d min!",
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
"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",
"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.",
"Unknown type": "Loại không xác định",
"Wrong parameter": "Tham số không đúng",
"Wrong verification code!": "Mã xác thực sai!",
"You should verify your code in %d min!": "Bạn nên kiểm tra mã của mình trong %d phút!",
"the user does not exist, please sign up first": "Người dùng không tồn tại, vui lòng đăng ký trước"
},
"webauthn": {
"Found no credentials for this user": "Found no credentials for this user",
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
"Found no credentials for this user": "Không tìm thấy thông tin xác thực cho người dùng này",
"Please call WebAuthnSigninBegin first": "Vui lòng gọi WebAuthnSigninBegin trước"
}
}

View File

@@ -1,31 +1,27 @@
{
"account": {
"Failed to add user": "添加用户失败",
"Get init score failed, error: %w": "初始化分数失败: %w",
"Invalid information": "无效信息",
"Please sign out first before signing in": "请在登录前先退出登录",
"Please sign out first before signing up": "请在注册前先退出登录",
"Please sign out first": "请先退出登录",
"The application does not allow to sign up new account": "该应用不允许注册新用户"
},
"auth": {
"Challenge method should be S256": "Challenge 方法应该为 S256",
"Challenge method should be S256": "Challenge方法应该为S256",
"Failed to create user, user information is invalid: %s": "创建用户失败,用户信息无效: %s",
"Failed to login in: %s": "登录失败: %s",
"Invalid token": "无效token",
"State expected: %s, but got: %s": "期望状态为: %s, 实际状态为: %s",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许通过 %s 注册新账户, 请使用其他方式注册",
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许注册新账户, 请联系IT支持",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "提供商账户: %s 与用户名: %s (%s) 已经与其他账户绑定: %s (%s)",
"The application: %s does not exist": "应用 %s 不存在",
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "提供商账户: %s与用户名: %s (%s)已经与其他账户绑定: %s (%s)",
"The application: %s does not exist": "应用%s不存在",
"The login method: login with password is not enabled for the application": "该应用禁止采用密码登录方式",
"The provider type: %s is not supported": "不支持该类型的提供商: %s",
"The provider: %s is not enabled for the application": "该应用的提供商: %s 未被启用",
"The user is forbidden to sign in, please contact the administrator": "该用户被禁止登录,请联系管理员",
"Turing test failed.": "人机验证失败",
"The provider: %s is not enabled for the application": "该应用的提供商: %s未被启用",
"Unauthorized operation": "未授权的操作",
"Unknown authentication type (not password or provider), form = %s": "未知的认证类型(非密码或第三方提供商):%s"
},
"cas": {
"Service %s and %s do not match": "服务 %s%s 不匹配"
"Service %s and %s do not match": "服务%s%s不匹配"
},
"check": {
"Affiliation cannot be blank": "工作单位不可为空",
@@ -61,7 +57,7 @@
"general": {
"Missing parameter": "缺少参数",
"Please login first": "请先登录",
"The user: %s doesn't exist": "用户: %s 不存在",
"The user: %s doesn't exist": "用户: %s不存在",
"don't support captchaProvider: ": "不支持验证码提供商: "
},
"ldap": {
@@ -76,13 +72,13 @@
"You can't unlink yourself, you are not a member of any application": "您无法自行解绑,您不是任何应用程序的成员"
},
"organization": {
"Only admin can modify the %s.": "仅允许管理员可以修改 %s",
"The %s is immutable.": "%s 是不可变的",
"Only admin can modify the %s.": "仅允许管理员可以修改%s",
"The %s is immutable.": "%s是不可变的",
"Unknown modify rule %s.": "未知的修改规则: %s"
},
"provider": {
"Invalid application id": "无效的应用ID",
"the provider: %s does not exist": "提供商: %s 不存在"
"the provider: %s does not exist": "提供商: %s不存在"
},
"resource": {
"User is nil for tag: avatar": "上传头像时用户为空",
@@ -92,15 +88,15 @@
"Application %s not found": "未找到应用: %s"
},
"saml_sp": {
"provider %s's category is not SAML": "提供商: %s 不是SAML类型"
"provider %s's category is not SAML": "提供商: %s不是SAML类型"
},
"service": {
"Empty parameters for emailForm: %v": "邮件参数为空: %v",
"Invalid Email receivers: %s": " 无效的邮箱收件人: %s",
"Invalid Email receivers: %s": "无效的邮箱收件人: %s",
"Invalid phone receivers: %s": "无效的手机短信收信人: %s"
},
"storage": {
"The objectKey: %s is not allowed": "objectKey: %s 被禁止",
"The objectKey: %s is not allowed": "objectKey: %s被禁止",
"The provider type: %s is not supported": "不支持的提供商类型: %s"
},
"token": {
@@ -108,7 +104,7 @@
"Grant_type: %s is not supported in this application": "该应用不支持Grant_type: %s",
"Invalid application or wrong clientSecret": "无效应用或错误的clientSecret",
"Invalid client_id": "无效的ClientId",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "重定向 URI%s 在许可跳转列表中未找到",
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "重定向 URI%s在许可跳转列表中未找到",
"Token not found, invalid accessToken": "未查询到对应token, accessToken无效"
},
"user": {
@@ -120,15 +116,13 @@
"Failed to import users": "导入用户失败"
},
"util": {
"No application is found for userId: %s": "未找到用户: %s 的应用",
"No provider for category: %s is found for application: %s": "未找到类别为: %s 的提供商来满足应用: %s",
"No application is found for userId: %s": "未找到用户: %s的应用",
"No provider for category: %s is found for application: %s": "未找到类别为: %s的提供商来满足应用: %s",
"The provider: %s is not found": "未找到提供商: %s"
},
"verification": {
"Code has not been sent yet!": "验证码还未发送",
"Email is invalid": "非法的邮箱",
"Invalid captcha provider.": "非法的验证码提供商",
"Organization does not exist": "组织不存在",
"Phone number is invalid in your region %s": "您所在地区的电话号码无效 %s",
"Turing test failed.": "验证码还未发送",
"Unable to get the email modify rule.": "无法获取邮箱修改规则",
@@ -140,7 +134,7 @@
"the user does not exist, please sign up first": "用户不存在,请先注册"
},
"webauthn": {
"Found no credentials for this user": "该用户没有 WebAuthn 凭据",
"Please call WebAuthnSigninBegin first": "请先调用 WebAuthnSigninBegin"
"Found no credentials for this user": "该用户没有WebAuthn凭据",
"Please call WebAuthnSigninBegin first": "请先调用WebAuthnSigninBegin函数"
}
}

View File

@@ -108,8 +108,8 @@ func (idp *CasdoorIdProvider) GetToken(code string) (*oauth2.Token, error) {
type CasdoorUserInfo struct {
Id string `json:"sub"`
Name string `json:"name"`
DisplayName string `json:"preferred_username"`
Name string `json:"preferred_username,omitempty"`
DisplayName string `json:"name"`
Email string `json:"email"`
AvatarUrl string `json:"picture"`
Status string `json:"status"`

View File

@@ -61,8 +61,8 @@ func (idp *CustomIdProvider) GetToken(code string) (*oauth2.Token, error) {
type CustomUserInfo struct {
Id string `json:"sub"`
Name string `json:"name"`
DisplayName string `json:"preferred_username"`
Name string `json:"preferred_username,omitempty"`
DisplayName string `json:"name"`
Email string `json:"email"`
AvatarUrl string `json:"picture"`
Status string `json:"status"`

View File

@@ -88,7 +88,7 @@ type GothIdProvider struct {
Session goth.Session
}
func NewGothIdProvider(providerType string, clientId string, clientSecret string, redirectUrl string) *GothIdProvider {
func NewGothIdProvider(providerType string, clientId string, clientSecret string, redirectUrl string, hostUrl string) *GothIdProvider {
var idp GothIdProvider
switch providerType {
case "Amazon":
@@ -102,8 +102,13 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
Session: &apple.Session{},
}
case "AzureAD":
domain := "common"
if hostUrl != "" {
domain = hostUrl
}
idp = GothIdProvider{
Provider: azureadv2.New(clientId, clientSecret, redirectUrl, azureadv2.ProviderOptions{Tenant: "common"}),
Provider: azureadv2.New(clientId, clientSecret, redirectUrl, azureadv2.ProviderOptions{Tenant: azureadv2.TenantType(domain)}),
Session: &azureadv2.Session{},
}
case "Auth0":

View File

@@ -90,7 +90,7 @@ func GetIdProvider(typ string, subType string, clientId string, clientSecret str
} else if typ == "Douyin" {
return NewDouyinIdProvider(clientId, clientSecret, redirectUrl)
} else if isGothSupport(typ) {
return NewGothIdProvider(typ, clientId, clientSecret, redirectUrl)
return NewGothIdProvider(typ, clientId, clientSecret, redirectUrl, hostUrl)
} else if typ == "Bilibili" {
return NewBilibiliIdProvider(clientId, clientSecret, redirectUrl)
}

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package controllers
package ldap
import (
"fmt"
@@ -20,76 +20,78 @@ import (
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/object"
"github.com/forestmgy/ldapserver"
ldap "github.com/forestmgy/ldapserver"
"github.com/lor00x/goldap/message"
)
func StartLdapServer() {
server := ldapserver.NewServer()
routes := ldapserver.NewRouteMux()
server := ldap.NewServer()
routes := ldap.NewRouteMux()
routes.Bind(handleBind)
routes.Search(handleSearch).Label(" SEARCH****")
server.Handle(routes)
server.ListenAndServe("0.0.0.0:" + conf.GetConfigString("ldapServerPort"))
err := server.ListenAndServe("0.0.0.0:" + conf.GetConfigString("ldapServerPort"))
if err != nil {
return
}
}
func handleBind(w ldapserver.ResponseWriter, m *ldapserver.Message) {
func handleBind(w ldap.ResponseWriter, m *ldap.Message) {
r := m.GetBindRequest()
res := ldapserver.NewBindResponse(ldapserver.LDAPResultSuccess)
res := ldap.NewBindResponse(ldap.LDAPResultSuccess)
if r.AuthenticationChoice() == "simple" {
bindusername, bindorg, err := object.GetNameAndOrgFromDN(string(r.Name()))
bindUsername, bindOrg, err := getNameAndOrgFromDN(string(r.Name()))
if err != "" {
log.Printf("Bind failed ,ErrMsg=%s", err)
res.SetResultCode(ldapserver.LDAPResultInvalidDNSyntax)
res.SetResultCode(ldap.LDAPResultInvalidDNSyntax)
res.SetDiagnosticMessage("bind failed ErrMsg: " + err)
w.Write(res)
return
}
bindpassword := string(r.AuthenticationSimple())
binduser, err := object.CheckUserPassword(bindorg, bindusername, bindpassword, "en")
bindPassword := string(r.AuthenticationSimple())
bindUser, err := object.CheckUserPassword(object.CasdoorOrganization, bindUsername, bindPassword, "en")
if err != "" {
log.Printf("Bind failed User=%s, Pass=%#v, ErrMsg=%s", string(r.Name()), r.Authentication(), err)
res.SetResultCode(ldapserver.LDAPResultInvalidCredentials)
res.SetResultCode(ldap.LDAPResultInvalidCredentials)
res.SetDiagnosticMessage("invalid credentials ErrMsg: " + err)
w.Write(res)
return
}
if bindorg == "built-in" {
if bindOrg == "built-in" || bindUser.IsGlobalAdmin {
m.Client.IsGlobalAdmin, m.Client.IsOrgAdmin = true, true
} else if binduser.IsAdmin {
} else if bindUser.IsAdmin {
m.Client.IsOrgAdmin = true
}
m.Client.IsAuthenticated = true
m.Client.UserName = bindusername
m.Client.OrgName = bindorg
m.Client.UserName = bindUsername
m.Client.OrgName = bindOrg
} else {
res.SetResultCode(ldapserver.LDAPResultAuthMethodNotSupported)
res.SetResultCode(ldap.LDAPResultAuthMethodNotSupported)
res.SetDiagnosticMessage("Authentication method not supported,Please use Simple Authentication")
}
w.Write(res)
}
func handleSearch(w ldapserver.ResponseWriter, m *ldapserver.Message) {
res := ldapserver.NewSearchResultDoneResponse(ldapserver.LDAPResultSuccess)
func handleSearch(w ldap.ResponseWriter, m *ldap.Message) {
res := ldap.NewSearchResultDoneResponse(ldap.LDAPResultSuccess)
if !m.Client.IsAuthenticated {
res.SetResultCode(ldapserver.LDAPResultUnwillingToPerform)
res.SetResultCode(ldap.LDAPResultUnwillingToPerform)
w.Write(res)
return
}
r := m.GetSearchRequest()
if r.FilterString() == "(objectClass=*)" {
w.Write(res)
return
}
name, org, errCode := object.GetUserNameAndOrgFromBaseDnAndFilter(string(r.BaseObject()), r.FilterString())
if errCode != ldapserver.LDAPResultSuccess {
res.SetResultCode(errCode)
w.Write(res)
return
}
// Handle Stop Signal (server stop / client disconnected / Abandoned request....)
select {
case <-m.Done:
@@ -97,16 +99,17 @@ func handleSearch(w ldapserver.ResponseWriter, m *ldapserver.Message) {
return
default:
}
users, errCode := object.GetFilteredUsers(m, name, org)
if errCode != ldapserver.LDAPResultSuccess {
res.SetResultCode(errCode)
users, code := GetFilteredUsers(m)
if code != ldap.LDAPResultSuccess {
res.SetResultCode(code)
w.Write(res)
return
}
for i := 0; i < len(users); i++ {
user := users[i]
for _, user := range users {
dn := fmt.Sprintf("cn=%s,%s", user.Name, string(r.BaseObject()))
e := ldapserver.NewSearchResultEntry(dn)
e := ldap.NewSearchResultEntry(dn)
e.AddAttribute("cn", message.AttributeValue(user.Name))
e.AddAttribute("uid", message.AttributeValue(user.Name))
e.AddAttribute("email", message.AttributeValue(user.Email))
@@ -117,22 +120,3 @@ func handleSearch(w ldapserver.ResponseWriter, m *ldapserver.Message) {
}
w.Write(res)
}
// get user password with hash type prefix
// TODO not handle salt yet
// @return {md5}5f4dcc3b5aa765d61d8327deb882cf99
func getUserPasswordWithType(user *object.User) string {
org := object.GetOrganizationByUser(user)
if org.PasswordType == "" || org.PasswordType == "plain" {
return user.Password
}
prefix := org.PasswordType
if prefix == "salt" {
prefix = "sha256"
} else if prefix == "md5-salt" {
prefix = "md5"
} else if prefix == "pbkdf2-salt" {
prefix = "pbkdf2"
}
return fmt.Sprintf("{%s}%s", prefix, user.Password)
}

116
ldap/util.go Normal file
View File

@@ -0,0 +1,116 @@
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ldap
import (
"fmt"
"log"
"strings"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"
ldap "github.com/forestmgy/ldapserver"
)
func getNameAndOrgFromDN(DN string) (string, string, string) {
DNFields := strings.Split(DN, ",")
params := make(map[string]string, len(DNFields))
for _, field := range DNFields {
if strings.Contains(field, "=") {
k := strings.Split(field, "=")
params[k[0]] = k[1]
}
}
if params["cn"] == "" {
return "", "", "please use Admin Name format like cn=xxx,ou=xxx,dc=example,dc=com"
}
if params["ou"] == "" {
return params["cn"], object.CasdoorOrganization, ""
}
return params["cn"], params["ou"], ""
}
func getNameAndOrgFromFilter(baseDN, filter string) (string, string, int) {
if !strings.Contains(baseDN, "ou=") {
return "", "", ldap.LDAPResultInvalidDNSyntax
}
name, org, _ := getNameAndOrgFromDN(fmt.Sprintf("cn=%s,", getUsername(filter)) + baseDN)
return name, org, ldap.LDAPResultSuccess
}
func getUsername(filter string) string {
nameIndex := strings.Index(filter, "cn=")
if nameIndex == -1 {
return "*"
}
var name string
for i := nameIndex + 3; filter[i] != ')'; i++ {
name = name + string(filter[i])
}
return name
}
func GetFilteredUsers(m *ldap.Message) (filteredUsers []*object.User, code int) {
r := m.GetSearchRequest()
name, org, code := getNameAndOrgFromFilter(string(r.BaseObject()), r.FilterString())
if code != ldap.LDAPResultSuccess {
return nil, code
}
if name == "*" && m.Client.IsOrgAdmin { // get all users from organization 'org'
if m.Client.IsGlobalAdmin && org == "*" {
filteredUsers = object.GetGlobalUsers()
return filteredUsers, ldap.LDAPResultSuccess
}
if m.Client.IsGlobalAdmin || org == m.Client.OrgName {
filteredUsers = object.GetUsers(org)
return filteredUsers, ldap.LDAPResultSuccess
} else {
return nil, ldap.LDAPResultInsufficientAccessRights
}
} else {
hasPermission, err := object.CheckUserPermission(fmt.Sprintf("%s/%s", m.Client.OrgName, m.Client.UserName), fmt.Sprintf("%s/%s", org, name), true, "en")
if !hasPermission {
log.Printf("ErrMsg = %v", err.Error())
return nil, ldap.LDAPResultInsufficientAccessRights
}
user := object.GetUser(util.GetId(org, name))
filteredUsers = append(filteredUsers, user)
return filteredUsers, ldap.LDAPResultSuccess
}
}
// get user password with hash type prefix
// TODO not handle salt yet
// @return {md5}5f4dcc3b5aa765d61d8327deb882cf99
func getUserPasswordWithType(user *object.User) string {
org := object.GetOrganizationByUser(user)
if org.PasswordType == "" || org.PasswordType == "plain" {
return user.Password
}
prefix := org.PasswordType
if prefix == "salt" {
prefix = "sha256"
} else if prefix == "md5-salt" {
prefix = "md5"
} else if prefix == "pbkdf2-salt" {
prefix = "pbkdf2"
}
return fmt.Sprintf("{%s}%s", prefix, user.Password)
}

View File

@@ -23,7 +23,7 @@ import (
_ "github.com/beego/beego/session/redis"
"github.com/casdoor/casdoor/authz"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/controllers"
"github.com/casdoor/casdoor/ldap"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/proxy"
"github.com/casdoor/casdoor/routers"
@@ -81,7 +81,7 @@ func main() {
// logs.SetLevel(logs.LevelInformational)
logs.SetLogFuncCall(false)
go controllers.StartLdapServer()
go ldap.StartLdapServer()
beego.Run(fmt.Sprintf(":%v", port))
}

View File

@@ -63,19 +63,19 @@ func getPermanentAvatarUrl(organization string, username string, url string, upl
uploadedFileUrl, _ := GetUploadFileUrl(defaultStorageProvider, fullFilePath, false)
if upload {
DownloadAndUpload(url, fullFilePath)
DownloadAndUpload(url, fullFilePath, "en")
}
return uploadedFileUrl
}
func DownloadAndUpload(url string, fullFilePath string) {
func DownloadAndUpload(url string, fullFilePath string, lang string) {
fileBuffer, err := downloadFile(url)
if err != nil {
panic(err)
}
_, _, err = UploadFileSafe(defaultStorageProvider, fullFilePath, fileBuffer)
_, _, err = UploadFileSafe(defaultStorageProvider, fullFilePath, fileBuffer, lang)
if err != nil {
panic(err)
}

View File

@@ -250,11 +250,13 @@ func filterField(field string) bool {
return reFieldWhiteList.MatchString(field)
}
func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, lang string) (bool, error) {
func CheckUserPermission(requestUserId, userId string, strict bool, lang string) (bool, error) {
if requestUserId == "" {
return false, fmt.Errorf(i18n.Translate(lang, "general:Please login first"))
}
userOwner := util.GetOwnerFromId(userId)
if userId != "" {
targetUser := GetUser(userId)
if targetUser == nil {

View File

@@ -115,7 +115,7 @@ func LdapUsersToLdapRespUsers(users []ldapUser) []LdapRespUser {
}
func isMicrosoftAD(Conn *goldap.Conn) (bool, error) {
SearchFilter := "(objectclass=*)"
SearchFilter := "(objectClass=*)"
SearchAttributes := []string{"vendorname", "vendorversion", "isGlobalCatalogReady", "forestFunctionality"}
searchReq := goldap.NewSearchRequest("",
@@ -126,7 +126,7 @@ func isMicrosoftAD(Conn *goldap.Conn) (bool, error) {
return false, err
}
if len(searchResult.Entries) == 0 {
return false, errors.New("no result")
return false, nil
}
isMicrosoft := false
var ldapServerType ldapServerType

View File

@@ -1,74 +0,0 @@
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package object
import (
"fmt"
"log"
"strings"
"github.com/forestmgy/ldapserver"
)
func GetNameAndOrgFromDN(DN string) (string, string, string) {
DNValue := strings.Split(DN, ",")
if len(DNValue) == 1 || strings.ToLower(DNValue[0])[0] != 'c' || strings.ToLower(DNValue[1])[0] != 'o' {
return "", "", "please use correct Admin Name format like cn=xxx,ou=xxx,dc=example,dc=com"
}
return DNValue[0][3:], DNValue[1][3:], ""
}
func GetUserNameAndOrgFromBaseDnAndFilter(baseDN, filter string) (string, string, int) {
if !strings.Contains(baseDN, "ou=") || !strings.Contains(filter, "cn=") {
return "", "", ldapserver.LDAPResultInvalidDNSyntax
}
name := getUserNameFromFilter(filter)
_, org, _ := GetNameAndOrgFromDN(fmt.Sprintf("cn=%s,", name) + baseDN)
errCode := ldapserver.LDAPResultSuccess
return name, org, errCode
}
func getUserNameFromFilter(filter string) string {
nameIndex := strings.Index(filter, "cn=")
var name string
for i := nameIndex + 3; filter[i] != ')'; i++ {
name = name + string(filter[i])
}
return name
}
func GetFilteredUsers(m *ldapserver.Message, name, org string) ([]*User, int) {
var filteredUsers []*User
if name == "*" && m.Client.IsOrgAdmin { // get all users from organization 'org'
if m.Client.OrgName == "built-in" && org == "*" {
filteredUsers = GetGlobalUsers()
return filteredUsers, ldapserver.LDAPResultSuccess
} else if m.Client.OrgName == "built-in" || org == m.Client.OrgName {
filteredUsers = GetUsers(org)
return filteredUsers, ldapserver.LDAPResultSuccess
} else {
return nil, ldapserver.LDAPResultInsufficientAccessRights
}
} else {
hasPermission, err := CheckUserPermission(fmt.Sprintf("%s/%s", m.Client.OrgName, m.Client.UserName), fmt.Sprintf("%s/%s", org, name), org, true, "en")
if !hasPermission {
log.Printf("ErrMsg = %v", err.Error())
return nil, ldapserver.LDAPResultInsufficientAccessRights
}
user := getUser(org, name)
filteredUsers = append(filteredUsers, user)
return filteredUsers, ldapserver.LDAPResultSuccess
}
}

View File

@@ -86,19 +86,30 @@ func NewSamlResponse(user *User, host string, certificate string, destination st
authnStatement.CreateElement("saml:AuthnContext").CreateElement("saml:AuthnContextClassRef").SetText("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport")
attributes := assertion.CreateElement("saml:AttributeStatement")
email := attributes.CreateElement("saml:Attribute")
email.CreateAttr("Name", "Email")
email.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
email.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.Email)
name := attributes.CreateElement("saml:Attribute")
name.CreateAttr("Name", "Name")
name.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
name.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.Name)
displayName := attributes.CreateElement("saml:Attribute")
displayName.CreateAttr("Name", "DisplayName")
displayName.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
displayName.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.DisplayName)
roles := attributes.CreateElement("saml:Attribute")
roles.CreateAttr("Name", "Roles")
roles.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
ExtendUserWithRolesAndPermissions(user)
for _, role := range user.Roles {
roles.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(role.Name)
}
return samlResponse, nil
}

View File

@@ -36,13 +36,11 @@ func ParseSamlResponse(samlResponse string, providerType string) (string, error)
return "", err
}
assertionInfo, err := sp.RetrieveAssertionInfo(samlResponse)
if err != nil {
panic(err)
}
return assertionInfo.NameID, nil
return assertionInfo.NameID, err
}
func GenerateSamlLoginUrl(id, relayState, lang string) (string, string, error) {
func GenerateSamlLoginUrl(id, relayState, lang string) (auth string, method string, err error) {
provider := GetProvider(id)
if provider.Category != "SAML" {
return "", "", fmt.Errorf(i18n.Translate(lang, "saml_sp:provider %s's category is not SAML"), provider.Name)
@@ -51,8 +49,7 @@ func GenerateSamlLoginUrl(id, relayState, lang string) (string, string, error) {
if err != nil {
return "", "", err
}
auth := ""
method := ""
if provider.EnableSignAuthnRequest {
post, err := sp.BuildAuthBodyPost(relayState)
if err != nil {

View File

@@ -106,11 +106,11 @@ func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool
return fileUrl, objectKey
}
func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffer) (string, string, error) {
func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffer, lang string) (string, string, error) {
endpoint := getProviderEndpoint(provider)
storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
if storageProvider == nil {
return "", "", fmt.Errorf("the provider type: %s is not supported", provider.Type)
return "", "", fmt.Errorf(i18n.Translate(lang, "storage:The provider type: %s is not supported"), provider.Type)
}
if provider.Domain == "" {
@@ -128,7 +128,7 @@ func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffe
return fileUrl, objectKey, nil
}
func UploadFileSafe(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffer) (string, string, error) {
func UploadFileSafe(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffer, lang string) (string, string, error) {
// check fullFilePath is there security issue
if strings.Contains(fullFilePath, "..") {
return "", "", fmt.Errorf("the fullFilePath: %s is not allowed", fullFilePath)
@@ -139,7 +139,7 @@ func UploadFileSafe(provider *Provider, fullFilePath string, fileBuffer *bytes.B
var err error
times := 0
for {
fileUrl, objectKey, err = uploadFile(provider, fullFilePath, fileBuffer)
fileUrl, objectKey, err = uploadFile(provider, fullFilePath, fileBuffer, lang)
if err != nil {
times += 1
if times >= 5 {

View File

@@ -51,7 +51,7 @@ type Token struct {
Organization string `xorm:"varchar(100)" json:"organization"`
User string `xorm:"varchar(100)" json:"user"`
Code string `xorm:"varchar(100)" json:"code"`
Code string `xorm:"varchar(100) index" json:"code"`
AccessToken string `xorm:"mediumtext" json:"accessToken"`
RefreshToken string `xorm:"mediumtext" json:"refreshToken"`
ExpiresIn int `json:"expiresIn"`
@@ -362,7 +362,8 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
}
token.CodeIsUsed = true
updateUsedByCode(token)
go updateUsedByCode(token)
tokenWrapper := &TokenWrapper{
AccessToken: token.AccessToken,
IdToken: token.AccessToken,
@@ -613,7 +614,8 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
nullUser := &User{
Owner: application.Owner,
Id: application.GetId(),
Name: fmt.Sprintf("app/%s", application.Name),
Name: application.Name,
Type: "application",
}
accessToken, _, tokenName, err := generateJwtToken(application, nullUser, "", scope, host)

View File

@@ -18,6 +18,7 @@ import (
"errors"
"fmt"
"math/rand"
"strings"
"time"
"github.com/casdoor/casdoor/conf"
@@ -38,6 +39,11 @@ const (
timeoutError = 3
)
const (
VerifyTypePhone = "phone"
VerifyTypeEmail = "email"
)
type VerificationRecord struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
@@ -213,6 +219,14 @@ func CheckSigninCode(user *User, dest, code, lang string) string {
}
}
func GetVerifyType(username string) (verificationCodeType string) {
if strings.Contains(username, "@") {
return VerifyTypeEmail
} else {
return VerifyTypeEmail
}
}
// From Casnode/object/validateCode.go line 116
var stdNums = []byte("0123456789")

View File

@@ -50,6 +50,7 @@ func initAPI() {
beego.Router("/api/logout", &controllers.ApiController{}, "GET,POST:Logout")
beego.Router("/api/get-account", &controllers.ApiController{}, "GET:GetAccount")
beego.Router("/api/userinfo", &controllers.ApiController{}, "GET:GetUserinfo")
beego.Router("/api/user", &controllers.ApiController{}, "GET:GetUserinfo2")
beego.Router("/api/unlink", &controllers.ApiController{}, "POST:Unlink")
beego.Router("/api/get-saml-login", &controllers.ApiController{}, "GET:GetSamlLogin")
beego.Router("/api/acs", &controllers.ApiController{}, "POST:HandleSamlLogin")
@@ -114,6 +115,7 @@ func initAPI() {
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "GET:GetEmailAndPhone")
beego.Router("/api/send-verification-code", &controllers.ApiController{}, "POST:SendVerificationCode")
beego.Router("/api/verify-code", &controllers.ApiController{}, "POST:VerifyCode")
beego.Router("/api/verify-captcha", &controllers.ApiController{}, "POST:VerifyCaptcha")
beego.Router("/api/reset-email-or-phone", &controllers.ApiController{}, "POST:ResetEmailOrPhone")
beego.Router("/api/get-captcha", &controllers.ApiController{}, "GET:GetCaptcha")

View File

@@ -2058,22 +2058,13 @@
"tags": [
"System API"
],
"description": "get user's system info",
"description": "get system info like CPU and memory usage",
"operationId": "ApiController.GetSystemInfo",
"parameters": [
{
"in": "query",
"name": "id",
"description": "The id ( owner/name ) of the user",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "The Response object",
"schema": {
"$ref": "#/definitions/object.SystemInfo"
"$ref": "#/definitions/util.SystemInfo"
}
}
}
@@ -2180,6 +2171,12 @@
"name": "phone",
"description": "The phone of the user",
"type": "string"
},
{
"in": "query",
"name": "userId",
"description": "The userId of the user",
"type": "string"
}
],
"responses": {
@@ -2323,11 +2320,14 @@
"tags": [
"System API"
],
"description": "get local git repo's latest release version info",
"description": "get version info like Casdoor release version and commit ID",
"operationId": "ApiController.GetVersionInfo",
"responses": {
"200": {
"description": "{string} local latest version hash of Casdoor"
"description": "The Response object",
"schema": {
"$ref": "#/definitions/util.VersionInfo"
}
}
}
}
@@ -3494,6 +3494,23 @@
"operationId": "ApiController.UploadResource"
}
},
"/api/user": {
"get": {
"tags": [
"Account API"
],
"description": "return Laravel compatible user information according to OAuth 2.0",
"operationId": "ApiController.UserInfo2",
"responses": {
"200": {
"description": "The Response object",
"schema": {
"$ref": "#/definitions/LaravelResponse"
}
}
}
}
},
"/api/userinfo": {
"get": {
"tags": [
@@ -3627,14 +3644,18 @@
}
},
"definitions": {
"2268.0xc000528cf0.false": {
"2306.0xc0003a4480.false": {
"title": "false",
"type": "object"
},
"2302.0xc000528d20.false": {
"2340.0xc0003a44b0.false": {
"title": "false",
"type": "object"
},
"LaravelResponse": {
"title": "LaravelResponse",
"type": "object"
},
"Response": {
"title": "Response",
"type": "object"
@@ -3682,6 +3703,9 @@
"captchaType": {
"type": "string"
},
"clientId": {
"type": "string"
},
"clientSecret": {
"type": "string"
},
@@ -3758,10 +3782,10 @@
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/2268.0xc000528cf0.false"
"$ref": "#/definitions/2306.0xc0003a4480.false"
},
"data2": {
"$ref": "#/definitions/2302.0xc000528d20.false"
"$ref": "#/definitions/2340.0xc0003a44b0.false"
},
"msg": {
"type": "string"
@@ -4830,10 +4854,6 @@
}
}
},
"object.SystemInfo": {
"title": "SystemInfo",
"type": "object"
},
"object.TableColumn": {
"title": "TableColumn",
"type": "object",
@@ -5475,6 +5495,43 @@
"title": "CredentialCreationResponse",
"type": "object"
},
"util.SystemInfo": {
"title": "SystemInfo",
"type": "object",
"properties": {
"cpuUsage": {
"type": "array",
"items": {
"type": "number",
"format": "double"
}
},
"memoryTotal": {
"type": "integer",
"format": "int64"
},
"memoryUsed": {
"type": "integer",
"format": "int64"
}
}
},
"util.VersionInfo": {
"title": "VersionInfo",
"type": "object",
"properties": {
"commitId": {
"type": "string"
},
"commitOffset": {
"type": "integer",
"format": "int64"
},
"version": {
"type": "string"
}
}
},
"webauthn.Credential": {
"title": "Credential",
"type": "object"

View File

@@ -1340,19 +1340,13 @@ paths:
get:
tags:
- System API
description: get user's system info
description: get system info like CPU and memory usage
operationId: ApiController.GetSystemInfo
parameters:
- in: query
name: id
description: The id ( owner/name ) of the user
required: true
type: string
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/object.SystemInfo'
$ref: '#/definitions/util.SystemInfo'
/api/get-token:
get:
tags:
@@ -1423,6 +1417,10 @@ paths:
name: phone
description: The phone of the user
type: string
- in: query
name: userId
description: The userId of the user
type: string
responses:
"200":
description: The Response object
@@ -1515,11 +1513,13 @@ paths:
get:
tags:
- System API
description: get local git repo's latest release version info
description: get version info like Casdoor release version and commit ID
operationId: ApiController.GetVersionInfo
responses:
"200":
description: '{string} local latest version hash of Casdoor'
description: The Response object
schema:
$ref: '#/definitions/util.VersionInfo'
/api/get-webhook:
get:
tags:
@@ -2288,6 +2288,17 @@ paths:
tags:
- Resource API
operationId: ApiController.UploadResource
/api/user:
get:
tags:
- Account API
description: return Laravel compatible user information according to OAuth 2.0
operationId: ApiController.UserInfo2
responses:
"200":
description: The Response object
schema:
$ref: '#/definitions/LaravelResponse'
/api/userinfo:
get:
tags:
@@ -2374,12 +2385,15 @@ paths:
schema:
$ref: '#/definitions/Response'
definitions:
2268.0xc000528cf0.false:
2306.0xc0003a4480.false:
title: "false"
type: object
2302.0xc000528d20.false:
2340.0xc0003a44b0.false:
title: "false"
type: object
LaravelResponse:
title: LaravelResponse
type: object
Response:
title: Response
type: object
@@ -2413,6 +2427,8 @@ definitions:
type: string
captchaType:
type: string
clientId:
type: string
clientSecret:
type: string
code:
@@ -2464,9 +2480,9 @@ definitions:
type: object
properties:
data:
$ref: '#/definitions/2268.0xc000528cf0.false'
$ref: '#/definitions/2306.0xc0003a4480.false'
data2:
$ref: '#/definitions/2302.0xc000528d20.false'
$ref: '#/definitions/2340.0xc0003a44b0.false'
msg:
type: string
name:
@@ -3183,9 +3199,6 @@ definitions:
type: string
user:
type: string
object.SystemInfo:
title: SystemInfo
type: object
object.TableColumn:
title: TableColumn
type: object
@@ -3617,6 +3630,32 @@ definitions:
protocol.CredentialCreationResponse:
title: CredentialCreationResponse
type: object
util.SystemInfo:
title: SystemInfo
type: object
properties:
cpuUsage:
type: array
items:
type: number
format: double
memoryTotal:
type: integer
format: int64
memoryUsed:
type: integer
format: int64
util.VersionInfo:
title: VersionInfo
type: object
properties:
commitId:
type: string
commitOffset:
type: integer
format: int64
version:
type: string
webauthn.Credential:
title: Credential
type: object

View File

@@ -95,6 +95,15 @@ func GetOwnerAndNameFromId(id string) (string, string) {
return tokens[0], tokens[1]
}
func GetOwnerFromId(id string) string {
tokens := strings.Split(id, "/")
if len(tokens) != 2 {
panic(errors.New("GetOwnerAndNameFromId() error, wrong token count for ID: " + id))
}
return tokens[0]
}
func GetOwnerAndNameFromIdNoCheck(id string) (string, string) {
tokens := strings.SplitN(id, "/", 2)
return tokens[0], tokens[1]

View File

@@ -15,8 +15,13 @@
package util
import (
"bufio"
"os"
"path"
"regexp"
"runtime"
"strconv"
"strings"
"time"
"github.com/go-git/go-git/v5"
@@ -54,7 +59,7 @@ func getMemoryUsage() (uint64, uint64, error) {
var m runtime.MemStats
runtime.ReadMemStats(&m)
return m.TotalAlloc, virtualMem.Total, nil
return m.Alloc, virtualMem.Total, nil
}
func GetSystemInfo() (*SystemInfo, error) {
@@ -140,3 +145,47 @@ func GetVersionInfo() (*VersionInfo, error) {
}
return res, nil
}
func GetVersionInfoFromFile() (*VersionInfo, error) {
res := &VersionInfo{
Version: "",
CommitId: "",
CommitOffset: -1,
}
_, filename, _, _ := runtime.Caller(0)
rootPath := path.Dir(path.Dir(filename))
file, err := os.Open(path.Join(rootPath, "version_info.txt"))
if err != nil {
return res, err
}
defer file.Close()
// Read file contents line by line
scanner := bufio.NewScanner(file)
for scanner.Scan() {
// Use regular expressions to match strings
re := regexp.MustCompile(`\{([^{}]+)\}`)
versionInfo := scanner.Text()
matches := re.FindStringSubmatch(versionInfo)
if len(matches) > 1 {
split := strings.Split(matches[1], " ")
version := split[0]
commitId := split[1]
commitOffset, _ := strconv.Atoi(split[2])
res = &VersionInfo{
Version: version,
CommitId: commitId,
CommitOffset: commitOffset,
}
break
}
}
if err := scanner.Err(); err != nil {
return res, err
}
return res, nil
}

View File

@@ -40,7 +40,7 @@ func TestGetMemoryUsage(t *testing.T) {
t.Log(used, total)
}
func TestGetGitRepoVersion(t *testing.T) {
func TestGetVersionInfo(t *testing.T) {
versionInfo, err := GetVersionInfo()
assert.Nil(t, err)
t.Log(versionInfo)
@@ -90,3 +90,9 @@ func TestGetVersion(t *testing.T) {
assert.Equal(t, 3, aheadCnt)
assert.Equal(t, "v1.257.0", releaseVersion)
}
func TestFromFile(t *testing.T) {
versionInfo, err := GetVersionInfoFromFile()
assert.Nil(t, err)
t.Log(versionInfo)
}

View File

@@ -21,7 +21,7 @@ import i18next from "i18next";
import "codemirror/lib/codemirror.css";
import * as ModelBackend from "./backend/ModelBackend";
import PolicyTable from "./common/PoliciyTable";
import PolicyTable from "./table/PoliciyTable";
require("codemirror/theme/material-darker.css");
require("codemirror/mode/javascript/javascript");

View File

@@ -52,7 +52,7 @@ import PaymentEditPage from "./PaymentEditPage";
import PaymentResultPage from "./PaymentResultPage";
import AccountPage from "./account/AccountPage";
import HomePage from "./basic/HomePage";
import CustomGithubCorner from "./CustomGithubCorner";
import CustomGithubCorner from "./common/CustomGithubCorner";
import * as Conf from "./Conf";
import * as Auth from "./auth/Auth";
@@ -60,7 +60,7 @@ import EntryPage from "./EntryPage";
import ResultPage from "./auth/ResultPage";
import * as AuthBackend from "./auth/AuthBackend";
import AuthCallback from "./auth/AuthCallback";
import SelectLanguageBox from "./SelectLanguageBox";
import LanguageSelect from "./common/select/LanguageSelect";
import i18next from "i18next";
import OdicDiscoveryPage from "./auth/OidcDiscoveryPage";
import SamlCallback from "./auth/SamlCallback";
@@ -70,7 +70,7 @@ import SystemInfo from "./SystemInfo";
import AdapterListPage from "./AdapterListPage";
import AdapterEditPage from "./AdapterEditPage";
import {withTranslation} from "react-i18next";
import SelectThemeBox from "./SelectThemeBox";
import ThemeSelect from "./common/select/ThemeSelect";
import SessionListPage from "./SessionListPage";
const {Header, Footer, Content} = Layout;
@@ -135,10 +135,12 @@ class App extends Component {
this.setState({selectedMenuKey: "/applications"});
} else if (uri.includes("/resources")) {
this.setState({selectedMenuKey: "/resources"});
} else if (uri.includes("/tokens")) {
this.setState({selectedMenuKey: "/tokens"});
} else if (uri.includes("/records")) {
this.setState({selectedMenuKey: "/records"});
} else if (uri.includes("/tokens")) {
this.setState({selectedMenuKey: "/tokens"});
} else if (uri.includes("/sessions")) {
this.setState({selectedMenuKey: "/sessions"});
} else if (uri.includes("/webhooks")) {
this.setState({selectedMenuKey: "/webhooks"});
} else if (uri.includes("/syncers")) {
@@ -352,7 +354,7 @@ class App extends Component {
return (
<React.Fragment>
{this.renderRightDropdown()}
<SelectThemeBox
<ThemeSelect
themeAlgorithm={this.state.themeAlgorithm}
onChange={(nextThemeAlgorithm) => {
this.setState({
@@ -360,7 +362,7 @@ class App extends Component {
logo: this.getLogo(nextThemeAlgorithm),
});
}} />
<SelectLanguageBox languages={this.state.account.organization.languages} />
<LanguageSelect languages={this.state.account.organization.languages} />
</React.Fragment>
);
}

View File

@@ -25,9 +25,9 @@ import * as ResourceBackend from "./backend/ResourceBackend";
import SignupPage from "./auth/SignupPage";
import LoginPage from "./auth/LoginPage";
import i18next from "i18next";
import UrlTable from "./UrlTable";
import ProviderTable from "./ProviderTable";
import SignupTable from "./SignupTable";
import UrlTable from "./table/UrlTable";
import ProviderTable from "./table/ProviderTable";
import SignupTable from "./table/SignupTable";
import PromptPage from "./auth/PromptPage";
import copy from "copy-to-clipboard";
@@ -867,6 +867,8 @@ class ApplicationEditPage extends React.Component {
submitApplicationEdit(willExist) {
const application = Setting.deepCopy(this.state.application);
application.providers = application.providers?.filter(provider => this.state.providers.map(provider => provider.name).includes(provider.name));
ApplicationBackend.updateApplication("admin", this.state.applicationName, application)
.then((res) => {
if (res.status === "ok") {

View File

@@ -21,8 +21,8 @@ import * as Setting from "./Setting";
import * as Conf from "./Conf";
import i18next from "i18next";
import {LinkOutlined} from "@ant-design/icons";
import LdapTable from "./LdapTable";
import AccountTable from "./AccountTable";
import LdapTable from "./table/LdapTable";
import AccountTable from "./table/AccountTable";
import ThemeEditor from "./common/theme/ThemeEditor";
const {Option} = Select;

View File

@@ -19,12 +19,12 @@ import * as ProviderBackend from "./backend/ProviderBackend";
import * as Setting from "./Setting";
import i18next from "i18next";
import {authConfig} from "./auth/Auth";
import * as ProviderEditTestEmail from "./TestEmailWidget";
import * as ProviderEditTestSms from "./TestSmsWidget";
import * as ProviderEditTestEmail from "./common/TestEmailWidget";
import * as ProviderEditTestSms from "./common/TestSmsWidget";
import copy from "copy-to-clipboard";
import {CaptchaPreview} from "./common/CaptchaPreview";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import {CountryCodeSelect} from "./common/CountryCodeSelect";
import {CountryCodeSelect} from "./common/select/CountryCodeSelect";
const {Option} = Select;
const {TextArea} = Input;
@@ -110,7 +110,7 @@ class ProviderEditPage extends React.Component {
getClientSecretLabel(provider) {
switch (provider.category) {
case "Email":
return Setting.getLabel(i18next.t("login:Password"), i18next.t("login:Password - Tooltip"));
return Setting.getLabel(i18next.t("general:Password"), i18next.t("general:Password - Tooltip"));
case "SMS":
if (provider.type === "Volc Engine SMS") {
return Setting.getLabel(i18next.t("provider:Secret access key"), i18next.t("provider:Secret access key - Tooltip"));
@@ -130,6 +130,24 @@ class ProviderEditPage extends React.Component {
}
}
getProviderSubTypeOptions(type) {
if (type === "WeCom" || type === "Infoflow") {
return (
[
{id: "Internal", name: i18next.t("provider:Internal")},
{id: "Third-party", name: i18next.t("provider:Third-party")},
]
);
} else if (type === "Aliyun Captcha") {
return [
{id: "nc", name: i18next.t("provider:Sliding Validation")},
{id: "ic", name: i18next.t("provider:Intelligent Validation")},
];
} else {
return [];
}
}
getAppIdRow(provider) {
let text = "";
let tooltip = "";
@@ -315,7 +333,7 @@ class ProviderEditPage extends React.Component {
this.updateProviderField("subType", value);
}}>
{
Setting.getProviderSubTypeOptions(this.state.provider.type).map((providerSubType, index) => <Option key={index} value={providerSubType.id}>{providerSubType.name}</Option>)
this.getProviderSubTypeOptions(this.state.provider.type).map((providerSubType, index) => <Option key={index} value={providerSubType.id}>{providerSubType.name}</Option>)
}
</Select>
</Col>
@@ -331,7 +349,10 @@ class ProviderEditPage extends React.Component {
this.updateProviderField("method", value);
}}>
{
[{name: "Normal"}, {name: "Silent"}].map((method, index) => <Option key={index} value={method.name}>{method.name}</Option>)
[
{id: "Normal", name: i18next.t("provider:Normal")},
{id: "Silent", name: i18next.t("provider:Silent")},
].map((method, index) => <Option key={index} value={method.name}>{method.name}</Option>)
}
</Select>
</Col>
@@ -484,7 +505,7 @@ class ProviderEditPage extends React.Component {
)
}
{
this.state.provider.type !== "Adfs" && this.state.provider.type !== "Casdoor" && this.state.provider.type !== "Okta" ? null : (
this.state.provider.type !== "Adfs" && this.state.provider.type !== "AzureAD" && this.state.provider.type !== "Casdoor" && this.state.provider.type !== "Okta" ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={2}>
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :

View File

@@ -14,7 +14,7 @@
import React from "react";
import {Link} from "react-router-dom";
import {Checkbox, Form, Modal, Select, Tag, Tooltip, message, theme} from "antd";
import {Select, Tag, Tooltip, message, theme} from "antd";
import {QuestionCircleTwoTone} from "@ant-design/icons";
import {isMobile as isMobileDevice} from "react-device-detect";
import "./i18n";
@@ -38,7 +38,7 @@ export const Countries = [{label: "English", key: "en", country: "US", alt: "Eng
{label: "Español", key: "es", country: "ES", alt: "Español"},
{label: "Français", key: "fr", country: "FR", alt: "Français"},
{label: "Deutsch", key: "de", country: "DE", alt: "Deutsch"},
{label: "Bahasa Indonesia", key: "id", country: "ID", alt: "Bahasa Indonesia"},
{label: "Indonesia", key: "id", country: "ID", alt: "Indonesia"},
{label: "日本語", key: "ja", country: "JP", alt: "日本語"},
{label: "한국어", key: "ko", country: "KR", alt: "한국어"},
{label: "Русский", key: "ru", country: "RU", alt: "Русский"},
@@ -552,10 +552,6 @@ export function addRow(array, row, position = "end") {
return position === "end" ? [...array, row] : [row, ...array];
}
export function prependRow(array, row) {
return [row, ...array];
}
export function deleteRow(array, i) {
// return array = array.slice(0, i).concat(array.slice(i + 1));
return [...array.slice(0, i), ...array.slice(i + 1)];
@@ -585,76 +581,6 @@ export function isMobile() {
return isMobileDevice;
}
export function getTermsOfUseContent(url, setTermsOfUseContent) {
fetch(url, {
method: "GET",
}).then(r => {
r.text().then(setTermsOfUseContent);
});
}
export function isAgreementRequired(application) {
if (application) {
const agreementItem = application.signupItems.find(item => item.name === "Agreement");
if (!agreementItem || agreementItem.rule === "None" || !agreementItem.rule) {
return false;
}
if (agreementItem.required) {
return true;
}
}
return false;
}
export function isDefaultTrue(application) {
const agreementItem = application.signupItems.find(item => item.name === "Agreement");
return isAgreementRequired(application) && agreementItem.rule === "Signin (Default True)";
}
export function renderAgreement(required, onClick, noStyle, layout, initialValue) {
return (
<Form.Item
name="agreement"
key="agreement"
valuePropName="checked"
rules={[
{
required: required,
message: i18next.t("signup:Please accept the agreement!"),
},
]}
{...layout}
noStyle={noStyle}
initialValue={initialValue}
>
<Checkbox style={{float: "left"}}>
{i18next.t("signup:Accept")}&nbsp;
<a onClick={onClick}>
{i18next.t("signup:Terms of Use")}
</a>
</Checkbox>
</Form.Item>
);
}
export function renderModal(isOpen, onOk, onCancel, doc) {
return (
<Modal
title={i18next.t("signup:Terms of Use")}
open={isOpen}
width={"55vw"}
closable={false}
okText={i18next.t("signup:Accept")}
cancelText={i18next.t("signup:Decline")}
onOk={onOk}
onCancel={onCancel}
>
<iframe title={"terms"} style={{border: 0, width: "100%", height: "60vh"}} srcDoc={doc} />
</Modal>
);
}
export function getFormattedDate(date) {
if (date === undefined) {
return null;
@@ -731,14 +657,6 @@ export function getAvatarColor(s) {
return colorList[hash % 4];
}
export function getLogo(theme) {
if (theme === "Dark") {
return `${StaticBaseUrl}/img/casdoor-logo_1185x256_dark.png`;
} else {
return `${StaticBaseUrl}/img/casdoor-logo_1185x256.png`;
}
}
export function getLanguageText(text) {
if (!text.includes("|")) {
return text;
@@ -763,11 +681,6 @@ export function setLanguage(language) {
i18next.changeLanguage(language);
}
export function setTheme(themeKey) {
localStorage.setItem("theme", themeKey);
dispatchEvent(new Event("changeTheme"));
}
export function getAcceptLanguage() {
if (i18next.language === null || i18next.language === "") {
return "en;q=0.9,en;q=0.8";
@@ -948,24 +861,6 @@ export function getProviderTypeOptions(category) {
}
}
export function getProviderSubTypeOptions(type) {
if (type === "WeCom" || type === "Infoflow") {
return (
[
{id: "Internal", name: "Internal"},
{id: "Third-party", name: "Third-party"},
]
);
} else if (type === "Aliyun Captcha") {
return [
{id: "nc", name: "Sliding Validation"},
{id: "ic", name: "Intelligent Validation"},
];
} else {
return [];
}
}
export function renderLogo(application) {
if (application === null) {
return null;
@@ -1239,94 +1134,3 @@ export function inIframe() {
return true;
}
}
export function getSyncerTableColumns(syncer) {
switch (syncer.type) {
case "Keycloak":
return [
{
"name": "ID",
"type": "string",
"casdoorName": "Id",
"isHashed": true,
"values": [
],
},
{
"name": "USERNAME",
"type": "string",
"casdoorName": "Name",
"isHashed": true,
"values": [
],
},
{
"name": "LAST_NAME+FIRST_NAME",
"type": "string",
"casdoorName": "DisplayName",
"isHashed": true,
"values": [
],
},
{
"name": "EMAIL",
"type": "string",
"casdoorName": "Email",
"isHashed": true,
"values": [
],
},
{
"name": "EMAIL_VERIFIED",
"type": "boolean",
"casdoorName": "EmailVerified",
"isHashed": true,
"values": [
],
},
{
"name": "FIRST_NAME",
"type": "string",
"casdoorName": "FirstName",
"isHashed": true,
"values": [
],
},
{
"name": "LAST_NAME",
"type": "string",
"casdoorName": "LastName",
"isHashed": true,
"values": [
],
},
{
"name": "CREATED_TIMESTAMP",
"type": "string",
"casdoorName": "CreatedTime",
"isHashed": true,
"values": [
],
},
{
"name": "ENABLED",
"type": "boolean",
"casdoorName": "IsForbidden",
"isHashed": true,
"values": [
],
},
];
default:
return [];
}
}

View File

@@ -19,7 +19,7 @@ import * as SyncerBackend from "./backend/SyncerBackend";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as Setting from "./Setting";
import i18next from "i18next";
import SyncerTableColumnTable from "./SyncerTableColumnTable";
import SyncerTableColumnTable from "./table/SyncerTableColumnTable";
import {Controlled as CodeMirror} from "react-codemirror2";
import "codemirror/lib/codemirror.css";
@@ -80,6 +80,97 @@ class SyncerEditPage extends React.Component {
});
}
getSyncerTableColumns(syncer) {
switch (syncer.type) {
case "Keycloak":
return [
{
"name": "ID",
"type": "string",
"casdoorName": "Id",
"isHashed": true,
"values": [
],
},
{
"name": "USERNAME",
"type": "string",
"casdoorName": "Name",
"isHashed": true,
"values": [
],
},
{
"name": "LAST_NAME+FIRST_NAME",
"type": "string",
"casdoorName": "DisplayName",
"isHashed": true,
"values": [
],
},
{
"name": "EMAIL",
"type": "string",
"casdoorName": "Email",
"isHashed": true,
"values": [
],
},
{
"name": "EMAIL_VERIFIED",
"type": "boolean",
"casdoorName": "EmailVerified",
"isHashed": true,
"values": [
],
},
{
"name": "FIRST_NAME",
"type": "string",
"casdoorName": "FirstName",
"isHashed": true,
"values": [
],
},
{
"name": "LAST_NAME",
"type": "string",
"casdoorName": "LastName",
"isHashed": true,
"values": [
],
},
{
"name": "CREATED_TIMESTAMP",
"type": "string",
"casdoorName": "CreatedTime",
"isHashed": true,
"values": [
],
},
{
"name": "ENABLED",
"type": "boolean",
"casdoorName": "IsForbidden",
"isHashed": true,
"values": [
],
},
];
default:
return [];
}
}
renderSyncer() {
return (
<Card size="small" title={
@@ -120,7 +211,7 @@ class SyncerEditPage extends React.Component {
<Select virtual={false} style={{width: "100%"}} value={this.state.syncer.type} onChange={(value => {
this.updateSyncerField("type", value);
const syncer = this.state.syncer;
syncer["tableColumns"] = Setting.getSyncerTableColumns(this.state.syncer);
syncer["tableColumns"] = this.getSyncerTableColumns(this.state.syncer);
syncer.table = (value === "Keycloak") ? "user_entity" : this.state.syncer.table;
this.setState({
syncer: syncer,

View File

@@ -45,7 +45,7 @@ class SystemInfo extends React.Component {
}).catch(error => {
Setting.showMessage("error", `System info failed to get: ${error}`);
});
}, 1000 * 3);
}, 1000 * 2);
this.setState({intervalId: id});
}).catch(error => {
Setting.showMessage("error", `System info failed to get: ${error}`);

View File

@@ -18,18 +18,18 @@ import * as UserBackend from "./backend/UserBackend";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as Setting from "./Setting";
import i18next from "i18next";
import CropperDiv from "./CropperDiv.js";
import CropperDivModal from "./common/modal/CropperDivModal.js";
import * as ApplicationBackend from "./backend/ApplicationBackend";
import PasswordModal from "./PasswordModal";
import ResetModal from "./ResetModal";
import AffiliationSelect from "./common/AffiliationSelect";
import PasswordModal from "./common/modal/PasswordModal";
import ResetModal from "./common/modal/ResetModal";
import AffiliationSelect from "./common/select/AffiliationSelect";
import OAuthWidget from "./common/OAuthWidget";
import SamlWidget from "./common/SamlWidget";
import SelectRegionBox from "./SelectRegionBox";
import WebAuthnCredentialTable from "./WebauthnCredentialTable";
import ManagedAccountTable from "./ManagedAccountTable";
import PropertyTable from "./propertyTable";
import {CountryCodeSelect} from "./common/CountryCodeSelect";
import RegionSelect from "./common/select/RegionSelect";
import WebAuthnCredentialTable from "./table/WebauthnCredentialTable";
import ManagedAccountTable from "./table/ManagedAccountTable";
import PropertyTable from "./table/propertyTable";
import {CountryCodeSelect} from "./common/select/CountryCodeSelect";
const {Option} = Select;
@@ -253,7 +253,7 @@ class UserEditPage extends React.Component {
</Col>
</Row>
<Row style={{marginTop: "20px"}}>
<CropperDiv buttonText={`${i18next.t("user:Upload a photo")}...`} title={i18next.t("user:Upload a photo")} user={this.state.user} organization={this.state.organizations.find(organization => organization.name === this.state.organizationName)} />
<CropperDivModal buttonText={`${i18next.t("user:Upload a photo")}...`} title={i18next.t("user:Upload a photo")} user={this.state.user} organization={this.state.organizations.find(organization => organization.name === this.state.organizationName)} />
</Row>
</Col>
</Row>
@@ -341,7 +341,7 @@ class UserEditPage extends React.Component {
{Setting.getLabel(i18next.t("user:Country/Region"), i18next.t("user:Country/Region - Tooltip"))} :
</Col>
<Col span={22} >
<SelectRegionBox defaultValue={this.state.user.region} onChange={(value) => {
<RegionSelect defaultValue={this.state.user.region} onChange={(value) => {
this.updateUserField("region", value);
}} />
</Col>
@@ -614,7 +614,7 @@ class UserEditPage extends React.Component {
);
}
submitUserEdit(willExist) {
submitUserEdit(needExit) {
const user = Setting.deepCopy(this.state.user);
UserBackend.updateUser(this.state.organizationName, this.state.userName, user)
.then((res) => {
@@ -626,13 +626,18 @@ class UserEditPage extends React.Component {
});
if (this.props.history !== undefined) {
if (willExist) {
this.props.history.push("/users");
if (needExit) {
const userListUrl = sessionStorage.getItem("userListUrl");
if (userListUrl !== null) {
this.props.history.push(userListUrl);
} else {
this.props.history.push("/users");
}
} else {
this.props.history.push(`/users/${this.state.user.owner}/${this.state.user.name}`);
}
} else {
if (willExist) {
if (needExit) {
if (this.state.returnUrl) {
window.location.href = this.state.returnUrl;
}

View File

@@ -70,6 +70,7 @@ class UserListPage extends BaseListPage {
UserBackend.addUser(newUser)
.then((res) => {
if (res.status === "ok") {
sessionStorage.setItem("userListUrl", window.location.pathname);
this.props.history.push({pathname: `/users/${newUser.owner}/${newUser.name}`, mode: "add"});
Setting.showMessage("success", i18next.t("general:Successfully added"));
} else {
@@ -341,7 +342,10 @@ class UserListPage extends BaseListPage {
const disabled = (record.owner === this.props.account.owner && record.name === this.props.account.name);
return (
<div>
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/users/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => {
sessionStorage.setItem("userListUrl", window.location.pathname);
this.props.history.push(`/users/${record.owner}/${record.name}`);
}}>{i18next.t("general:Edit")}</Button>
<PopconfirmModal
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
onConfirm={() => this.deleteUser(index)}
@@ -402,6 +406,8 @@ class UserListPage extends BaseListPage {
const users = res.data;
if (users.length > 0) {
this.getOrganization(users[0].owner);
} else {
this.getOrganization(this.state.organizationName);
}
} else {
if (Setting.isResponseDenied(res)) {
@@ -430,6 +436,8 @@ class UserListPage extends BaseListPage {
const users = res.data;
if (users.length > 0) {
this.getOrganization(users[0].owner);
} else {
this.getOrganization(this.state.organizationName);
}
} else {
if (Setting.isResponseDenied(res)) {

View File

@@ -19,7 +19,7 @@ import * as WebhookBackend from "./backend/WebhookBackend";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as Setting from "./Setting";
import i18next from "i18next";
import WebhookHeaderTable from "./WebhookHeaderTable";
import WebhookHeaderTable from "./table/WebhookHeaderTable";
import {Controlled as CodeMirror} from "react-codemirror2";
import "codemirror/lib/codemirror.css";

View File

@@ -22,7 +22,7 @@ import i18next from "i18next";
import {SendCodeInput} from "../common/SendCodeInput";
import * as UserBackend from "../backend/UserBackend";
import {CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
import CustomGithubCorner from "../CustomGithubCorner";
import CustomGithubCorner from "../common/CustomGithubCorner";
import {withRouter} from "react-router-dom";
const {Option} = Select;
@@ -32,11 +32,9 @@ class ForgetPage extends React.Component {
this.state = {
classes: props,
applicationName: props.applicationName ?? props.match.params?.applicationName,
application: null,
msg: null,
userId: "",
username: "",
name: "",
username: "",
phone: "",
email: "",
dest: "",
@@ -49,7 +47,7 @@ class ForgetPage extends React.Component {
}
componentDidMount() {
if (this.getApplicationObj() === null) {
if (this.getApplicationObj() === undefined) {
if (this.state.applicationName !== undefined) {
this.getApplication();
} else {
@@ -66,14 +64,11 @@ class ForgetPage extends React.Component {
ApplicationBackend.getApplication("admin", this.state.applicationName)
.then((application) => {
this.onUpdateApplication(application);
this.setState({
application: application,
});
});
}
getApplicationObj() {
return this.props.application ?? this.state.application;
return this.props.application;
}
onUpdateApplication(application) {
@@ -90,7 +85,7 @@ class ForgetPage extends React.Component {
const phone = res.data.phone;
const email = res.data.email;
if (phone === "" && email === "") {
if (!phone && !email) {
Setting.showMessage("error", "no verification method!");
} else {
this.setState({
@@ -128,18 +123,16 @@ class ForgetPage extends React.Component {
});
break;
case "step2":
const oAuthParams = Util.getOAuthGetParameters();
AuthBackend.login({
UserBackend.verifyCode({
application: forms.step2.getFieldValue("application"),
organization: forms.step2.getFieldValue("organization"),
username: forms.step2.getFieldValue("dest"),
name: this.state.name,
code: forms.step2.getFieldValue("code"),
type: "login",
}, oAuthParams).then(res => {
}).then(res => {
if (res.status === "ok") {
this.setState({current: 2, userId: res.data});
this.setState({current: 2, code: forms.step2.getFieldValue("code")});
} else {
Setting.showMessage("error", res.msg);
}
@@ -154,7 +147,7 @@ class ForgetPage extends React.Component {
onFinish(values) {
values.username = this.state.name;
values.userOwner = this.getApplicationObj()?.organizationObj.name;
UserBackend.setPassword(values.userOwner, values.username, "", values?.newPassword).then(res => {
UserBackend.setPassword(values.userOwner, values.username, "", values?.newPassword, this.state.code).then(res => {
if (res.status === "ok") {
Setting.redirectToLoginPage(this.getApplicationObj(), this.props.history);
} else {
@@ -391,7 +384,6 @@ class ForgetPage extends React.Component {
hasFeedback
>
<Input.Password
disabled={this.state.userId === ""}
prefix={<LockOutlined />}
placeholder={i18next.t("general:Password")}
/>
@@ -418,14 +410,13 @@ class ForgetPage extends React.Component {
]}
>
<Input.Password
disabled={this.state.userId === ""}
prefix={<CheckCircleOutlined />}
placeholder={i18next.t("signup:Confirm")}
/>
</Form.Item>
<br />
<Form.Item hidden={this.state.current !== 2}>
<Button block type="primary" htmlType="submit" disabled={this.state.userId === ""}>
<Button block type="primary" htmlType="submit">
{i18next.t("forget:Change Password")}
</Button>
</Form.Item>
@@ -436,6 +427,9 @@ class ForgetPage extends React.Component {
render() {
const application = this.getApplicationObj();
if (application === undefined) {
return null;
}
if (application === null) {
return Util.renderMessageLarge(this, this.state.msg);
}

View File

@@ -14,11 +14,10 @@
import i18next from "i18next";
import {createButton} from "react-social-login-buttons";
import {StaticBaseUrl} from "../Setting";
function LoginButton({type, align = "center", style = {background: "#ffffff", color: "#000000"}, activeStyle = {background: "#ededee"}}) {
function LoginButton({type, logoUrl, align = "center", style = {background: "#ffffff", color: "#000000"}, activeStyle = {background: "#ededee"}}) {
function Icon({width = 24, height = 24, color}) {
return <img src={`${StaticBaseUrl}/buttons/${type.toLowerCase()}.svg`} alt={`Sign in with ${type}`} style={{width: width, height: height}} />;
return <img src={logoUrl} alt={`Sign in with ${type}`} style={{width: width, height: height}} />;
}
const config = {
text: `Sign in with ${type}`,

View File

@@ -24,12 +24,13 @@ import * as Provider from "./Provider";
import * as ProviderButton from "./ProviderButton";
import * as Util from "./Util";
import * as Setting from "../Setting";
import * as AgreementModal from "../common/modal/AgreementModal";
import SelfLoginButton from "./SelfLoginButton";
import i18next from "i18next";
import CustomGithubCorner from "../CustomGithubCorner";
import CustomGithubCorner from "../common/CustomGithubCorner";
import {SendCodeInput} from "../common/SendCodeInput";
import SelectLanguageBox from "../SelectLanguageBox";
import {CaptchaModal} from "../common/CaptchaModal";
import LanguageSelect from "../common/select/LanguageSelect";
import {CaptchaModal} from "../common/modal/CaptchaModal";
import RedirectForm from "../common/RedirectForm";
class LoginPage extends React.Component {
@@ -38,10 +39,9 @@ class LoginPage extends React.Component {
this.state = {
classes: props,
type: props.type,
applicationName: props.applicationName !== undefined ? props.applicationName : (props.match === undefined ? null : props.match.params.applicationName),
owner: props.owner !== undefined ? props.owner : (props.match === undefined ? null : props.match.params.owner),
application: null,
mode: props.mode !== undefined ? props.mode : (props.match === undefined ? null : props.match.params.mode), // "signup" or "signin"
applicationName: props.applicationName ?? (props.match?.params?.applicationName ?? null),
owner: props.owner ?? (props.match?.params?.owner ?? null),
mode: props.mode ?? (props.match?.params?.mode ?? null), // "signup" or "signin"
msg: null,
username: null,
validEmailOrPhone: false,
@@ -58,21 +58,19 @@ class LoginPage extends React.Component {
};
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
this.state.owner = props.match?.params.owner;
this.state.applicationName = props.match?.params.casApplicationName;
this.state.owner = props.match?.params?.owner;
this.state.applicationName = props.match?.params?.casApplicationName;
}
this.form = React.createRef();
}
componentDidMount() {
if (this.getApplicationObj() === null) {
if (this.state.type === "login" || this.state.type === "cas") {
if (this.getApplicationObj() === undefined) {
if (this.state.type === "login" || this.state.type === "cas" || this.state.type === "saml") {
this.getApplication();
} else if (this.state.type === "code") {
this.getApplicationLogin();
} else if (this.state.type === "saml") {
this.getSamlApplication();
} else {
Setting.showMessage("error", `Unknown authentication type: ${this.state.type}`);
}
@@ -80,14 +78,35 @@ class LoginPage extends React.Component {
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (this.state.application && !prevState.application) {
const captchaProviderItems = this.getCaptchaProviderItems(this.state.application);
if (!captchaProviderItems) {
return;
if (prevProps.application !== this.props.application) {
const captchaProviderItems = this.getCaptchaProviderItems(this.props.application);
if (captchaProviderItems) {
this.setState({enableCaptchaModal: captchaProviderItems.some(providerItem => providerItem.rule === "Always")});
}
this.setState({enableCaptchaModal: captchaProviderItems.some(providerItem => providerItem.rule === "Always")});
if (this.props.account && this.props.account.owner === this.props.application?.organization) {
const params = new URLSearchParams(this.props.location.search);
const silentSignin = params.get("silentSignin");
if (silentSignin !== null) {
this.sendSilentSigninData("signing-in");
const values = {};
values["application"] = this.props.application.name;
this.login(values);
}
if (params.get("popup") === "1") {
window.addEventListener("beforeunload", () => {
this.sendPopupData({type: "windowClosed"}, params.get("redirect_uri"));
});
}
if (this.props.application.enableAutoSignin) {
const values = {};
values["application"] = this.props.application.name;
this.login(values);
}
}
}
}
@@ -96,47 +115,37 @@ class LoginPage extends React.Component {
AuthBackend.getApplicationLogin(oAuthParams)
.then((res) => {
if (res.status === "ok") {
this.onUpdateApplication(res.data);
this.setState({
application: res.data,
});
const application = res.data;
this.onUpdateApplication(application);
} else {
// Setting.showMessage("error", res.msg);
this.onUpdateApplication(null);
this.setState({
application: res.data,
msg: res.msg,
});
}
});
return null;
}
getApplication() {
if (this.state.applicationName === null) {
return;
return null;
}
if (this.state.owner === null || this.state.owner === undefined || this.state.owner === "") {
if (this.state.owner === null || this.state.type === "saml") {
ApplicationBackend.getApplication("admin", this.state.applicationName)
.then((application) => {
this.onUpdateApplication(application);
this.setState({
application: application,
}, () => Setting.getTermsOfUseContent(this.state.application.termsOfUse, res => {
this.setState({termsOfUseContent: res});
}));
});
} else {
OrganizationBackend.getDefaultApplication("admin", this.state.owner)
.then((res) => {
if (res.status === "ok") {
this.onUpdateApplication(res.data);
const application = res.data;
this.onUpdateApplication(application);
this.setState({
application: res.data,
applicationName: res.data.name,
}, () => Setting.getTermsOfUseContent(this.state.application.termsOfUse, res => {
this.setState({termsOfUseContent: res});
}));
});
} else {
this.onUpdateApplication(null);
Setting.showMessage("error", res.msg);
@@ -145,21 +154,8 @@ class LoginPage extends React.Component {
}
}
getSamlApplication() {
if (this.state.applicationName === null) {
return;
}
ApplicationBackend.getApplication(this.state.owner, this.state.applicationName)
.then((application) => {
this.onUpdateApplication(application);
this.setState({
application: application,
});
});
}
getApplicationObj() {
return this.props.application ?? this.state.application;
return this.props.application;
}
onUpdateAccount(account) {
@@ -183,24 +179,25 @@ class LoginPage extends React.Component {
}
populateOauthValues(values) {
if (this.getApplicationObj()?.organization) {
values["organization"] = this.getApplicationObj().organization;
}
const oAuthParams = Util.getOAuthGetParameters();
if (oAuthParams !== null && oAuthParams.responseType !== null && oAuthParams.responseType !== "") {
values["type"] = oAuthParams.responseType;
} else {
values["type"] = this.state.type;
}
if (oAuthParams !== null) {
values["type"] = oAuthParams?.responseType ?? this.state.type;
if (oAuthParams?.samlRequest) {
values["samlRequest"] = oAuthParams.samlRequest;
}
if (values["samlRequest"] !== null && values["samlRequest"] !== "" && values["samlRequest"] !== undefined) {
values["type"] = "saml";
values["relayState"] = oAuthParams.relayState;
}
}
if (this.getApplicationObj()?.organization) {
values["organization"] = this.getApplicationObj().organization;
sendPopupData(message, redirectUri) {
const params = new URLSearchParams(this.props.location.search);
if (params.get("popup") === "1") {
window.opener.postMessage(message, redirectUri);
}
}
@@ -243,6 +240,7 @@ class LoginPage extends React.Component {
}
} else {
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
this.sendPopupData({type: "loginSuccess", data: {code: code, state: oAuthParams.state}}, oAuthParams.redirectUri);
}
}
}
@@ -297,7 +295,6 @@ class LoginPage extends React.Component {
// OAuth
const oAuthParams = Util.getOAuthGetParameters();
this.populateOauthValues(values);
AuthBackend.login(values, oAuthParams)
.then((res) => {
if (res.status === "ok") {
@@ -310,7 +307,6 @@ class LoginPage extends React.Component {
Setting.goToLink(link);
} else if (responseType === "code") {
this.postCodeLoginAction(res);
// Setting.showMessage("success", `Authorization code: ${res.data}`);
} else if (responseType === "token" || responseType === "id_token") {
const accessToken = res.data;
Setting.goToLink(`${oAuthParams.redirectUri}#${responseType}=${accessToken}?state=${oAuthParams.state}&token_type=bearer`);
@@ -463,25 +459,17 @@ class LoginPage extends React.Component {
this.renderPasswordOrCodeInput()
}
</Row>
<Form.Item>
{
Setting.isAgreementRequired(application) ?
Setting.renderAgreement(true, () => {
this.setState({
isTermsOfUseVisible: true,
});
}, true, {}, Setting.isDefaultTrue(application)) : (
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
<Checkbox style={{float: "left"}} disabled={!application.enablePassword}>
{i18next.t("login:Auto sign in")}
</Checkbox>
</Form.Item>
)
}
<div style={{display: "inline-flex", justifyContent: "space-between", width: "320px", marginBottom: AgreementModal.isAgreementRequired(application) ? "5px" : "25px"}}>
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
<Checkbox style={{float: "left"}} disabled={!application.enablePassword}>
{i18next.t("login:Auto sign in")}
</Checkbox>
</Form.Item>
{
Setting.renderForgetLink(application, i18next.t("login:Forgot password?"))
}
</Form.Item>
</div>
{AgreementModal.isAgreementRequired(application) ? AgreementModal.renderAgreementFormItem(application, true, {}, this) : null}
<Form.Item>
<Button
type="primary"
@@ -626,31 +614,12 @@ class LoginPage extends React.Component {
}
const application = this.getApplicationObj();
if (this.props.account.owner !== application.organization) {
if (this.props.account.owner !== application?.organization) {
return null;
}
const params = new URLSearchParams(this.props.location.search);
const silentSignin = params.get("silentSignin");
if (silentSignin !== null) {
this.sendSilentSigninData("signing-in");
const values = {};
values["application"] = application.name;
this.onFinish(values);
}
if (application.enableAutoSignin) {
const values = {};
values["application"] = application.name;
this.onFinish(values);
}
return (
<div>
{/* {*/}
{/* JSON.stringify(silentSignin)*/}
{/* }*/}
<div style={{fontSize: 16, textAlign: "left"}}>
{i18next.t("login:Continue with")}&nbsp;:
</div>
@@ -658,7 +627,7 @@ class LoginPage extends React.Component {
<SelfLoginButton account={this.props.account} onClick={() => {
const values = {};
values["application"] = application.name;
this.onFinish(values);
this.login(values);
}} />
<br />
<br />
@@ -800,6 +769,9 @@ class LoginPage extends React.Component {
render() {
const application = this.getApplicationObj();
if (application === undefined) {
return null;
}
if (application === null) {
return Util.renderMessageLarge(this, this.state.msg);
}
@@ -842,29 +814,13 @@ class LoginPage extends React.Component {
{
Setting.renderLogo(application)
}
{/* {*/}
{/* this.state.clientId !== null ? "Redirect" : null*/}
{/* }*/}
<SelectLanguageBox languages={application.organizationObj.languages} style={{top: "55px", right: "5px", position: "absolute"}} />
<LanguageSelect languages={application.organizationObj.languages} style={{top: "55px", right: "5px", position: "absolute"}} />
{
this.renderSignedInBox()
}
{
this.renderForm(application)
}
{
Setting.renderModal(this.state.isTermsOfUseVisible, () => {
this.form.current.setFieldsValue({agreement: true});
this.setState({
isTermsOfUseVisible: false,
});
}, () => {
this.form.current.setFieldsValue({agreement: false});
this.setState({
isTermsOfUseVisible: false,
});
}, this.state.termsOfUseContent)
}
</div>
</div>
</div>

View File

@@ -19,9 +19,9 @@ import * as UserBackend from "../backend/UserBackend";
import * as AuthBackend from "./AuthBackend";
import * as Setting from "../Setting";
import i18next from "i18next";
import AffiliationSelect from "../common/AffiliationSelect";
import AffiliationSelect from "../common/select/AffiliationSelect";
import OAuthWidget from "../common/OAuthWidget";
import SelectRegionBox from "../SelectRegionBox";
import RegionSelect from "../common/select/RegionSelect";
import {withRouter} from "react-router-dom";
class PromptPage extends React.Component {
@@ -151,7 +151,7 @@ class PromptPage extends React.Component {
</span>
</Col>
<Col >
<SelectRegionBox defaultValue={this.state.user.region} onChange={(value) => {
<RegionSelect defaultValue={this.state.user.region} onChange={(value) => {
this.updateUserFieldWithoutSubmit("region", value);
}} />
</Col>

View File

@@ -378,6 +378,12 @@ export function getAuthUrl(application, provider, method) {
const state = Util.getStateFromQueryParams(application.name, provider.name, method, isShortState);
const codeChallenge = "P3S-a7dr8bgM4bF6vOyiKkKETDl16rcAzao9F8UIL1Y"; // SHA256(Base64-URL-encode("casdoor-verifier"))
if (provider.type === "AzureAD") {
if (provider.domain !== "") {
endpoint = endpoint.replace("common", provider.domain);
}
}
if (provider.type === "Google" || provider.type === "GitHub" || provider.type === "QQ" || 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"

View File

@@ -44,69 +44,70 @@ import * as AuthBackend from "./AuthBackend";
import {getEvent} from "./Util";
import {Modal} from "antd";
function getSigninButton(type) {
const text = i18next.t("login:Sign in with {type}").replace("{type}", type);
if (type === "GitHub") {
function getSigninButton(provider) {
const text = i18next.t("login:Sign in with {type}").replace("{type}", provider.type);
if (provider.type === "GitHub") {
return <GithubLoginButton text={text} align={"center"} />;
} else if (type === "Google") {
} else if (provider.type === "Google") {
return <GoogleLoginButton text={text} align={"center"} />;
} else if (type === "QQ") {
} else if (provider.type === "QQ") {
return <QqLoginButton text={text} align={"center"} />;
} else if (type === "Facebook") {
} else if (provider.type === "Facebook") {
return <FacebookLoginButton text={text} align={"center"} />;
} else if (type === "Weibo") {
} else if (provider.type === "Weibo") {
return <WeiboLoginButton text={text} align={"center"} />;
} else if (type === "Gitee") {
} else if (provider.type === "Gitee") {
return <GiteeLoginButton text={text} align={"center"} />;
} else if (type === "WeChat") {
} else if (provider.type === "WeChat") {
return <WechatLoginButton text={text} align={"center"} />;
} else if (type === "DingTalk") {
} else if (provider.type === "DingTalk") {
return <DingTalkLoginButton text={text} align={"center"} />;
} else if (type === "LinkedIn") {
} else if (provider.type === "LinkedIn") {
return <LinkedInLoginButton text={text} align={"center"} />;
} else if (type === "WeCom") {
} else if (provider.type === "WeCom") {
return <WeComLoginButton text={text} align={"center"} />;
} else if (type === "Lark") {
} else if (provider.type === "Lark") {
return <LarkLoginButton text={text} align={"center"} />;
} else if (type === "GitLab") {
} else if (provider.type === "GitLab") {
return <GitLabLoginButton text={text} align={"center"} />;
} else if (type === "Adfs") {
} else if (provider.type === "Adfs") {
return <AdfsLoginButton text={text} align={"center"} />;
} else if (type === "Casdoor") {
} else if (provider.type === "Casdoor") {
return <CasdoorLoginButton text={text} align={"center"} />;
} else if (type === "Baidu") {
} else if (provider.type === "Baidu") {
return <BaiduLoginButton text={text} align={"center"} />;
} else if (type === "Alipay") {
} else if (provider.type === "Alipay") {
return <AlipayLoginButton text={text} align={"center"} />;
} else if (type === "Infoflow") {
} else if (provider.type === "Infoflow") {
return <InfoflowLoginButton text={text} align={"center"} />;
} else if (type === "Apple") {
} else if (provider.type === "Apple") {
return <AppleLoginButton text={text} align={"center"} />;
} else if (type === "AzureAD") {
} else if (provider.type === "AzureAD") {
return <AzureADLoginButton text={text} align={"center"} />;
} else if (type === "Slack") {
} else if (provider.type === "Slack") {
return <SlackLoginButton text={text} align={"center"} />;
} else if (type === "Steam") {
} else if (provider.type === "Steam") {
return <SteamLoginButton text={text} align={"center"} />;
} else if (type === "Bilibili") {
} else if (provider.type === "Bilibili") {
return <BilibiliLoginButton text={text} align={"center"} />;
} else if (type === "Okta") {
} else if (provider.type === "Okta") {
return <OktaLoginButton text={text} align={"center"} />;
} else if (type === "Douyin") {
} else if (provider.type === "Douyin") {
return <DouyinLoginButton text={text} align={"center"} />;
} else {
return <LoginButton key={type} type={type} />;
return <LoginButton key={provider.type} type={provider.type} logoUrl={getProviderLogoURL(provider)} />;
}
}
function getSamlUrl(provider, location) {
function goToSamlUrl(provider, location) {
const params = new URLSearchParams(location.search);
const clientId = params.get("client_id");
const application = params.get("state");
const clientId = params.get("client_id") ?? "";
const state = params.get("state");
const realRedirectUri = params.get("redirect_uri");
const redirectUri = `${window.location.origin}/callback/saml`;
const providerName = provider.name;
const relayState = `${clientId}&${application}&${providerName}&${realRedirectUri}&${redirectUri}`;
const relayState = `${clientId}&${state}&${providerName}&${realRedirectUri}&${redirectUri}`;
AuthBackend.getSamlLogin(`${provider.owner}/${providerName}`, btoa(relayState)).then((res) => {
if (res.data2 === "POST") {
document.write(res.data);
@@ -148,12 +149,11 @@ export function renderProviderLogo(provider, application, width, margin, size, l
}
} else if (provider.category === "SAML") {
return (
<a key={provider.displayName} onClick={() => getSamlUrl(provider, location)}>
<a key={provider.displayName} onClick={() => goToSamlUrl(provider, location)}>
<img width={width} height={width} src={getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
</a>
);
}
} else if (provider.type === "Custom") {
// style definition
const text = i18next.t("login:Sign in with {type}").replace("{type}", provider.displayName);
@@ -172,7 +172,7 @@ export function renderProviderLogo(provider, application, width, margin, size, l
);
} else if (provider.category === "SAML") {
return (
<a key={provider.displayName} onClick={() => getSamlUrl(provider, location)} style={customAStyle}>
<a key={provider.displayName} onClick={() => goToSamlUrl(provider, location)} style={customAStyle}>
<button style={customButtonStyle}>
<img width={26} src={getProviderLogoURL(provider)} alt={provider.displayName} style={customImgStyle} />
<span style={customSpanStyle}>{text}</span>
@@ -181,14 +181,27 @@ export function renderProviderLogo(provider, application, width, margin, size, l
);
}
} else {
return (
<div key={provider.displayName} style={{marginBottom: "10px"}}>
<a href={Provider.getAuthUrl(application, provider, "signup")}>
{
getSigninButton(provider.type)
}
</a>
</div>
);
// big button, for disable password signin
if (provider.category === "SAML") {
return (
<div key={provider.displayName} style={{marginBottom: "10px"}}>
<a onClick={() => goToSamlUrl(provider, location)}>
{
getSigninButton(provider)
}
</a>
</div>
);
} else {
return (
<div key={provider.displayName} style={{marginBottom: "10px"}}>
<a href={Provider.getAuthUrl(application, provider, "signup")}>
{
getSigninButton(provider)
}
</a>
</div>
);
}
}
}

View File

@@ -49,18 +49,21 @@ class SamlCallback extends React.Component {
const params = new URLSearchParams(this.props.location.search);
const relayState = params.get("relayState");
const samlResponse = params.get("samlResponse");
const messages = atob(relayState).split("&");
const clientId = messages[0];
const applicationName = (messages[1] === "null" || messages[1] === "undefined") ? "app-built-in" : messages[1];
const clientId = messages[0] === "" ? "" : messages[0];
const application = messages[0] === "" ? "app-built-in" : "";
const state = messages[1];
const providerName = messages[2];
const redirectUri = messages[3];
const responseType = this.getResponseType(redirectUri);
const body = {
type: responseType,
application: applicationName,
clientId: clientId,
provider: providerName,
state: applicationName,
state: state,
application: application,
redirectUri: `${window.location.origin}/callback`,
method: "signup",
relayState: relayState,
@@ -71,7 +74,7 @@ class SamlCallback extends React.Component {
if (clientId === null || clientId === "") {
param = "";
} else {
param = `?clientId=${clientId}&responseType=${responseType}&redirectUri=${redirectUri}&scope=read&state=${applicationName}`;
param = `?clientId=${clientId}&responseType=${responseType}&redirectUri=${redirectUri}&scope=read&state=${state}`;
}
AuthBackend.loginWithSaml(body, param)
@@ -83,7 +86,7 @@ class SamlCallback extends React.Component {
Setting.goToLink("/");
} else if (responseType === "code") {
const code = res.data;
Setting.goToLink(`${redirectUri}?code=${code}&state=${applicationName}`);
Setting.goToLink(`${redirectUri}?code=${code}&state=${state}`);
}
} else {
this.setState({

View File

@@ -40,7 +40,7 @@ class SelfLoginButton extends React.Component {
};
const SelfLoginButton = createButton(config);
return <SelfLoginButton text={this.getAccountShowName()} onClick={() => this.props.onClick()} align={"center"} />;
return <SelfLoginButton text={this.getAccountShowName()} onClick={this.props.onClick} align={"center"} />;
}
}

View File

@@ -21,12 +21,13 @@ import i18next from "i18next";
import * as Util from "./Util";
import {authConfig} from "./Auth";
import * as ApplicationBackend from "../backend/ApplicationBackend";
import * as AgreementModal from "../common/modal/AgreementModal";
import {SendCodeInput} from "../common/SendCodeInput";
import SelectRegionBox from "../SelectRegionBox";
import CustomGithubCorner from "../CustomGithubCorner";
import SelectLanguageBox from "../SelectLanguageBox";
import RegionSelect from "../common/select/RegionSelect";
import CustomGithubCorner from "../common/CustomGithubCorner";
import LanguageSelect from "../common/select/LanguageSelect";
import {withRouter} from "react-router-dom";
import {CountryCodeSelect} from "../common/CountryCodeSelect";
import {CountryCodeSelect} from "../common/select/CountryCodeSelect";
const formItemLayout = {
labelCol: {
@@ -47,7 +48,7 @@ const formItemLayout = {
},
};
const tailFormItemLayout = {
export const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
@@ -65,8 +66,7 @@ class SignupPage extends React.Component {
super(props);
this.state = {
classes: props,
applicationName: props.match.params?.applicationName ?? authConfig.appName,
application: null,
applicationName: props.match?.params?.applicationName ?? authConfig.appName,
email: "",
phone: "",
countryCode: "",
@@ -83,20 +83,17 @@ class SignupPage extends React.Component {
}
componentDidMount() {
let applicationName = this.state.applicationName;
const oAuthParams = Util.getOAuthGetParameters();
if (oAuthParams !== null) {
applicationName = oAuthParams.state;
this.setState({applicationName: oAuthParams.state});
const signinUrl = window.location.href.replace("/signup/oauth/authorize", "/login/oauth/authorize");
sessionStorage.setItem("signinUrl", signinUrl);
}
if (this.getApplicationObj() === null) {
if (applicationName !== undefined) {
this.getApplication(applicationName);
if (this.getApplicationObj() === undefined) {
if (this.state.applicationName !== null) {
this.getApplication(this.state.applicationName);
} else {
Setting.showMessage("error", `Unknown application name: ${applicationName}`);
Setting.showMessage("error", `Unknown application name: ${this.state.applicationName}`);
}
}
}
@@ -109,15 +106,6 @@ class SignupPage extends React.Component {
ApplicationBackend.getApplication("admin", applicationName)
.then((application) => {
this.onUpdateApplication(application);
this.setState({
application: application,
});
if (application !== null && application !== undefined) {
Setting.getTermsOfUseContent(application.termsOfUse, res => {
this.setState({termsOfUseContent: res});
});
}
});
}
@@ -134,7 +122,7 @@ class SignupPage extends React.Component {
}
getApplicationObj() {
return this.props.application ?? this.state.application;
return this.props.application;
}
onUpdateAccount(account) {
@@ -318,7 +306,7 @@ class SignupPage extends React.Component {
},
]}
>
<SelectRegionBox onChange={(value) => {this.setState({region: value});}} />
<RegionSelect onChange={(value) => {this.setState({region: value});}} />
</Form.Item>
);
} else if (signupItem.name === "Email") {
@@ -398,11 +386,11 @@ class SignupPage extends React.Component {
},
({getFieldValue}) => ({
validator: (_, value) => {
if (!required && value === "") {
if (!required && !value) {
return Promise.resolve();
}
if (value !== "" && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
if (value && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
this.setState({validPhone: false});
return Promise.reject(i18next.t("signup:The input is not valid Phone!"));
}
@@ -484,32 +472,10 @@ class SignupPage extends React.Component {
</Form.Item>
);
} else if (signupItem.name === "Agreement") {
return (
Setting.renderAgreement(Setting.isAgreementRequired(application), () => {
this.setState({
isTermsOfUseVisible: true,
});
}, false, tailFormItemLayout, Setting.isDefaultTrue(application))
);
return AgreementModal.renderAgreementFormItem(application, required, tailFormItemLayout, this);
}
}
renderModal() {
return (
Setting.renderModal(this.state.isTermsOfUseVisible, () => {
this.form.current.setFieldsValue({agreement: true});
this.setState({
isTermsOfUseVisible: false,
});
}, () => {
this.form.current.setFieldsValue({agreement: false});
this.setState({
isTermsOfUseVisible: false,
});
}, this.state.termsOfUseContent)
);
}
renderForm(application) {
if (!application.enableSignUp) {
return (
@@ -596,7 +562,7 @@ class SignupPage extends React.Component {
render() {
const application = this.getApplicationObj();
if (application === null) {
if (application === undefined || application === null) {
return null;
}
@@ -622,16 +588,13 @@ class SignupPage extends React.Component {
{
Setting.renderLogo(application)
}
<SelectLanguageBox languages={application.organizationObj.languages} style={{top: "55px", right: "5px", position: "absolute"}} />
<LanguageSelect languages={application.organizationObj.languages} style={{top: "55px", right: "5px", position: "absolute"}} />
{
this.renderForm(application)
}
</div>
</div>
</div>
{
this.renderModal()
}
</React.Fragment>
);
}

View File

@@ -43,27 +43,20 @@ export function renderMessage(msg) {
export function renderMessageLarge(ths, msg) {
if (msg !== null) {
return (
<div style={{display: "inline"}}>
<Result
status="error"
title="There was a problem signing you in.."
subTitle={msg}
extra={[
<Button type="primary" key="back" onClick={() => {
window.history.go(-2);
}}>
<Result
style={{margin: "0px auto"}}
status="error"
title="There was a problem signing you in.."
subTitle={msg}
extra={[
<Button type="primary" key="back" onClick={() => {
window.history.go(-2);
}}>
Back
</Button>,
// <Button key="home" onClick={() => Setting.goToLinkSoft(ths, "/")}>
// Home
// </Button>,
// <Button type="primary" key="signup" onClick={() => Setting.goToLinkSoft(ths, "/signup")}>
// Sign Up
// </Button>,
]}
>
</Result>
</div>
</Button>,
]}
>
</Result>
);
} else {
return null;
@@ -71,7 +64,7 @@ export function renderMessageLarge(ths, msg) {
}
function getRefinedValue(value) {
return (value === null) ? "" : value;
return value ?? "";
}
export function getCasParameters(params) {
@@ -100,7 +93,7 @@ export function getOAuthGetParameters(params) {
const relayState = getRefinedValue(queries.get("RelayState"));
const noRedirect = getRefinedValue(queries.get("noRedirect"));
if ((clientId === undefined || clientId === null || clientId === "") && (samlRequest === "" || samlRequest === undefined)) {
if (clientId === "" && samlRequest === "") {
// login
return null;
} else {

View File

@@ -55,11 +55,10 @@ export function getUserApplication(owner, name) {
}
export function updateApplication(owner, name, application) {
const newApplication = Setting.deepCopy(application);
return fetch(`${Setting.ServerUrl}/api/update-application?id=${owner}/${encodeURIComponent(name)}`, {
method: "POST",
credentials: "include",
body: JSON.stringify(newApplication),
body: JSON.stringify(application),
headers: {
"Accept-Language": Setting.getAcceptLanguage(),
},

View File

@@ -93,12 +93,16 @@ export function getAffiliationOptions(url, code) {
}).then(res => res.json());
}
export function setPassword(userOwner, userName, oldPassword, newPassword) {
export function setPassword(userOwner, userName, oldPassword, newPassword, code = "") {
const formData = new FormData();
formData.append("userOwner", userOwner);
formData.append("userName", userName);
formData.append("oldPassword", oldPassword);
formData.append("newPassword", newPassword);
if (code) {
formData.append("code", code);
}
return fetch(`${Setting.ServerUrl}/api/set-password`, {
method: "POST",
credentials: "include",
@@ -188,3 +192,14 @@ export function getCaptcha(owner, name, isCurrentProvider) {
},
}).then(res => res.json()).then(res => res.data);
}
export function verifyCode(values) {
return fetch(`${Setting.ServerUrl}/api/verify-code`, {
method: "POST",
credentials: "include",
body: JSON.stringify(values),
headers: {
"Accept-Language": Setting.getAcceptLanguage(),
},
}).then(res => res.json());
}

View File

@@ -15,7 +15,7 @@
import {Button} from "antd";
import React from "react";
import i18next from "i18next";
import {CaptchaModal} from "./CaptchaModal";
import {CaptchaModal} from "./modal/CaptchaModal";
import * as UserBackend from "../backend/UserBackend";
export const CaptchaPreview = (props) => {

View File

@@ -13,7 +13,7 @@
// limitations under the License.
import React from "react";
import * as Conf from "./Conf";
import * as Conf from "../Conf";
import GithubCorner from "react-github-corner";
class CustomGithubCorner extends React.Component {

View File

@@ -17,7 +17,7 @@ import React from "react";
import i18next from "i18next";
import * as UserBackend from "../backend/UserBackend";
import {SafetyOutlined} from "@ant-design/icons";
import {CaptchaModal} from "./CaptchaModal";
import {CaptchaModal} from "./modal/CaptchaModal";
const {Search} = Input;

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
export function sendTestEmail(provider, email) {

View File

@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
export function sendTestSms(provider, phone) {

View File

@@ -0,0 +1,126 @@
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {Checkbox, Form, Modal} from "antd";
import i18next from "i18next";
import React, {useEffect, useState} from "react";
export const AgreementModal = (props) => {
const {open, onOk, onCancel, application} = props;
const [doc, setDoc] = useState("");
useEffect(() => {
getTermsOfUseContent(application.termsOfUseUrl).then((data) => {
setDoc(data);
});
}, []);
return (
<Modal
title={i18next.t("signup:Terms of Use")}
open={open}
width={"55vw"}
closable={false}
okText={i18next.t("signup:Accept")}
cancelText={i18next.t("signup:Decline")}
onOk={onOk}
onCancel={onCancel}
>
<iframe title={"terms"} style={{border: 0, width: "100%", height: "60vh"}} srcDoc={doc} />
</Modal>
);
};
function getTermsOfUseContent(url) {
return fetch(url, {
method: "GET",
}).then(r => r.text());
}
export function isAgreementRequired(application) {
if (application) {
const agreementItem = application.signupItems.find(item => item.name === "Agreement");
if (!agreementItem || agreementItem.rule === "None" || !agreementItem.rule) {
return false;
}
if (agreementItem.required) {
return true;
}
}
return false;
}
function initDefaultValue(application) {
const agreementItem = application.signupItems.find(item => item.name === "Agreement");
return isAgreementRequired(application) && agreementItem.rule === "Signin (Default True)";
}
export function renderAgreementFormItem(application, required, layout, ths) {
return (<React.Fragment>
<Form.Item
name="agreement"
key="agreement"
valuePropName="checked"
rules={[
{
required: required,
},
() => ({
validator: (_, value) => {
if (!required) {
return Promise.resolve();
}
if (!value) {
return Promise.reject(i18next.t("signup:Please accept the agreement!"));
} else {
return Promise.resolve();
}
},
}),
]
}
{...layout}
initialValue={initDefaultValue(application)}
>
<Checkbox style={{float: "left"}}>
{i18next.t("signup:Accept")}&nbsp;
<a onClick={() => {
ths.setState({
isTermsOfUseVisible: true,
});
}}
>
{i18next.t("signup:Terms of Use")}
</a>
</Checkbox>
</Form.Item>
<AgreementModal application={application} layout={layout} open={ths.state.isTermsOfUseVisible}
onOk={() => {
ths.form.current.setFieldsValue({agreement: true});
ths.setState({
isTermsOfUseVisible: false,
});
}}
onCancel={() => {
ths.form.current.setFieldsValue({agreement: false});
ths.setState({
isTermsOfUseVisible: false,
});
}} />
</React.Fragment>
);
}

View File

@@ -15,8 +15,8 @@
import {Button, Col, Input, Modal, Row} from "antd";
import i18next from "i18next";
import React, {useEffect} from "react";
import * as UserBackend from "../backend/UserBackend";
import {CaptchaWidget} from "./CaptchaWidget";
import * as UserBackend from "../../backend/UserBackend";
import {CaptchaWidget} from "../CaptchaWidget";
import {SafetyOutlined} from "@ant-design/icons";
export const CaptchaModal = (props) => {

View File

@@ -15,12 +15,12 @@
import React, {useEffect, useState} from "react";
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";
import * as Setting from "./Setting";
import * as Setting from "../../Setting";
import {Button, Col, Modal, Row, Select} from "antd";
import i18next from "i18next";
import * as ResourceBackend from "./backend/ResourceBackend";
import * as ResourceBackend from "../../backend/ResourceBackend";
export const CropperDiv = (props) => {
export const CropperDivModal = (props) => {
const [loading, setLoading] = useState(true);
const [options, setOptions] = useState([]);
const [image, setImage] = useState("");
@@ -60,7 +60,7 @@ export const CropperDiv = (props) => {
// Setting.showMessage("success", "uploading...");
const extension = image.substring(image.indexOf("/") + 1, image.indexOf(";base64"));
const fullFilePath = `avatar/${user.owner}/${user.name}.${extension}`;
ResourceBackend.uploadResource(user.owner, user.name, "avatar", "CropperDiv", fullFilePath, blob)
ResourceBackend.uploadResource(user.owner, user.name, "avatar", "CropperDivModal", fullFilePath, blob)
.then((res) => {
if (res.status === "ok") {
window.location.href = window.location.pathname;
@@ -187,4 +187,4 @@ export const CropperDiv = (props) => {
);
};
export default CropperDiv;
export default CropperDivModal;

View File

@@ -15,8 +15,8 @@
import {Button, Col, Input, Modal, Row} from "antd";
import i18next from "i18next";
import React from "react";
import * as UserBackend from "./backend/UserBackend";
import * as Setting from "./Setting";
import * as UserBackend from "../../backend/UserBackend";
import * as Setting from "../../Setting";
export const PasswordModal = (props) => {
const [visible, setVisible] = React.useState(false);

View File

@@ -15,9 +15,9 @@
import {Button, Col, Input, Modal, Row} from "antd";
import i18next from "i18next";
import React from "react";
import * as Setting from "./Setting";
import * as UserBackend from "./backend/UserBackend";
import {SendCodeInput} from "./common/SendCodeInput";
import * as Setting from "../../Setting";
import * as UserBackend from "../../backend/UserBackend";
import {SendCodeInput} from "../SendCodeInput";
import {MailOutlined, PhoneOutlined} from "@ant-design/icons";
export const ResetModal = (props) => {

View File

@@ -1,119 +1,119 @@
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import {Cascader, Col, Input, Row, Select} from "antd";
import i18next from "i18next";
import * as UserBackend from "../backend/UserBackend";
import * as Setting from "../Setting";
class AffiliationSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
addressOptions: [],
affiliationOptions: [],
};
}
UNSAFE_componentWillMount() {
this.getAddressOptions(this.props.application);
this.getAffiliationOptions(this.props.application, this.props.user);
}
getAddressOptions(application) {
if (application.affiliationUrl === "") {
return;
}
const addressUrl = application.affiliationUrl.split("|")[0];
UserBackend.getAddressOptions(addressUrl)
.then((addressOptions) => {
this.setState({
addressOptions: addressOptions,
});
});
}
getAffiliationOptions(application, user) {
if (application.affiliationUrl === "") {
return;
}
const affiliationUrl = application.affiliationUrl.split("|")[1];
const code = user.address[user.address.length - 1];
UserBackend.getAffiliationOptions(affiliationUrl, code)
.then((affiliationOptions) => {
this.setState({
affiliationOptions: affiliationOptions,
});
});
}
updateUserField(key, value) {
this.props.onUpdateUserField(key, value);
}
render() {
return (
<React.Fragment>
{
this.props.application?.affiliationUrl === "" ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={this.props.labelSpan}>
{Setting.getLabel(i18next.t("user:Address"), i18next.t("user:Address - Tooltip"))} :
</Col>
<Col span={24 - this.props.labelSpan} >
<Cascader style={{width: "100%", maxWidth: "400px"}} value={this.props.user.address} options={this.state.addressOptions} onChange={value => {
this.updateUserField("address", value);
this.updateUserField("affiliation", "");
this.updateUserField("score", 0);
this.getAffiliationOptions(this.props.application, this.props.user);
}} placeholder={i18next.t("signup:Please input your address!")} />
</Col>
</Row>
)
}
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={this.props.labelSpan}>
{Setting.getLabel(i18next.t("user:Affiliation"), i18next.t("user:Affiliation - Tooltip"))} :
</Col>
<Col span={22} >
{
this.props.application?.affiliationUrl === "" ? (
<Input value={this.props.user.affiliation} onChange={e => {
this.updateUserField("affiliation", e.target.value);
}} />
) : (
<Select virtual={false} style={{width: "100%"}} value={this.props.user.affiliation}
onChange={(value => {
const name = value;
const affiliationOption = Setting.getArrayItem(this.state.affiliationOptions, "name", name);
const id = affiliationOption.id;
this.updateUserField("affiliation", name);
this.updateUserField("score", id);
})}
options={[Setting.getOption(`(${i18next.t("general:empty")})`, "")].concat(this.state.affiliationOptions.map((affiliationOption) => Setting.getOption(affiliationOption.name, affiliationOption.name))
)} />
)
}
</Col>
</Row>
</React.Fragment>
);
}
}
export default AffiliationSelect;
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import {Cascader, Col, Input, Row, Select} from "antd";
import i18next from "i18next";
import * as UserBackend from "../../backend/UserBackend";
import * as Setting from "../../Setting";
class AffiliationSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
addressOptions: [],
affiliationOptions: [],
};
}
componentDidMount() {
this.getAddressOptions(this.props.application);
this.getAffiliationOptions(this.props.application, this.props.user);
}
getAddressOptions(application) {
if (application.affiliationUrl === "") {
return;
}
const addressUrl = application.affiliationUrl.split("|")[0];
UserBackend.getAddressOptions(addressUrl)
.then((addressOptions) => {
this.setState({
addressOptions: addressOptions,
});
});
}
getAffiliationOptions(application, user) {
if (application.affiliationUrl === "") {
return;
}
const affiliationUrl = application.affiliationUrl.split("|")[1];
const code = user.address[user.address.length - 1];
UserBackend.getAffiliationOptions(affiliationUrl, code)
.then((affiliationOptions) => {
this.setState({
affiliationOptions: affiliationOptions,
});
});
}
updateUserField(key, value) {
this.props.onUpdateUserField(key, value);
}
render() {
return (
<React.Fragment>
{
this.props.application?.affiliationUrl === "" ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={this.props.labelSpan}>
{Setting.getLabel(i18next.t("user:Address"), i18next.t("user:Address - Tooltip"))} :
</Col>
<Col span={24 - this.props.labelSpan} >
<Cascader style={{width: "100%", maxWidth: "400px"}} value={this.props.user.address} options={this.state.addressOptions} onChange={value => {
this.updateUserField("address", value);
this.updateUserField("affiliation", "");
this.updateUserField("score", 0);
this.getAffiliationOptions(this.props.application, this.props.user);
}} placeholder={i18next.t("signup:Please input your address!")} />
</Col>
</Row>
)
}
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={this.props.labelSpan}>
{Setting.getLabel(i18next.t("user:Affiliation"), i18next.t("user:Affiliation - Tooltip"))} :
</Col>
<Col span={22} >
{
this.props.application?.affiliationUrl === "" ? (
<Input value={this.props.user.affiliation} onChange={e => {
this.updateUserField("affiliation", e.target.value);
}} />
) : (
<Select virtual={false} style={{width: "100%"}} value={this.props.user.affiliation}
onChange={(value => {
const name = value;
const affiliationOption = Setting.getArrayItem(this.state.affiliationOptions, "name", name);
const id = affiliationOption.id;
this.updateUserField("affiliation", name);
this.updateUserField("score", id);
})}
options={[Setting.getOption(`(${i18next.t("general:empty")})`, "")].concat(this.state.affiliationOptions.map((affiliationOption) => Setting.getOption(affiliationOption.name, affiliationOption.name))
)} />
)
}
</Col>
</Row>
</React.Fragment>
);
}
}
export default AffiliationSelect;

View File

@@ -13,7 +13,7 @@
// limitations under the License.
import {Select} from "antd";
import * as Setting from "../Setting";
import * as Setting from "../../Setting";
import React from "react";
export const CountryCodeSelect = (props) => {

View File

@@ -13,9 +13,9 @@
// limitations under the License.
import React from "react";
import * as Setting from "./Setting";
import * as Setting from "../../Setting";
import {Dropdown} from "antd";
import "./App.less";
import "../../App.less";
import {GlobalOutlined} from "@ant-design/icons";
function flagIcon(country, alt) {
@@ -24,7 +24,7 @@ function flagIcon(country, alt) {
);
}
class SelectLanguageBox extends React.Component {
class LanguageSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
@@ -63,4 +63,4 @@ class SelectLanguageBox extends React.Component {
}
}
export default SelectLanguageBox;
export default LanguageSelect;

View File

@@ -13,12 +13,12 @@
// limitations under the License.
import React from "react";
import * as Setting from "./Setting";
import * as Setting from "../../Setting";
import {Select} from "antd";
const {Option} = Select;
class SelectRegionBox extends React.Component {
class RegionSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
@@ -59,4 +59,4 @@ class SelectRegionBox extends React.Component {
}
}
export default SelectRegionBox;
export default RegionSelect;

View File

@@ -13,9 +13,9 @@
// limitations under the License.
import React from "react";
import * as Setting from "./Setting";
import * as Setting from "../../Setting";
import {Dropdown} from "antd";
import "./App.less";
import "../../App.less";
import i18next from "i18next";
import {CheckOutlined} from "@ant-design/icons";
import {CompactTheme, DarkTheme, Light} from "antd-token-previewer/es/icons";
@@ -34,7 +34,7 @@ function getIcon(themeKey) {
}
}
class SelectThemeBox extends React.Component {
class ThemeSelect extends React.Component {
constructor(props) {
super(props);
}
@@ -91,4 +91,4 @@ class SelectThemeBox extends React.Component {
}
}
export default SelectThemeBox;
export default ThemeSelect;

View File

@@ -1,110 +1,110 @@
{
"account": {
"Logout": "Abmeldung",
"Logout": "Abmelden",
"My Account": "Mein Konto",
"Sign Up": "Anmeldung"
"Sign Up": "Anmelden"
},
"adapter": {
"Duplicated policy rules": "Doppelte Richtlinienregeln",
"Edit Adapter": "Bearbeiten Sie den Adapter",
"Failed to sync policies": "Fehler beim Synchronisieren von Richtlinien",
"Edit Adapter": "Adapter bearbeiten",
"Failed to sync policies": "Fehler beim Synchronisieren der Richtlinien",
"New Adapter": "Neuer Adapter",
"Policies": "Richtlinien",
"Policies - Tooltip": "Casbin-Richtlinienregeln",
"Sync policies successfully": "Synchronisierungspolitiken erfolgreich umgesetzt"
"Policies - Tooltip": "Casbin Richtlinienregeln",
"Sync policies successfully": "Richtlinien synchronisiert"
},
"application": {
"Always": "Immer",
"Auto signin": "Automatische Anmeldung",
"Auto signin - Tooltip": "Wenn eine angemeldete Sitzung in Casdoor vorhanden ist, wird sie automatisch für die Anmeldung auf Anwendungsebene verwendet",
"Background URL": "Hintergrund-URL",
"Background URL - Tooltip": "URL des Hintergrundbildes, das auf der Anmeldeseite verwendet wird",
"Auto signin - Tooltip": "Wenn eine angemeldete Session in Casdoor vorhanden ist, wird diese automatisch für die Anmeldung auf Anwendungsebene verwendet",
"Background URL": "Background-URL",
"Background URL - Tooltip": "URL des Hintergrundbildes, das auf der Anmeldeseite angezeigt wird",
"Center": "Zentrum",
"Copy SAML metadata URL": "Kopieren Sie die SAML-Metadaten-URL",
"Copy prompt page URL": "Kopiere die URL der Prompt-Seite",
"Copy signin page URL": "Kopieren Sie die URL der Anmeldeseite",
"Copy signup page URL": "Kopieren Sie die URL der Anmeldeseite",
"Edit Application": "Bearbeitungsanwendung",
"Copy SAML metadata URL": "SAML-Metadaten-URL kopieren",
"Copy prompt page URL": "URL der Prompt-Seite kopieren",
"Copy signin page URL": "URL der Anmeldeseite kopieren",
"Copy signup page URL": "URL der Anmeldeseite kopieren",
"Edit Application": "Anwendung bearbeiten",
"Enable Email linking": "E-Mail-Verknüpfung aktivieren",
"Enable Email linking - Tooltip": "Bei der Verwendung von 3rd-Party-Anbietern zur Anmeldung wird, wenn es in der Organisation einen Benutzer mit der gleichen E-Mail gibt, automatisch die 3rd-Party-Anmelde-Methode mit diesem Benutzer verbunden",
"Enable SAML compression": "Aktivieren Sie SAML-Komprimierung",
"Enable Email linking - Tooltip": "Bei der Verwendung von Drittanbietern zur Anmeldung wird, wenn es in der Organisation einen Benutzer mit der gleichen E-Mail gibt, automatisch die Drittanbieter-Anmelde-Methode mit diesem Benutzer verbunden",
"Enable SAML compression": "SAML-Komprimierung aktivieren",
"Enable SAML compression - Tooltip": "Ob SAML-Antwortnachrichten komprimiert werden sollen, wenn Casdoor als SAML-IdP verwendet wird",
"Enable WebAuthn signin": "Aktivieren Sie die Anmeldung mit WebAuthn",
"Enable WebAuthn signin": "Anmeldung mit WebAuthn aktivieren",
"Enable WebAuthn signin - Tooltip": "Ob Benutzern erlaubt werden soll, sich mit WebAuthn anzumelden",
"Enable code signin": "Aktivieren Sie die Code-Unterzeichnung",
"Enable code signin - Tooltip": "Ob Benutzern erlaubt werden soll, sich mit einer Telefon- oder E-Mail-Bestätigungscode anzumelden",
"Enable password": "Aktiviere das Passwort",
"Enable code signin": "Code Anmeldung aktivieren",
"Enable code signin - Tooltip": "Ob Benutzern erlaubt werden soll, sich mit einem Telefon- oder E-Mail-Bestätigungscode anzumelden",
"Enable password": "Passwort aktivieren",
"Enable password - Tooltip": "Ob Benutzern erlaubt werden soll, sich mit einem Passwort anzumelden",
"Enable side panel": "Aktiviere die Seitenleiste",
"Enable side panel": "Sidepanel aktivieren",
"Enable signin session - Tooltip": "Ob Casdoor eine Sitzung aufrechterhält, nachdem man sich von der Anwendung aus bei Casdoor angemeldet hat",
"Enable signup": "Aktivieren Sie die Registrierung",
"Enable signup": "Registrierung aktivieren",
"Enable signup - Tooltip": "Ob Benutzern erlaubt werden soll, ein neues Konto zu registrieren",
"Failed to sign in": "Fehler bei der Anmeldung",
"File uploaded successfully": "Datei erfolgreich hochgeladen",
"Follow organization theme": "Folge dem Thema der Organisation",
"Form CSS": "Formular CSS",
"Form CSS - Edit": "Formular CSS - Bearbeiten",
"Form CSS - Tooltip": "CSS-Styling der Anmelde-, Registrierungs- und Passwort-vergessen-Formulare (z. B. Hinzufügen von Rahmen und Schatten)",
"Follow organization theme": "Folge dem Theme der Organisation",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Bearbeiten",
"Form CSS - Tooltip": "CSS-Styling der Anmelde-, Registrierungs- und Passwort-vergessen-Seite (z. B. Hinzufügen von Rahmen und Schatten)",
"Form position": "Formposition",
"Form position - Tooltip": "Ort der Anmelde-, Anmelde- und Passwort vergessen-Formulare",
"Form position - Tooltip": "Position der Anmelde-, Registrierungs- und Passwort-vergessen-Formulare",
"Grant types": "Grant-Typen",
"Grant types - Tooltip": "Wählen Sie aus, welche Förderarten im OAuth-Protokoll zulässig sind",
"Grant types - Tooltip": "Wählen Sie aus, welche Grant-Typen im OAuth-Protokoll zulässig sind",
"Left": "Links",
"Logged in successfully": "Erfolgreich eingeloggt",
"Logged out successfully": "Erfolgreich ausgeloggt",
"New Application": "Neue Anwendung",
"None": "kein",
"Please input your application!": "Bitte geben Sie Ihre Bewerbung ein!",
"None": "kein(e)",
"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",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Die URL der Seite wurde erfolgreich in die Zwischenablage kopiert. Bitte fügen Sie sie in das Inkognito-Fenster oder einen anderen Browser ein",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Die URL der Seite wurde erfolgreich in die Zwischenablage kopiert. Bitte fügen Sie sie in einen Inkognito-Tab oder einen anderen Browser ein",
"Redirect URL": "Weiterleitungs-URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Weiterleitungs-URL (Assertion Consumer Service POST Binding URL)",
"Redirect URLs": "Weiterleitungs-URLs",
"Redirect URLs - Tooltip": "Liste erlaubter Umleitungs-URLs mit Unterstützung von regulärer Ausdrucksprüfung; URLs, die nicht in der Liste enthalten sind, können nicht umgeleitet werden",
"Refresh token expire": "Das Auffrischen des Tokens ist abgelaufen",
"Refresh token expire - Tooltip": "Ablaufzeit des Aktualisierungstokens",
"Refresh token expire": "Gültigkeitsdauer des Refresh-Tokens",
"Refresh token expire - Tooltip": "Angabe der Gültigkeitsdauer des Refresh Tokens",
"Right": "Rechts",
"Rule": "Regel",
"SAML metadata": "SAML-Metadaten",
"SAML metadata - Tooltip": "Die Metadaten des SAML-Protokolls",
"SAML metadata URL copied to clipboard successfully": "SAML-Metadaten URL erfolgreich in die Zwischenablage kopiert",
"SAML reply URL": "SAML Antwort-URL",
"Side panel HTML": "Seitenleisten-HTML",
"Side panel HTML - Edit": "Seitenleisten HTML - Bearbeiten",
"Side panel HTML - Tooltip": "Passen Sie den HTML-Code für das Seitenfeld der Login-Seite an",
"SAML reply URL": "SAML Reply-URL",
"Side panel HTML": "Sidepanel-HTML",
"Side panel HTML - Edit": "Sidepanel HTML - Bearbeiten",
"Side panel HTML - Tooltip": "Passen Sie den HTML-Code für das Sidepanel der Login-Seite an",
"Sign Up Error": "Registrierungsfehler",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Die URL der Anmeldeseite wurde erfolgreich in die Zwischenablage kopiert. Bitte fügen Sie sie in das Inkognito-Fenster oder einen anderen Browser ein",
"Signin session": "Anmeldesitzung",
"Signup items": "Anmeldungsartikel",
"Signup items - Tooltip": "Gegenstände, die Benutzer ausfüllen müssen, wenn sie neue Konten registrieren",
"Signup page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Anmeldeseite-URL erfolgreich in die Zwischenablage kopiert. Bitte fügen Sie sie in das Inkognito-Fenster oder einen anderen Browser ein",
"The application does not allow to sign up new account": "Die Anwendung erlaubt es nicht, ein neues Konto anzumelden",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Die URL der Anmeldeseite wurde in die Zwischenablage kopiert. Bitte fügen Sie sie in einen Inkognito-Tab oder einen anderen Browser ein",
"Signin session": "Anmeldesession",
"Signup items": "Registrierungs Items",
"Signup items - Tooltip": "Items, die Benutzer ausfüllen müssen, wenn sie neue Konten registrieren",
"Signup page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Die URL der Registrierungsseite wurde in die Zwischenablage kopiert. Bitte fügen Sie sie in einen Inkognito-Tab oder einen anderen Browser ein",
"The application does not allow to sign up new account": "Die Anwendung erlaubt es nicht, ein neues Konto zu registrieren",
"Token expire": "Token läuft ab",
"Token expire - Tooltip": "Ablaufzeit des Zugriffstokens",
"Token expire - Tooltip": "Ablaufzeit des Access-Tokens",
"Token format": "Token-Format",
"Token format - Tooltip": "Das Format des Zugriffstokens",
"You are unexpected to see this prompt page": "Du bist unerwartet diese Aufforderungsseite zu sehen"
"Token format - Tooltip": "Das Format des Access-Tokens",
"You are unexpected to see this prompt page": "Sie sind unerwartet auf diese Aufforderungsseite gelangt"
},
"cert": {
"Bit size": "Bitgröße",
"Bit size - Tooltip": "Geheimschlüssellänge",
"Bit size - Tooltip": "Länge des Secret-Keys",
"Certificate": "Zertifikat",
"Certificate - Tooltip": "Öffentliches Schlüsselzertifikat, das zum Entschlüsseln der JWT-Signatur des Access Tokens verwendet wird. Dieses Zertifikat muss normalerweise auf der Casdoor SDK-Seite (d. h. der Anwendung) bereitgestellt werden, um das JWT zu analysieren",
"Certificate copied to clipboard successfully": "Zertifikat erfolgreich in die Zwischenablage kopiert",
"Certificate - Tooltip": "Public-Key-Zertifikat, das zum Entschlüsseln der JWT-Signatur des Access Tokens verwendet wird. Dieses Zertifikat muss normalerweise auf der Casdoor SDK-Seite (d. h. der Anwendung) bereitgestellt werden, um das JWT zu parsen",
"Certificate copied to clipboard successfully": "Zertifikat in die Zwischenablage kopiert",
"Copy certificate": "Kopieren Sie das Zertifikat",
"Copy private key": "Privaten Schlüssel kopieren",
"Copy private key": "Private-Key kopieren",
"Crypto algorithm": "Kryptoalgorithmus",
"Crypto algorithm - Tooltip": "Verschlüsselungsalgorithmus, der vom Zertifikat verwendet wird",
"Download certificate": "Zertifikat herunterladen",
"Download private key": "Privater Schlüssel herunterladen",
"Download private key": "Private-Key herunterladen",
"Edit Cert": "Edit Cert - Zertifikat bearbeiten",
"Expire in years": "Verfallen in Jahren",
"Expire in years": "Ablaufzeit in Jahren",
"Expire in years - Tooltip": "Gültigkeitsdauer des Zertifikats in Jahren",
"New Cert": "Neues Zertifikat",
"Private key": "Privater Schlüssel",
"Private key": "Private-Key",
"Private key - Tooltip": "Privater Schlüssel, der zum öffentlichen Schlüsselzertifikat gehört",
"Private key copied to clipboard successfully": "Privater Schlüssel wurde erfolgreich in die Zwischenablage kopiert",
"Private key copied to clipboard successfully": "Private-Key wurde erfolgreich in die Zwischenablage kopiert",
"Scope - Tooltip": "Nutzungsszenarien des Zertifikats",
"Type - Tooltip": "Art des Zertifikats"
},
@@ -117,7 +117,7 @@
"Please input your phone verification code!": "Bitte geben Sie den Bestätigungscode Ihres Telefons ein!",
"Please input your verification code!": "Bitte geben Sie Ihren Bestätigungscode ein!",
"Send Code": "Code senden",
"Sending": "Senden",
"Sending": "Sendet",
"Submit and complete": "Einreichen und abschließen"
},
"forget": {
@@ -125,7 +125,7 @@
"Change Password": "Passwort ändern",
"Choose email or phone": "Wählen Sie E-Mail oder Telefon",
"Next Step": "Nächster Schritt",
"Please input your username!": "Bitte gib deinen Benutzernamen ein!",
"Please input your username!": "Bitte geben Sie Ihren Benutzernamen ein!",
"Reset": "Zurücksetzen",
"Retrieve password": "Passwort abrufen",
"Unknown forget type": "Unbekannter Vergesslichkeitstyp",
@@ -137,24 +137,24 @@
"Adapter - Tooltip": "Tabellenname des Policy Stores",
"Adapters": "Adapter",
"Add": "Hinzufügen",
"Affiliation URL": "Zugehörigkeits-URL",
"Affiliation URL": "Affiliation-URL",
"Affiliation URL - Tooltip": "Die Homepage-URL für die Zugehörigkeit",
"Application": "Bewerbung",
"Application": "Applikation",
"Applications": "Anwendungen",
"Applications that require authentication": "Anwendungen, die eine Authentifizierung erfordern",
"Avatar": "Avatar",
"Avatar - Tooltip": "Öffentliches Avatarbild für den Benutzer",
"Back Home": "Zurück zu Hause",
"Back Home": "Zurück nach Hause",
"Cancel": "Abbrechen",
"Captcha": "Captcha",
"Cert": "Zertifikat",
"Cert - Tooltip": "Das öffentliche Schlüsselzertifikat, das vom Client-SDK, das mit dieser Anwendung korrespondiert, verifiziert werden muss",
"Cert - Tooltip": "Das Public-Key-Zertifikat, das vom Client-SDK, das mit dieser Anwendung korrespondiert, verifiziert werden muss",
"Certs": "Zertifikate",
"Click to Upload": "Klicken Sie zum Hochladen",
"Client IP": "Kunden-IP",
"Client IP": "Client-IP",
"Close": "Schließen",
"Created time": "Erstellte Zeit",
"Default application": "Standardanwendung",
"Default application": "Standard Anwendung",
"Default application - Tooltip": "Standard-Anwendung für Benutzer, die direkt von der Organisationsseite registriert wurden",
"Default avatar": "Standard-Avatar",
"Default avatar - Tooltip": "Standard-Avatar, der verwendet wird, wenn neu registrierte Benutzer kein Avatar-Bild festlegen",
@@ -167,16 +167,16 @@
"Edit": "Bearbeiten",
"Email": "E-Mail",
"Email - Tooltip": "Gültige E-Mail-Adresse",
"Failed to add": "Konnte nicht hinzufügen",
"Failed to add": "Fehler beim hinzufügen",
"Failed to connect to server": "Die Verbindung zum Server konnte nicht hergestellt werden",
"Failed to delete": "Konnte nicht gelöscht werden",
"Failed to save": "Konnte nicht gespeichert werden",
"Favicon": "Favicon",
"Favicon - Tooltip": "Favicon Icon-URL, die auf allen Casdoor-Seiten der Organisation verwendet wird",
"Favicon - Tooltip": "Favicon-URL, die auf allen Casdoor-Seiten der Organisation verwendet wird",
"First name": "Vorname",
"Forget URL": "Vergessen Sie die URL",
"Forget URL": "Passwort vergessen URL",
"Forget URL - Tooltip": "Benutzerdefinierte URL für die \"Passwort vergessen\" Seite. Wenn nicht festgelegt, wird die standardmäßige Casdoor \"Passwort vergessen\" Seite verwendet. Wenn sie festgelegt ist, wird der \"Passwort vergessen\" Link auf der Login-Seite zu dieser URL umgeleitet",
"Found some texts still not translated? Please help us translate at": "Hast du noch einige Texte gefunden, die nicht übersetzt wurden? Bitte hilf uns beim Übersetzen",
"Found some texts still not translated? Please help us translate at": "Haben Sie noch Texte gefunden, die nicht übersetzt wurden? Bitte helfen Sie uns beim Übersetzen",
"Go to writable demo site?": "Gehe zur beschreibbaren Demo-Website?",
"Home": "Zuhause",
"Home - Tooltip": "Homepage der Anwendung",
@@ -207,22 +207,22 @@
"Organizations": "Organisationen",
"Password": "Passwort",
"Password - Tooltip": "Stellen Sie sicher, dass das Passwort korrekt ist",
"Password salt": "Passworthash",
"Password salt": "Passwort-Salt",
"Password salt - Tooltip": "Zufälliger Parameter, der für die Verschlüsselung von Passwörtern verwendet wird",
"Password type": "Passworttyp",
"Password type - Tooltip": "Speicherformat von Passwörtern in der Datenbank",
"Payments": "Zahlungen",
"Permissions": "Erlaubnisse",
"Permissions": "Rechte",
"Permissions - Tooltip": "Berechtigungen, die diesem Benutzer gehören",
"Phone": "Telefon",
"Phone - Tooltip": "Telefonnummer",
"Preview": "Vorschau",
"Preview - Tooltip": "Vorschau der konfigurierten Effekte",
"Products": "Produkte",
"Provider": "Anbieter",
"Provider - Tooltip": "Zahlungsanbieter müssen konfiguriert werden, einschließlich PayPal, Alipay, WeChat Pay usw.",
"Providers": "Anbieter",
"Providers - Tooltip": "Anbieter müssen konfiguriert werden, einschließlich Anmeldung durch Drittanbieter, Objektspeicherung, Verifizierungscode usw.",
"Provider": "Provider",
"Provider - Tooltip": "Zahlungsprovider, die konfiguriert werden müssen, inkl. PayPal, Alipay, WeChat Pay usw.",
"Providers": "Provider",
"Providers - Tooltip": "Provider, die konfiguriert werden müssen, einschließlich Drittanbieter-Logins, Objektspeicherung, Verifizierungscode usw.",
"Real name": "Echter Name",
"Records": "Datensätze",
"Request URI": "Anforderungs-URI",
@@ -230,9 +230,9 @@
"Roles": "Rollen",
"Roles - Tooltip": "Rollen, denen der Benutzer angehört",
"Save": "Speichern",
"Save & Exit": "Speichern und Beenden",
"Session ID": "Sitzungs-ID",
"Sessions": "Sitzungen",
"Save & Exit": "Speichern und verlassen",
"Session ID": "Session-ID",
"Sessions": "Sessions",
"Signin URL": "Anmeldungs-URL",
"Signin URL - Tooltip": "Benutzerdefinierte URL für die Anmeldeseite. Wenn sie nicht festgelegt ist, wird die standardmäßige Casdoor-Anmeldeseite verwendet. Wenn sie festgelegt ist, leiten die Anmeldelinks auf verschiedenen Casdoor-Seiten zu dieser URL um",
"Signup URL": "Anmelde-URL",
@@ -241,7 +241,7 @@
"Signup application - Tooltip": "Durch welche Anwendung hat sich der Benutzer angemeldet, als er sich registriert hat?",
"Sorry, the page you visited does not exist.": "Entschuldigung, die von Ihnen besuchte Seite existiert nicht.",
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Entschuldigung, der von Ihnen besuchte Benutzer existiert nicht oder Sie sind nicht autorisiert, auf diesen Benutzer zuzugreifen.",
"Sorry, you do not have permission to access this page or logged in status invalid.": "Es tut uns leid, aber Sie haben keine Berechtigung, auf diese Seite zuzugreifen, oder Ihr angemeldeter Status ist ungültig.",
"Sorry, you do not have permission to access this page or logged in status invalid.": "Es tut uns leid, aber Sie haben keine Berechtigung, auf diese Seite zuzugreifen, oder Sie sind nicht angemeldet.",
"State": "Bundesland / Staat",
"State - Tooltip": "Bundesland",
"Successfully added": "Erfolgreich hinzugefügt",
@@ -249,7 +249,7 @@
"Successfully saved": "Erfolgreich gespeichert",
"Supported country codes": "Unterstützte Ländercodes",
"Supported country codes - Tooltip": "Ländercodes, die von der Organisation unterstützt werden. Diese Codes können als Präfix ausgewählt werden, wenn SMS-Verifizierungscodes gesendet werden",
"Sure to delete": "Sicher löschen (or Gesichertes Löschen)",
"Sure to delete": "Sicher zu löschen",
"Swagger": "Swagger",
"Sync": "Synchronisieren",
"Syncers": "Syncers",
@@ -286,7 +286,7 @@
"Enable SSL - Tooltip": "Ob SSL aktiviert werden soll",
"Group ID": "Gruppen-ID",
"Last Sync": "Letzte Synchronisation",
"Server": "Serverh)",
"Server": "Server",
"Server host": "Server Host",
"Server host - Tooltip": "LDAP-Server-Adresse",
"Server name": "Servername",
@@ -298,7 +298,7 @@
},
"login": {
"Auto sign in": "Automatische Anmeldung",
"Continue with": "Mach weiter mit",
"Continue with": "Weitermachen mit",
"Email or phone": "E-Mail oder Telefon",
"Forgot password?": "Passwort vergessen?",
"Loading": "Laden",
@@ -316,30 +316,30 @@
"Signing in...": "Anmelden...",
"Successfully logged in with WebAuthn credentials": "Erfolgreich mit WebAuthn-Anmeldeinformationen angemeldet",
"The input is not valid Email or phone number!": "Die Eingabe ist keine gültige E-Mail-Adresse oder Telefonnummer!",
"To access": "Zu Zugriff",
"To access": "Zum Zugriff",
"Verification code": "Verifizierungscode",
"WebAuthn": "WebAuthn",
"sign up now": "Melde dich jetzt an",
"username, Email or phone": "Benutzername, E-Mail oder Telefon"
},
"model": {
"Edit Model": "Bearbeiten Modell",
"Edit Model": "Modell bearbeiten",
"Model text": "Modelltext",
"Model text - Tooltip": "Casbin Zugriffskontrollmodell inklusive integrierter Modelle wie ACL, RBAC, ABAC, RESTful, usw. Sie können auch benutzerdefinierte Modelle erstellen. Weitere Informationen finden Sie auf der Casbin-Website",
"New Model": "Neues Modell"
},
"organization": {
"Account items": "Kontenpositionen",
"Account items": "Konto Items",
"Account items - Tooltip": "Elemente auf der persönlichen Einstellungsseite",
"Edit Organization": "Organisation bearbeiten",
"Follow global theme": "Folge dem globalen Thema",
"Init score": "Initiale Punktzahl",
"Follow global theme": "Folge dem globalen Theme",
"Init score": "Initialer Score",
"Init score - Tooltip": "Anfangspunkte, die Benutzern bei der Registrierung vergeben werden",
"Is profile public": "Ist das Profil öffentlich?",
"Is profile public - Tooltip": "Nach der Schließung können nur globale Administratoren oder Benutzer in der gleichen Organisation auf die Profilseite des Benutzers zugreifen",
"Modify rule": "Regel ändern",
"New Organization": "Neue Organisation",
"Soft deletion": "Weiche Löschung",
"Soft deletion": "Softe Löschung",
"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",
@@ -353,8 +353,8 @@
"Currency": "Währung",
"Currency - Tooltip": "Wie USD, CNY usw.",
"Download Invoice": "Rechnung herunterladen",
"Edit Payment": "Bearbeiten Sie die Zahlung",
"Individual": "Individuum",
"Edit Payment": "Zahlung bearbeiten",
"Individual": "individuell",
"Invoice URL": "Rechnungs-URL",
"Invoice URL - Tooltip": "URL für den Download der Rechnung",
"Invoice actions": "Rechnungsaktionen",
@@ -382,16 +382,16 @@
"Please carefully check your invoice information. Once the invoice is issued, it cannot be withdrawn or modified.": "Bitte prüfen Sie sorgfältig Ihre Rechnungsinformationen. Sobald die Rechnung ausgestellt wurde, kann sie nicht zurückgenommen oder geändert werden.",
"Please click the below button to return to the original website": "Bitte klicken Sie auf den unten stehenden Button, um zur ursprünglichen Website zurückzukehren",
"Please pay the order first!": "Bitte zahlen Sie zuerst die Bestellung!",
"Processing...": "Verarbeitung...",
"Processing...": "In Bearbeitung...",
"Product": "Produkt",
"Product - Tooltip": "Produktname",
"Result": "Ergebnis",
"Return to Website": "Zurück zur Website",
"The payment has failed": "Die Zahlung ist fehlgeschlagen",
"The payment is still under processing": "Die Zahlung wird immer noch bearbeitet",
"Type - Tooltip": "Zahlungsmethode, die beim Kauf des Produkts verwendet wird",
"Type - Tooltip": "Zahlungsmethode, die beim Kauf des Produkts verwendet wurde",
"You have successfully completed the payment": "Sie haben die Zahlung erfolgreich abgeschlossen",
"please wait for a few seconds...": "Bitte warten Sie einige Sekunden...",
"please wait for a few seconds...": "Bitte warten Sie ein paar Sekunden...",
"the current state is": "der aktuelle Zustand ist"
},
"permission": {
@@ -399,17 +399,17 @@
"Actions - Tooltip": "Erlaubte Aktionen",
"Admin": "Admin",
"Allow": "erlauben",
"Approve time": "Zeit genehmigen",
"Approve time": "Zeit der Genehmigung",
"Approve time - Tooltip": "Die Genehmigungszeit für diese Erlaubnis",
"Approved": "Genehmigt",
"Approver": "Genehmiger",
"Approver - Tooltip": "Die Person, die die Genehmigung genehmigt hat",
"Deny": "Leugnen",
"Edit Permission": "Bearbeitungsberechtigung",
"Effect": "Wirkung",
"Effect - Tooltip": "erlauben oder ablehnen",
"Deny": "Ablehnen",
"Edit Permission": "Recht bearbeiten",
"Effect": "Effekt",
"Effect - Tooltip": "Erlauben oder ablehnen",
"New Permission": "Neue Genehmigung",
"Pending": "In Erwartung",
"Pending": "Ausstehend",
"Read": "Lesen",
"Resource type": "Ressourcentyp",
"Resource type - Tooltip": "Art der Ressource",
@@ -433,8 +433,8 @@
"New Product": "Neues Produkt",
"Pay": "Zahlen",
"PayPal": "PayPal",
"Payment providers": "Zahlungsanbieter",
"Payment providers - Tooltip": "Anbieter von Zahlungsdiensten",
"Payment providers": "Zahlungsprovider",
"Payment providers - Tooltip": "Provider von Zahlungsdiensten",
"Placing order...": "Bestellung aufgeben...",
"Please provide your username in the remark": "Bitte geben Sie Ihren Benutzernamen in der Anmerkung an",
"Please scan the QR code to pay": "Bitte scannen Sie den QR-Code, um zu bezahlen",
@@ -442,7 +442,7 @@
"Price - Tooltip": "Preis des Produkts",
"Quantity": "Menge",
"Quantity - Tooltip": "Menge des Produkts",
"Return URL": "Rückgabe-URL",
"Return URL": "Rückkeht-URL",
"Return URL - Tooltip": "URL für die Rückkehr nach einem erfolgreichen Kauf",
"SKU": "SKU",
"Sold": "Verkauft",
@@ -450,79 +450,79 @@
"Tag - Tooltip": "Tag des Produkts",
"Test buy page..": "Testkaufseite.",
"There is no payment channel for this product.": "Es gibt keinen Zahlungskanal für dieses Produkt.",
"This product is currently not in sale.": "Dieses Produkt ist derzeit nicht im Verkauf.",
"This product is currently not in sale.": "Dieses Produkt steht derzeit nicht zum Verkauf.",
"USD": "USD",
"WeChat Pay": "WeChat Pay"
},
"provider": {
"Access key": "Zugriffsschlüssel",
"Access key": "Access-Key",
"Access key - Tooltip": "Zugriffsschlüssel",
"Agent ID": "Agenten-ID",
"Agent ID - Tooltip": "Agenten-ID",
"App ID": "App ID",
"App ID - Tooltip": "App-ID",
"App key": "App-Schlüssel",
"App key": "App-Key",
"App key - Tooltip": "App-Schlüssel",
"App secret": "App-Geheimnis",
"App secret": "App-Secret",
"AppSecret - Tooltip": "App-Geheimnis",
"Auth URL": "Auth-URL",
"Auth URL - Tooltip": "Auth-URL",
"Bucket": "Eimer",
"Bucket - Tooltip": "Name des Eimers",
"Bucket": "Bucket",
"Bucket - Tooltip": "Name des Buckets",
"Can not parse metadata": "Kann Metadaten nicht durchsuchen / auswerten",
"Can signin": "Einloggen möglich",
"Can signup": "Kann registrieren",
"Can unlink": "Entkoppeln möglich",
"Can signin": "Kann sich einloggen",
"Can signup": "Kann sich registrieren",
"Can unlink": "Entlinken möglich",
"Category": "Kategorie",
"Category - Tooltip": "Wählen Sie eine Kategorie aus",
"Channel No.": "Kanal Nr.",
"Channel No. - Tooltip": "Kanalnummer.",
"Client ID": "Kunden-ID",
"Client ID - Tooltip": "Kundennummer",
"Client ID 2": "Kunden-ID 2",
"Client ID 2 - Tooltip": "Die zweite Kundennnummer (ID)",
"Client secret": "Kunden-Geheimnis",
"Client secret - Tooltip": "Kunden-Geheimnis",
"Client secret 2": "Kunden-Geheimnis 2",
"Client secret 2 - Tooltip": "Der zweite Geheimcode für den Kunden",
"Client ID": "Client-ID",
"Client ID - Tooltip": "Client-ID",
"Client ID 2": "Client-ID 2",
"Client ID 2 - Tooltip": "Die zweite Client-ID",
"Client secret": "Client-Secret",
"Client secret - Tooltip": "Client-Geheimnis",
"Client secret 2": "Client-Secret 2",
"Client secret 2 - Tooltip": "Der zweite Client-Secret-Key",
"Copy": "Kopieren",
"Disable SSL": "SSL deaktivieren",
"Disable SSL - Tooltip": "Ob die Deaktivierung des SSL-Protokolls bei der Kommunikation mit dem STMP-Server erfolgen soll",
"Domain": "Domain",
"Domain - Tooltip": "Benutzerdefinierte Domäne für Objektspeicher",
"Edit Provider": "Anbieter bearbeiten",
"Domain - Tooltip": "Benutzerdefinierte Domain für Objektspeicher",
"Edit Provider": "Provider bearbeiten",
"Email content": "Email-Inhalt",
"Email content - Tooltip": "Inhalt der E-Mail",
"Email sent successfully": "E-Mail erfolgreich gesendet",
"Email title": "Email-Titel",
"Email title - Tooltip": "Betreff der E-Mail",
"Enable QR code": "QR-Code aktivieren",
"Enable QR code - Tooltip": "Ob Scannen von QR-Code zum Einloggen erlaubt werden soll",
"Endpoint": "Endpunkt",
"Endpoint (Intranet)": "Endpunkt (Intranet)",
"Enable QR code - Tooltip": "Ob das Scannen von QR-Codes zum Einloggen aktiviert werden soll",
"Endpoint": "Endpoint",
"Endpoint (Intranet)": "Endpoint (Intranet)",
"Host": "Host",
"Host - Tooltip": "Name des Gastgebers",
"Host - Tooltip": "Name des Hosts",
"IdP": "IdP",
"IdP certificate": "IdP-Zertifikat",
"Issuer URL": "Emittenten-URL",
"Issuer URL": "Issuer-URL",
"Issuer URL - Tooltip": "Emittenten-URL",
"Link copied to clipboard successfully": "Link wurde erfolgreich in die Zwischenablage kopiert",
"Metadata": "Metadaten",
"Metadata - Tooltip": "SAML-Metadaten",
"Method - Tooltip": "Anmeldeverfahren, QR-Code oder geräuschloser Login",
"New Provider": "Neuer Anbieter",
"Method - Tooltip": "Anmeldeverfahren, QR-Code oder Silent-Login",
"New Provider": "Neuer Provider",
"Parse": "parsen",
"Parse metadata successfully": "Metadaten erfolgreich analysiert",
"Path prefix": "Pfadpräfix",
"Path prefix - Tooltip": "Bucket-Pfad-Präfix für Objektspeicher",
"Please use WeChat and scan the QR code to sign in": "Bitte verwende WeChat und scanne den QR-Code ein, um dich anzumelden",
"Port": "Hafen",
"Please use WeChat and scan the QR code to sign in": "Bitte verwenden Sie WeChat und scanne den QR-Code ein, um dich anzumelden",
"Port": "Port",
"Port - Tooltip": "Stellen Sie sicher, dass der Port offen ist",
"Prompted": "ausgelöst",
"Provider URL": "Anbieter-URL",
"Provider URL": "Provider-URL",
"Provider URL - Tooltip": "URL zur Konfiguration des Dienstanbieters, dieses Feld dient nur als Referenz und wird in Casdoor nicht verwendet",
"Region ID": "Regions-ID",
"Region ID - Tooltip": "Regionale ID für den Dienstleister",
"Region ID - Tooltip": "Regions-ID für den Dienstleister",
"Region endpoint for Internet": "Regionsendpunkt für das Internet",
"Region endpoint for Intranet": "Regionales Endpunkt für Intranet",
"Required": "Benötigt",
@@ -535,32 +535,32 @@
"SP ACS URL": "SP ACS URL",
"SP ACS URL - Tooltip": "SP ACS URL",
"SP Entity ID": "SP-Entitäts-ID",
"Scene": "Szene",
"Scene": "Scene",
"Scene - Tooltip": "Szene",
"Scope": "Umfang",
"Scope - Tooltip": "Umfang",
"Secret access key": "Geheimer Zugriffsschlüssel",
"Scope": "Scope",
"Scope - Tooltip": "Scope",
"Secret access key": "Secret-Access-Key",
"Secret access key - Tooltip": "Geheimer Zugriffsschlüssel",
"Secret key": "Geheimschlüssel",
"Secret key - Tooltip": "Vom Server verwendet, um die API des Verifizierungscodes-Anbieters für die Verifizierung aufzurufen",
"Secret key": "Secret-Key",
"Secret key - Tooltip": "Vom Server verwendet, um die API des Verifizierungscodes-Providers für die Verifizierung aufzurufen",
"Send Testing Email": "Senden Sie eine Test-E-Mail",
"Send Testing SMS": "Sende Test-SMS",
"Sign Name": "Unterschreiben Sie den Namen",
"Sign Name": "Signatur Namen",
"Sign Name - Tooltip": "Name der Signatur, die verwendet werden soll",
"Sign request": "Unterschriftsanforderung",
"Sign request - Tooltip": "Ob die Anfrage eine Unterschrift erfordert",
"Signin HTML": "Anmeldung HTML",
"Signin HTML - Edit": "Anmeldung HTML - Bearbeiten",
"Sign request": "Signaturanfrage",
"Sign request - Tooltip": "Ob die Anfrage eine Signatur erfordert",
"Signin HTML": "Anmeldungs-HTML",
"Signin HTML - Edit": "Anmeldungs-HTML - Bearbeiten",
"Signin HTML - Tooltip": "Benutzerdefiniertes HTML zur Ersetzung des Standard-Anmelde-Seitenstils",
"Signup HTML": "Anmeldung HTML",
"Signup HTML": "Registrierungs-HTML",
"Signup HTML - Edit": "Registrierung HTML - Bearbeiten",
"Signup HTML - Tooltip": "Benutzerdefiniertes HTML zur Ersetzung des Standard-Anmelde-Seitenstils",
"Site key": "Seitenschlüssel",
"Site key - Tooltip": "Site-Schlüssel",
"Signup HTML - Tooltip": "Benutzerdefiniertes HTML zur Ersetzung des Standard-Registrierungs-Seitenstils",
"Site key": "Site-Key",
"Site key - Tooltip": "Seitenschlüssel",
"Sub type": "Untertyp",
"Sub type - Tooltip": "Unterart",
"Template code": "Vorlagen-Code",
"Template code - Tooltip": "Vorlagen-Code",
"Template code": "Template-Code",
"Template code - Tooltip": "Template-Code",
"Test Email": "Test E-Mail",
"Test Email - Tooltip": "E-Mail-Adresse zum Empfangen von Test-E-Mails",
"Test SMTP Connection": "Testen Sie die SMTP-Verbindung",
@@ -570,23 +570,23 @@
"Type - Tooltip": "Wählen Sie einen Typ aus",
"UserInfo URL": "UserInfo-URL",
"UserInfo URL - Tooltip": "UserInfo-URL",
"admin (Shared)": "admin (Gemeinsam)"
"admin (Shared)": "admin (Shared)"
},
"record": {
"Is triggered": "Wird ausgelöst"
"Is triggered": "Ist ausgelöst"
},
"resource": {
"Copy Link": "Kopiere den Link",
"Copy Link": "Link kopieren",
"File name": "Dateiname",
"File size": "Dateigröße",
"Format": "Format",
"Parent": "Elternteil",
"Parent": "Parent",
"Upload a file...": "Hochladen einer Datei..."
},
"role": {
"Edit Role": "Rolle bearbeiten",
"New Role": "Neue Rolle",
"Sub domains": "Unterdomänen",
"Sub domains": "Subdomains",
"Sub domains - Tooltip": "In der aktuellen Rolle enthaltene Domains",
"Sub roles": "Unterrollen",
"Sub roles - Tooltip": "Rollen, die in der aktuellen Rolle enthalten sind",
@@ -597,11 +597,11 @@
"Accept": "Akzeptieren",
"Agreement": "Vereinbarung",
"Confirm": "Bestätigen",
"Decline": "Abnahme",
"Decline": "Ablehnen",
"Have account?": "Haben Sie ein Konto?",
"Please accept the agreement!": "Bitte akzeptieren Sie die Vereinbarung!",
"Please click the below button to sign in": "Bitte klicken Sie auf die untenstehende Schaltfläche, um sich anzumelden",
"Please confirm your password!": "Bitte bestätige dein Passwort!",
"Please click the below button to sign in": "Bitte klicken Sie auf den untenstehenden Button, um sich anzumelden",
"Please confirm your password!": "Bitte bestätigen Sie Ihr Passwort!",
"Please input the correct ID card number!": "Bitte geben Sie die korrekte Ausweisnummer ein!",
"Please input your Email!": "Bitte geben Sie Ihre E-Mail-Adresse ein!",
"Please input your ID card number!": "Bitte geben Sie Ihre Personalausweisnummer ein!",
@@ -637,17 +637,17 @@
"Database - Tooltip": "Der ursprüngliche Datenbankname",
"Database type": "Datenbanktyp",
"Database type - Tooltip": "Datenbanktyp, der alle Datenbanken unterstützt, die von XORM unterstützt werden, wie MySQL, PostgreSQL, SQL Server, Oracle, SQLite, usw.",
"Edit Syncer": "Edit Syncer",
"Edit Syncer": "Syncer bearbeiten",
"Error text": "Fehlermeldung",
"Error text - Tooltip": "Fehler Text",
"Is hashed": "wurde gehasht",
"Is hashed": "ist gehasht",
"New Syncer": "Neuer Syncer",
"Sync interval": "Synchronisierungsintervall",
"Sync interval - Tooltip": "Einheit in Sekunden",
"Table": "Tabelle",
"Table - Tooltip": "Name der Datenbanktabelle",
"Table columns": "Tabellenspalten",
"Table columns - Tooltip": "zu Deutsch: Spalten in der Tabelle, die an der Datensynchronisierung beteiligt sind. Spalten, die nicht an der Synchronisierung beteiligt sind, müssen nicht hinzugefügt werden",
"Table columns - Tooltip": "Spalten in der Tabelle, die an der Datensynchronisierung beteiligt sind. Spalten, die nicht an der Synchronisierung beteiligt sind, müssen nicht hinzugefügt werden",
"Table primary key": "Primärschlüssel der Tabelle",
"Table primary key - Tooltip": "Primärschlüssel in einer Tabelle, wie beispielsweise eine ID"
},
@@ -655,7 +655,7 @@
"About Casdoor": "Über Casdoor",
"An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "Eine Identitäts- und Zugriffsverwaltung (IAM) / Single-Sign-On (SSO) Plattform mit Web-UI, die OAuth 2.0, OIDC, SAML und CAS unterstützt",
"CPU Usage": "CPU-Auslastung",
"Community": "Gemeinschaft",
"Community": "Community",
"Failed to get CPU usage": "Konnte CPU-Auslastung nicht abrufen",
"Failed to get memory usage": "Fehler beim Abrufen der Speichernutzung",
"Memory Usage": "Speichernutzung",
@@ -664,29 +664,29 @@
"Version": "Version"
},
"theme": {
"Blossom": "Blüte",
"Border radius": "Eckradius",
"Compact": "Kompakt",
"Customize theme": "Anpassen des Themas",
"Dark": "Dunkelheit",
"Default": "Voreinstellung",
"Blossom": "Blossom",
"Border radius": "Border Radius",
"Compact": "Compact",
"Customize theme": "Anpassen des Themes",
"Dark": "Dunkel",
"Default": "Standardeinstellungen",
"Document": "Dokument",
"Is compact": "Ist kompakt",
"Primary color": "Primärfarbe",
"Theme": "Thema",
"Theme - Tooltip": "Stilthema der Anwendung"
"Theme": "Theme",
"Theme - Tooltip": "Stiltheme der Anwendung"
},
"token": {
"Access token": "Zugriffstoken",
"Access token": "Access-Token",
"Authorization code": "Authorisierungscode",
"Edit Token": "Edit-Token bearbeiten",
"Edit Token": "Token bearbeiten",
"Expires in": "läuft ab in",
"New Token": "Neues Token",
"New Token": "Neuer Token",
"Token type": "Token-Typ"
},
"user": {
"3rd-party logins": "3rd-Party-Logins",
"3rd-party logins - Tooltip": "Soziale Anmeldungen, die vom Benutzer verknüpft werden",
"3rd-party logins": "Drittanbieter-Logins",
"3rd-party logins - Tooltip": "Drittanbieter-Anmeldungen, die mit dem Benutzer verknüpft sind",
"Address": "Adresse",
"Address - Tooltip": "Wohnadresse",
"Affiliation": "Zugehörigkeit",
@@ -700,22 +700,22 @@
"Country/Region - Tooltip": "Land oder Region",
"Edit User": "Benutzer bearbeiten",
"Email cannot be empty": "E-Mail darf nicht leer sein",
"Email/phone reset successfully": "E-Mail-/Telefonrücksetzung erfolgreich durchgeführt",
"Empty input!": "Leereingabe!",
"Email/phone reset successfully": "E-Mail-/Telefon-Zurücksetzung erfolgreich durchgeführt",
"Empty input!": "Leere Eingabe!",
"Homepage": "Startseite des Benutzers",
"Homepage - Tooltip": "Homepage-URL des Benutzers",
"ID card": "Ausweis",
"Input your email": "Gib deine E-Mail-Adresse ein",
"Input your email": "Geben Sie Ihre E-Mail-Adresse ein",
"Input your phone number": "Geben Sie Ihre Telefonnummer ein",
"Is admin": "Ist Admin",
"Is admin - Tooltip": "Ist ein Administrator der Organisation, zu der der Benutzer gehört",
"Is deleted": "wurde gelöscht",
"Is deleted": "ist gelöscht",
"Is deleted - Tooltip": "\"Gelöschte Benutzer behalten nur Datenbankdatensätze und können keine Operationen ausführen.\"",
"Is forbidden": "Ist verboten",
"Is forbidden - Tooltip": "Verbotene Benutzer können sich nicht mehr einloggen",
"Is global admin": "Ist weltweiter Administrator",
"Is global admin": "Ist globaler Administrator",
"Is global admin - Tooltip": "Ist ein Administrator von Casdoor",
"Keys": "Schlüssel",
"Keys": "Keys",
"Link": "Link",
"Location": "Ort",
"Location - Tooltip": "Stadt des Wohnsitzes",
@@ -724,22 +724,22 @@
"New Email": "Neue E-Mail",
"New Password": "Neues Passwort",
"New User": "Neuer Benutzer",
"New phone": "Neues Telefon",
"New phone": "Neue Telefonnummer",
"Old Password": "Altes Passwort",
"Password set successfully": "Passwort erfolgreich festgelegt",
"Phone cannot be empty": "Telefon kann nicht leer sein",
"Phone cannot be empty": "Telefonnummer kann nicht leer sein",
"Please select avatar from resources": "Bitte wählen Sie einen Avatar aus den Ressourcen aus",
"Properties": "Eigenschaften",
"Properties - Tooltip": "Eigenschaften des Benutzers",
"Re-enter New": "Neueingabe betreten",
"Reset Email...": "Reset E-Mail...",
"Re-enter New": "Neueingabe wiederholen",
"Reset Email...": "E-Mail zurücksetzen...",
"Reset Phone...": "Telefon zurücksetzen...",
"Select a photo...": "Wählen Sie ein Foto aus...",
"Set Password": "Passwort festlegen",
"Set new profile picture": "Neues Profilbild festlegen",
"Set password...": "Passwort festlegen...",
"Tag": "Tag",
"Tag - Tooltip": "Tag des Benutzers",
"Tag - Tooltip": "Tags des Benutzers",
"Title": "Titel",
"Title - Tooltip": "Position in der Zugehörigkeit",
"Two passwords you typed do not match.": "Zwei von Ihnen eingegebene Passwörter stimmen nicht überein.",
@@ -749,10 +749,10 @@
"Values": "Werte",
"Verification code sent": "Bestätigungscode gesendet",
"WebAuthn credentials": "WebAuthn-Anmeldeinformationen",
"input password": "Eingabe des Passworts"
"input password": "Passwort eingeben"
},
"webhook": {
"Content type": "Inhaltstyp",
"Content type": "Content-Type",
"Content type - Tooltip": "Inhaltstyp",
"Edit Webhook": "Webhook bearbeiten",
"Events": "Ereignisse",
@@ -760,9 +760,9 @@
"Headers": "Überschriften",
"Headers - Tooltip": "HTTP-Header (Schlüssel-Wert-Paare)",
"Is user extended": "Wurde der Benutzer erweitert?",
"Is user extended - Tooltip": "Sollten die erweiterten Felder des Benutzers in das JSON eingeschlossen werden?",
"Is user extended - Tooltip": "Sollten die erweiterten Felder des Benutzers in das JSON inkludiert werden?",
"Method - Tooltip": "HTTP Methode",
"New Webhook": "Neuer Webhook",
"New Webhook": "Neue Webhook",
"Value": "Wert"
}
}

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "Whether to allow users to register a new account",
"Failed to sign in": "Failed to sign in",
"File uploaded successfully": "File uploaded successfully",
"First, last": "First, last",
"Follow organization theme": "Follow organization theme",
"Form CSS": "Form CSS",
"Form CSS - Edit": "Form CSS - Edit",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "Location of the signup, signin and forget password forms",
"Grant types": "Grant types",
"Grant types - Tooltip": "Select which grant types are allowed in the OAuth protocol",
"Incremental": "Incremental",
"Left": "Left",
"Logged in successfully": "Logged in successfully",
"Logged out successfully": "Logged out successfully",
"New Application": "New Application",
"No verification": "No verification",
"None": "None",
"Normal": "Normal",
"Only signup": "Only signup",
"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",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "Redirect URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Redirect URL (Assertion Consumer Service POST Binding URL)",
"Redirect URLs": "Redirect URLs",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "Side panel HTML - Edit",
"Side panel HTML - Tooltip": "Customize the HTML code for the side panel of the login page",
"Sign Up Error": "Sign Up Error",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
"Signin session": "Signin session",
"Signup items": "Signup items",
@@ -504,6 +513,8 @@
"Host - Tooltip": "Name of host",
"IdP": "IdP",
"IdP certificate": "IdP certificate",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "Issuer URL",
"Issuer URL - Tooltip": "Issuer URL",
"Link copied to clipboard successfully": "Link copied to clipboard successfully",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "SAML metadata",
"Method - Tooltip": "Login method, QR code or silent login",
"New Provider": "New Provider",
"Normal": "Normal",
"Parse": "Parse",
"Parse metadata successfully": "Parse metadata successfully",
"Path prefix": "Path prefix",
@@ -555,8 +567,10 @@
"Signup HTML": "Signup HTML",
"Signup HTML - Edit": "Signup HTML - Edit",
"Signup HTML - Tooltip": "Custom HTML for replacing the default signup page style",
"Silent": "Silent",
"Site key": "Site key",
"Site key - Tooltip": "Site key",
"Sliding Validation": "Sliding Validation",
"Sub type": "Sub type",
"Sub type - Tooltip": "Sub type",
"Template code": "Template code",
@@ -564,6 +578,7 @@
"Test Email": "Test Email",
"Test Email - Tooltip": "Email address to receive test mails",
"Test SMTP Connection": "Test SMTP Connection",
"Third-party": "Third-party",
"Token URL": "Token URL",
"Token URL - Tooltip": "Token URL",
"Type": "Type",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "The input is not valid Email!",
"The input is not valid Phone!": "The input is not valid Phone!",
"Username": "Username",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Your account has been created!",
"Your confirmed password is inconsistent with the password!": "Your confirmed password is inconsistent with the password!",
"sign in now": "sign in now"

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "Ya sea permitir que los usuarios registren una nueva cuenta",
"Failed to sign in": "Error al iniciar sesión",
"File uploaded successfully": "Archivo subido exitosamente",
"First, last": "First, last",
"Follow organization theme": "Seguir el tema de la organización",
"Form CSS": "Formulario CSS",
"Form CSS - Edit": "Formulario CSS - Editar",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "Ubicación de los formularios de registro, inicio de sesión y olvido de contraseña",
"Grant types": "Tipos de subvenciones",
"Grant types - Tooltip": "Selecciona cuáles tipos de subvenciones están permitidas en el protocolo OAuth",
"Incremental": "Incremental",
"Left": "Izquierda",
"Logged in successfully": "Acceso satisfactorio",
"Logged out successfully": "Cerró sesión exitosamente",
"New Application": "Nueva aplicación",
"No verification": "No verification",
"None": "Ninguno",
"Normal": "Normal",
"Only signup": "Only signup",
"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",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL de la página de acceso exitosamente copiada al portapapeles, por favor péguela en la ventana de incógnito o en otro navegador",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "Redireccionar URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redireccionamiento (URL de enlace de publicación del servicio consumidor de afirmaciones)",
"Redirect URLs": "Redireccionar URLs",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "Panel lateral HTML - Editar",
"Side panel HTML - Tooltip": "Personaliza el código HTML del panel lateral de la página de inicio de sesión",
"Sign Up Error": "Error de registro",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "La URL de la página de inicio de sesión fue copiada al portapapeles exitosamente, por favor péguela en una ventana de incógnito o en otro navegador",
"Signin session": "Sesión de inicio de sesión",
"Signup items": "Artículos de registro",
@@ -504,6 +513,8 @@
"Host - Tooltip": "Nombre del anfitrión",
"IdP": "IdP = Proveedor de Identidad",
"IdP certificate": "Certificado de proveedor de identidad (IdP)",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "URL del emisor",
"Issuer URL - Tooltip": "URL del emisor",
"Link copied to clipboard successfully": "Enlace copiado al portapapeles satisfactoriamente",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "Metadatos SAML",
"Method - Tooltip": "Método de inicio de sesión, código QR o inicio de sesión silencioso",
"New Provider": "Nuevo proveedor",
"Normal": "Normal",
"Parse": "Analizar",
"Parse metadata successfully": "Analizar los metadatos con éxito",
"Path prefix": "Prefijo de ruta",
@@ -555,8 +567,10 @@
"Signup HTML": "Registro HTML",
"Signup HTML - Edit": "Registro HTML - Editar",
"Signup HTML - Tooltip": "HTML personalizado para reemplazar el estilo predeterminado de la página de registro",
"Silent": "Silent",
"Site key": "Clave del sitio",
"Site key - Tooltip": "Clave del sitio",
"Sliding Validation": "Sliding Validation",
"Sub type": "Subtipo",
"Sub type - Tooltip": "Subtipo",
"Template code": "Código de plantilla",
@@ -564,6 +578,7 @@
"Test Email": "Correo de prueba",
"Test Email - Tooltip": "Dirección de correo electrónico para recibir mensajes de prueba",
"Test SMTP Connection": "Prueba de conexión SMTP",
"Third-party": "Third-party",
"Token URL": "Token URL",
"Token URL - Tooltip": "URL de token",
"Type": "Tipo",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "¡La entrada no es un correo electrónico válido!",
"The input is not valid Phone!": "¡La entrada no es un número de teléfono válido!",
"Username": "Nombre de usuario",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "¡Su cuenta ha sido creada!",
"Your confirmed password is inconsistent with the password!": "¡Su contraseña confirmada no es coherente con la contraseña!",
"sign in now": "Inicie sesión ahora"

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "Doit-on autoriser les utilisateurs à créer un nouveau compte ?",
"Failed to sign in": "Échec de la connexion",
"File uploaded successfully": "Fichier téléchargé avec succès",
"First, last": "First, last",
"Follow organization theme": "Suivre le thème de l'organisation",
"Form CSS": "Formulaire CSS",
"Form CSS - Edit": "Form CSS - Modifier",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "Emplacement des formulaires d'inscription, de connexion et de récupération de mot de passe",
"Grant types": "Types de subventions",
"Grant types - Tooltip": "Sélectionnez les types d'autorisations autorisés dans le protocole OAuth",
"Incremental": "Incremental",
"Left": "gauche",
"Logged in successfully": "Connecté avec succès",
"Logged out successfully": "Déconnecté avec succès",
"New Application": "Nouvelle application",
"No verification": "No verification",
"None": "Aucun",
"Normal": "Normal",
"Only signup": "Only signup",
"Please input your application!": "Veuillez saisir votre demande d'application !",
"Please input your organization!": "S'il vous plaît saisir votre organisation !",
"Please select a HTML file": "S'il vous plaît sélectionnez un fichier HTML",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL de la page rapide copiée avec succès dans le presse-papiers, veuillez la coller dans la fenêtre de navigation privée ou dans un autre navigateur",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "Rediriger l'URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL de redirection (URL de liaison POST du service consommateur d'assertions)",
"Redirect URLs": "Rediriger les URL",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "Panneau latéral HTML - Modifier",
"Side panel HTML - Tooltip": "Personnalisez le code HTML du panneau latéral de la page de connexion",
"Sign Up Error": "Erreur d'inscription",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "L'URL de la page de connexion a été copiée avec succès dans le presse-papiers, veuillez la coller dans la fenêtre de navigation privée ou dans un autre navigateur",
"Signin session": "Session de connexion",
"Signup items": "Les éléments d'inscription",
@@ -504,6 +513,8 @@
"Host - Tooltip": "Nom d'hôte",
"IdP": "IdP",
"IdP certificate": "Certificat IdP",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "URL de l'émetteur",
"Issuer URL - Tooltip": "URL de l'émetteur",
"Link copied to clipboard successfully": "Lien copié avec succès dans le presse-papiers",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "Métadonnées SAML",
"Method - Tooltip": "Méthode de connexion, code QR ou connexion silencieuse",
"New Provider": "Nouveau fournisseur",
"Normal": "Normal",
"Parse": "Parser",
"Parse metadata successfully": "Parcourir les métadonnées avec succès",
"Path prefix": "Préfixe de chemin",
@@ -555,8 +567,10 @@
"Signup HTML": "Inscription HTML",
"Signup HTML - Edit": "Inscription HTML - éditer",
"Signup HTML - Tooltip": "HTML personnalisé pour remplacer le style par défaut de la page d'inscription",
"Silent": "Silent",
"Site key": "Clé de site",
"Site key - Tooltip": "Clé de site",
"Sliding Validation": "Sliding Validation",
"Sub type": "Sous-type",
"Sub type - Tooltip": "Sous-type",
"Template code": "Code modèle",
@@ -564,6 +578,7 @@
"Test Email": "Courriel de test",
"Test Email - Tooltip": "Adresse e-mail pour recevoir des courriels de test",
"Test SMTP Connection": "Test de connexion SMTP",
"Third-party": "Third-party",
"Token URL": "URL de jeton",
"Token URL - Tooltip": "URL de jeton",
"Type": "Type",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "L'entrée n'est pas un e-mail valide !",
"The input is not valid Phone!": "L'entrée n'est pas un numéro de téléphone valide !",
"Username": "Nom d'utilisateur",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Votre compte a été créé !",
"Your confirmed password is inconsistent with the password!": "Votre mot de passe confirmé est incompatible avec le mot de passe !",
"sign in now": "Connectez-vous maintenant"

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "Apakah akan mengizinkan pengguna untuk mendaftar akun baru",
"Failed to sign in": "Gagal masuk",
"File uploaded successfully": "Berkas telah diunggah dengan sukses",
"First, last": "First, last",
"Follow organization theme": "Ikuti tema organisasi",
"Form CSS": "Formulir CSS",
"Form CSS - Edit": "Formulir CSS - Edit",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "Tempat pendaftaran, masuk, dan lupa kata sandi",
"Grant types": "Jenis-jenis hibah",
"Grant types - Tooltip": "Pilih jenis hibah apa yang diperbolehkan dalam protokol OAuth",
"Incremental": "Incremental",
"Left": "Kiri",
"Logged in successfully": "Berhasil masuk",
"Logged out successfully": "Berhasil keluar dari sistem",
"New Application": "Aplikasi Baru",
"No verification": "No verification",
"None": "Tidak ada",
"Normal": "Normal",
"Only signup": "Only signup",
"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",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Tautan halaman Prompt berhasil disalin ke papan klip, silakan tempelkan ke jendela penyamaran atau browser lainnya",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "Mengalihkan URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "URL pengalihan (Penyanggah Konsumen Layanan Ikatan POST URL)",
"Redirect URLs": "Mengarahkan URL",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "Panel sisi HTML - Sunting",
"Side panel HTML - Tooltip": "Menyesuaikan kode HTML untuk panel samping halaman login",
"Sign Up Error": "Kesalahan Pendaftaran",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL halaman masuk berhasil disalin ke clipboard, silakan tempelkan di jendela penyamaran atau browser lainnya",
"Signin session": "Sesi masuk",
"Signup items": "Item pendaftaran",
@@ -504,6 +513,8 @@
"Host - Tooltip": "Nama tuan rumah",
"IdP": "IdP",
"IdP certificate": "Sertifikat IdP",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "URL penerbit",
"Issuer URL - Tooltip": "URL Penerbit",
"Link copied to clipboard successfully": "Tautan berhasil disalin ke papan klip",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "Metadata SAML",
"Method - Tooltip": "Metode login, kode QR atau login tanpa suara",
"New Provider": "Penyedia Baru",
"Normal": "Normal",
"Parse": "Parse: Memecah atau mengurai data atau teks menjadi bagian-bagian yang lebih kecil dan lebih mudah dipahami atau dimanipulasi",
"Parse metadata successfully": "Berhasil mem-parse metadata",
"Path prefix": "Awalan jalur",
@@ -555,8 +567,10 @@
"Signup HTML": "Pendaftaran HTML",
"Signup HTML - Edit": "Pendaftaran HTML - Sunting",
"Signup HTML - Tooltip": "HTML khusus untuk mengganti gaya halaman pendaftaran bawaan",
"Silent": "Silent",
"Site key": "Kunci situs",
"Site key - Tooltip": "Kunci situs atau kunci halaman web",
"Sliding Validation": "Sliding Validation",
"Sub type": "Sub jenis",
"Sub type - Tooltip": "Sub jenis",
"Template code": "Kode template",
@@ -564,6 +578,7 @@
"Test Email": "Email Uji Coba",
"Test Email - Tooltip": "Alamat email untuk menerima email percobaan",
"Test SMTP Connection": "Tes Koneksi SMTP",
"Third-party": "Third-party",
"Token URL": "Token URL: Tautan Token",
"Token URL - Tooltip": "Token URL: URL Token",
"Type": "Jenis",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "Input yang dimasukkan bukan sesuai dengan format Email yang valid!",
"The input is not valid Phone!": "Masukan ponsel tidak valid!",
"Username": "Nama pengguna",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Akun Anda telah dibuat!",
"Your confirmed password is inconsistent with the password!": "Kata sandi yang dikonfirmasi tidak konsisten dengan kata sandi!",
"sign in now": "Masuk sekarang"
@@ -633,7 +649,7 @@
"Casdoor column": "Kolom Casdoor",
"Column name": "Nama kolom",
"Column type": "Tipe kolom",
"Database": "Database (bahasa Indonesia)",
"Database": "Database",
"Database - Tooltip": "Nama basis data asli",
"Database type": "Tipe Basis Data",
"Database type - Tooltip": "Jenis database, mendukung semua database yang didukung oleh XORM, seperti MySQL, PostgreSQL, SQL Server, Oracle, SQLite, dan lain-lain.",

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "新しいアカウントの登録をユーザーに許可するかどうか",
"Failed to sign in": "ログインに失敗しました",
"File uploaded successfully": "ファイルが正常にアップロードされました",
"First, last": "First, last",
"Follow organization theme": "組織のテーマに従ってください",
"Form CSS": "フォームCSS",
"Form CSS - Edit": "フォームのCSS - 編集",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "登録、ログイン、パスワード忘れフォームの位置",
"Grant types": "グラント種類",
"Grant types - Tooltip": "OAuthプロトコルで許可されているグラントタイプを選択してください",
"Incremental": "Incremental",
"Left": "左",
"Logged in successfully": "正常にログインしました",
"Logged out successfully": "正常にログアウトしました",
"New Application": "新しいアプリケーション",
"No verification": "No verification",
"None": "なし",
"Normal": "Normal",
"Only signup": "Only signup",
"Please input your application!": "あなたの申請を入力してください!",
"Please input your organization!": "あなたの組織を入力してください!",
"Please select a HTML file": "HTMLファイルを選択してください",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "プロンプトページのURLが正常にクリップボードにコピーされました。インコグニートウィンドウまたは別のブラウザに貼り付けてください",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "リダイレクトURL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "リダイレクトURLアサーションコンシューマサービスPOSTバインディングURL",
"Redirect URLs": "リダイレクトURL",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "サイドパネルのHTML - 編集",
"Side panel HTML - Tooltip": "ログインページのサイドパネルに対するHTMLコードをカスタマイズしてください",
"Sign Up Error": "サインアップエラー",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "サインインページのURLがクリップボードに正常にコピーされました。インコグニートウィンドウまたは別のブラウザに貼り付けてください",
"Signin session": "サインインセッション",
"Signup items": "サインアップアイテム",
@@ -504,6 +513,8 @@
"Host - Tooltip": "ホストの名前",
"IdP": "IdP",
"IdP certificate": "IdP証明書",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "発行者のURL",
"Issuer URL - Tooltip": "発行者URL",
"Link copied to clipboard successfully": "リンクがクリップボードに正常にコピーされました",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "SAMLのメタデータ",
"Method - Tooltip": "ログイン方法、QRコードまたはサイレントログイン",
"New Provider": "新しい提供者",
"Normal": "Normal",
"Parse": "パースする",
"Parse metadata successfully": "メタデータを正常に解析しました",
"Path prefix": "パスプレフィックス",
@@ -555,8 +567,10 @@
"Signup HTML": "サインアップ HTML",
"Signup HTML - Edit": "サインアップ HTML - 編集",
"Signup HTML - Tooltip": "デフォルトのサインアップページスタイルを置き換えるためのカスタムHTML",
"Silent": "Silent",
"Site key": "サイトキー",
"Site key - Tooltip": "サイトキー",
"Sliding Validation": "Sliding Validation",
"Sub type": "サブタイプ",
"Sub type - Tooltip": "サブタイプ",
"Template code": "テンプレートコード",
@@ -564,6 +578,7 @@
"Test Email": "テストメール",
"Test Email - Tooltip": "テストメールを受け取るためのメールアドレス",
"Test SMTP Connection": "SMTP接続をテストする",
"Third-party": "Third-party",
"Token URL": "トークンのURL",
"Token URL - Tooltip": "トークンURL",
"Type": "タイプ",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "入力されたものは有効なメールではありません",
"The input is not valid Phone!": "この入力は有効な電話番号ではありません!",
"Username": "ユーザー名",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "あなたのアカウントが作成されました!",
"Your confirmed password is inconsistent with the password!": "確認されたパスワードは、パスワードと矛盾しています!",
"sign in now": "今すぐサインインしてください"

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "사용자가 새로운 계정을 등록할지 여부",
"Failed to sign in": "로그인 실패했습니다",
"File uploaded successfully": "파일이 성공적으로 업로드되었습니다",
"First, last": "First, last",
"Follow organization theme": "조직의 주제를 따르세요",
"Form CSS": "CSS 양식",
"Form CSS - Edit": "폼 CSS - 편집",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "가입, 로그인 및 비밀번호 재설정 양식의 위치",
"Grant types": "Grant types: 부여 유형",
"Grant types - Tooltip": "OAuth 프로토콜에서 허용되는 그란트 유형을 선택하십시오",
"Incremental": "Incremental",
"Left": "왼쪽",
"Logged in successfully": "성공적으로 로그인했습니다",
"Logged out successfully": "로그아웃이 성공적으로 되었습니다",
"New Application": "새로운 응용 프로그램",
"No verification": "No verification",
"None": "없음",
"Normal": "Normal",
"Only signup": "Only signup",
"Please input your application!": "당신의 신청서를 입력해주세요!",
"Please input your organization!": "귀하의 조직을 입력해 주세요!",
"Please select a HTML file": "HTML 파일을 선택해 주세요",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "프롬프트 페이지 URL이 클립 보드에 성공적으로 복사되었습니다. 시크릿 모드 창이나 다른 브라우저에 붙여 넣으세요",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "리디렉트 URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "리디렉션 URL (단언 서비스 소비자 POST 바인딩 URL)",
"Redirect URLs": "URL 리디렉트",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "사이드 패널 HTML - 편집",
"Side panel HTML - Tooltip": "로그인 페이지의 측면 패널용 HTML 코드를 맞춤 설정하십시오",
"Sign Up Error": "가입 오류",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "로그인 페이지 URL이 클립보드에 성공적으로 복사되었습니다. 익명 창이나 다른 브라우저에 붙여넣어주세요",
"Signin session": "로그인 세션",
"Signup items": "가입 항목",
@@ -504,6 +513,8 @@
"Host - Tooltip": "호스트의 이름",
"IdP": "IdP",
"IdP certificate": "IdP 인증서",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "발행자 URL",
"Issuer URL - Tooltip": "발급자 URL",
"Link copied to clipboard successfully": "링크가 클립보드에 성공적으로 복사되었습니다",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "SAML 메타데이터",
"Method - Tooltip": "로그인 방법, QR 코드 또는 음성 로그인",
"New Provider": "새로운 공급 업체",
"Normal": "Normal",
"Parse": "파싱",
"Parse metadata successfully": "메타데이터를 성공적으로 분석했습니다",
"Path prefix": "경로 접두어",
@@ -555,8 +567,10 @@
"Signup HTML": "가입 양식 HTML",
"Signup HTML - Edit": "가입 HTML - 수정",
"Signup HTML - Tooltip": "기본 가입 페이지 스타일을 바꾸기 위한 사용자 지정 HTML",
"Silent": "Silent",
"Site key": "사이트 키",
"Site key - Tooltip": "사이트 키",
"Sliding Validation": "Sliding Validation",
"Sub type": "하위 유형",
"Sub type - Tooltip": "서브 타입",
"Template code": "템플릿 코드",
@@ -564,6 +578,7 @@
"Test Email": "테스트 이메일",
"Test Email - Tooltip": "테스트 메일을 받을 이메일 주소",
"Test SMTP Connection": "테스트 SMTP 연결",
"Third-party": "Third-party",
"Token URL": "토큰 URL",
"Token URL - Tooltip": "토큰 URL",
"Type": "타입",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "입력 값은 유효한 이메일이 아닙니다!",
"The input is not valid Phone!": "입력이 유효한 전화번호가 아닙니다!",
"Username": "사용자 이름",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "계정이 생성되었습니다!",
"Your confirmed password is inconsistent with the password!": "확인된 비밀번호가 비밀번호와 일치하지 않습니다!",
"sign in now": "지금 로그인하십시오"

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "Разрешить ли пользователям зарегистрировать новый аккаунт",
"Failed to sign in": "Не удалось войти в систему",
"File uploaded successfully": "Файл успешно загружен",
"First, last": "First, last",
"Follow organization theme": "Cледуйте теме организации",
"Form CSS": "Форма CSS",
"Form CSS - Edit": "Форма CSS - Редактирование",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "Местоположение форм регистрации, входа и восстановления пароля",
"Grant types": "Типы грантов",
"Grant types - Tooltip": "Выберите, какие типы грантов разрешены в протоколе OAuth",
"Incremental": "Incremental",
"Left": "Левый",
"Logged in successfully": "Успешный вход в систему",
"Logged out successfully": "Успешный выход из системы",
"New Application": "Новое приложение",
"No verification": "No verification",
"None": "Никакой",
"Normal": "Normal",
"Only signup": "Only signup",
"Please input your application!": "Пожалуйста, введите свою заявку!",
"Please input your organization!": "Пожалуйста, введите название вашей организации!",
"Please select a HTML file": "Пожалуйста, выберите файл HTML",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL страницы успешно скопирован в буфер обмена, пожалуйста, вставьте его в режиме инкогнито или в другом браузере",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "Перенаправление URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Перенаправление URL (адрес сервиса потребителя утверждения POST-связывание)",
"Redirect URLs": "Перенаправление URL-адресов",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "Боковая панель HTML - Редактировать",
"Side panel HTML - Tooltip": "Настроить HTML-код для боковой панели страницы входа в систему",
"Sign Up Error": "Ошибка при регистрации",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL страницы входа скопирован успешно, пожалуйста, вставьте ее в инкогнито-окно или другой браузер",
"Signin session": "Сессия входа в систему",
"Signup items": "Элементы регистрации",
@@ -504,6 +513,8 @@
"Host - Tooltip": "Имя хоста",
"IdP": "IdP",
"IdP certificate": "Сертификат IdP",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "URL выпускающего органа",
"Issuer URL - Tooltip": "URL эмитента",
"Link copied to clipboard successfully": "Ссылка успешно скопирована в буфер обмена",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "Метаданные SAML",
"Method - Tooltip": "Метод входа, QR-код или беззвучный вход",
"New Provider": "Новый провайдер",
"Normal": "Normal",
"Parse": "Спарсить",
"Parse metadata successfully": "Успешно обработана метаданные",
"Path prefix": "Префикс пути",
@@ -555,8 +567,10 @@
"Signup HTML": "Регистрационная форма HTML",
"Signup HTML - Edit": "Регистрационная форма HTML - Редактировать",
"Signup HTML - Tooltip": "Пользовательский HTML для замены стиля стандартной страницы регистрации",
"Silent": "Silent",
"Site key": "Ключ сайта",
"Site key - Tooltip": "Ключ сайта",
"Sliding Validation": "Sliding Validation",
"Sub type": "Подтип",
"Sub type - Tooltip": "Подтип",
"Template code": "Шаблонный код",
@@ -564,6 +578,7 @@
"Test Email": "Тестовое письмо",
"Test Email - Tooltip": "Адрес электронной почты для получения тестовых писем",
"Test SMTP Connection": "Тестирование соединения SMTP",
"Third-party": "Third-party",
"Token URL": "Токен URL (URL-адрес маркера)",
"Token URL - Tooltip": "Токен URL",
"Type": "Тип",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "Ввод не является действительным адресом электронной почты!",
"The input is not valid Phone!": "Ввод не является действительным телефоном!",
"Username": "Имя пользователя",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Ваш аккаунт был создан!",
"Your confirmed password is inconsistent with the password!": "Ваш подтвержденный пароль не соответствует паролю!",
"sign in now": "войти сейчас"

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "Có cho phép người dùng đăng ký tài khoản mới không?",
"Failed to sign in": "Không đăng nhập được",
"File uploaded successfully": "Tệp được tải lên thành công",
"First, last": "First, last",
"Follow organization theme": "Theo chủ đề tổ chức",
"Form CSS": "Mẫu CSS",
"Form CSS - Edit": "Biểu mẫu CSS - Chỉnh sửa",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "Vị trí của các biểu mẫu đăng ký, đăng nhập và quên mật khẩu",
"Grant types": "Loại hỗ trợ",
"Grant types - Tooltip": "Chọn loại hỗ trợ được cho phép trong giao thức OAuth",
"Incremental": "Incremental",
"Left": "Trái",
"Logged in successfully": "Đăng nhập thành công",
"Logged out successfully": "Đã đăng xuất thành công",
"New Application": "Ứng dụng mới",
"No verification": "No verification",
"None": "Không có gì",
"Normal": "Normal",
"Only signup": "Only signup",
"Please input your application!": "Vui lòng nhập đơn của bạn!",
"Please input your organization!": "Vui lòng nhập tên tổ chức của bạn!",
"Please select a HTML file": "Vui lòng chọn tệp HTML",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Đã sao chép đường dẫn trang một cách thành công, hãy dán nó vào cửa sổ ẩn danh hoặc trình duyệt khác",
"Random": "Random",
"Real name": "Real name",
"Redirect URL": "Chuyển hướng đường dẫn URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Điều hướng URL (URL khung POST Dịch vụ Tiêu thụ Khẳng định)",
"Redirect URLs": "Chuyển hướng URL",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "Bảng Panel Bên - Chỉnh sửa HTML",
"Side panel HTML - Tooltip": "Tùy chỉnh mã HTML cho bảng điều khiển bên của trang đăng nhập",
"Sign Up Error": "Lỗi đăng ký",
"Signin": "Signin",
"Signin (Default True)": "Signin (Default True)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Đã sao chép thành công địa chỉ URL trang Đăng nhập vào clipboard, vui lòng dán nó vào cửa sổ ẩn danh hoặc trình duyệt khác",
"Signin session": "Phiên đăng nhập",
"Signup items": "Các mục đăng ký",
@@ -504,6 +513,8 @@
"Host - Tooltip": "Tên của người chủ chỗ ở",
"IdP": "IdP",
"IdP certificate": "Chứng chỉ IdP",
"Intelligent Validation": "Intelligent Validation",
"Internal": "Internal",
"Issuer URL": "Địa chỉ URL của người phát hành",
"Issuer URL - Tooltip": "Địa chỉ URL của nhà phát hành",
"Link copied to clipboard successfully": "Đã sao chép liên kết vào bộ nhớ tạm thành công",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "SAML metadata: siêu dữ liệu SAML",
"Method - Tooltip": "Phương thức đăng nhập, mã QR hoặc đăng nhập im lặng",
"New Provider": "Nhà cung cấp mới",
"Normal": "Normal",
"Parse": "Phân tích cú pháp",
"Parse metadata successfully": "Phân tích siêu dữ liệu thành công",
"Path prefix": "Tiền tố đường dẫn",
@@ -555,8 +567,10 @@
"Signup HTML": "Đăng ký HTML",
"Signup HTML - Edit": "Đăng ký HTML - Chỉnh sửa",
"Signup HTML - Tooltip": "Trang HTML tùy chỉnh để thay thế phong cách trang đăng ký mặc định",
"Silent": "Silent",
"Site key": "Khóa trang web",
"Site key - Tooltip": "Khóa trang web",
"Sliding Validation": "Sliding Validation",
"Sub type": "Loại phụ",
"Sub type - Tooltip": "Loại phụ",
"Template code": "Mã mẫu của template",
@@ -564,6 +578,7 @@
"Test Email": "Thư Email kiểm tra",
"Test Email - Tooltip": "Địa chỉ email để nhận thư kiểm tra",
"Test SMTP Connection": "Kiểm tra kết nối SMTP",
"Third-party": "Third-party",
"Token URL": "Đường dẫn Token",
"Token URL - Tooltip": "Địa chỉ URL của Token",
"Type": "Kiểu",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "Đầu vào không phải là địa chỉ Email hợp lệ!",
"The input is not valid Phone!": "Đầu vào không hợp lệ! Số điện thoại không hợp lệ!",
"Username": "Tên đăng nhập",
"Username - Tooltip": "Username - Tooltip",
"Your account has been created!": "Tài khoản của bạn đã được tạo!",
"Your confirmed password is inconsistent with the password!": "Mật khẩu xác nhận của bạn không khớp với mật khẩu đã nhập!",
"sign in now": "Đăng nhập ngay bây giờ"

View File

@@ -41,6 +41,7 @@
"Enable signup - Tooltip": "是否允许用户注册",
"Failed to sign in": "登录失败",
"File uploaded successfully": "文件上传成功",
"First, last": "名字, 姓氏",
"Follow organization theme": "使用组织主题",
"Form CSS": "表单CSS",
"Form CSS - Edit": "编辑表单CSS",
@@ -49,15 +50,21 @@
"Form position - Tooltip": "注册、登录、忘记密码等表单的位置",
"Grant types": "OAuth授权类型",
"Grant types - Tooltip": "选择允许哪些OAuth协议中的grant types",
"Incremental": "递增",
"Left": "居左",
"Logged in successfully": "登录成功",
"Logged out successfully": "登出成功",
"New Application": "添加应用",
"No verification": "不校验",
"None": "关闭",
"Normal": "标准",
"Only signup": "仅注册",
"Please input your application!": "请输入你的应用",
"Please input your organization!": "请输入你的组织",
"Please select a HTML file": "请选择一个HTML文件",
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "提醒页面URL已成功复制到剪贴板请粘贴到当前浏览器的隐身模式窗口或另一个浏览器访问",
"Random": "随机",
"Real name": "真实姓名",
"Redirect URL": "重定向 URL",
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "回复 URL (断言使用者服务 URL, 使用POST请求返回响应) - Tooltip",
"Redirect URLs": "重定向 URLs",
@@ -74,6 +81,8 @@
"Side panel HTML - Edit": "侧面板HTML - 编辑",
"Side panel HTML - Tooltip": "自定义登录页面侧面板的HTML代码",
"Sign Up Error": "注册错误",
"Signin": "登录",
"Signin (Default True)": "登录 (默认同意)",
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "登录页面URL已成功复制到剪贴板请粘贴到当前浏览器的隐身模式窗口或另一个浏览器访问",
"Signin session": "保持登录会话",
"Signup items": "注册项",
@@ -504,6 +513,8 @@
"Host - Tooltip": "主机名",
"IdP": "IdP",
"IdP certificate": "IdP公钥证书",
"Intelligent Validation": "智能验证",
"Internal": "内部",
"Issuer URL": "Issuer链接",
"Issuer URL - Tooltip": "Issuer链接URL",
"Link copied to clipboard successfully": "链接已成功复制到剪贴板",
@@ -511,6 +522,7 @@
"Metadata - Tooltip": "SAML元数据",
"Method - Tooltip": "登录方法,二维码或者静默授权登录",
"New Provider": "添加提供商",
"Normal": "标准",
"Parse": "解析",
"Parse metadata successfully": "解析元数据成功",
"Path prefix": "路径前缀",
@@ -555,8 +567,10 @@
"Signup HTML": "注册页面HTML",
"Signup HTML - Edit": "注册页面HTML - 编辑",
"Signup HTML - Tooltip": "自定义HTML用于替换默认的注册页面样式",
"Silent": "静默",
"Site key": "Site key",
"Site key - Tooltip": "Site key",
"Sliding Validation": "滑块验证",
"Sub type": "子类型",
"Sub type - Tooltip": "子类型",
"Template code": "模板代码",
@@ -564,6 +578,7 @@
"Test Email": "测试Email配置",
"Test Email - Tooltip": "接收测试邮件的Email邮箱",
"Test SMTP Connection": "测试SMTP连接",
"Third-party": "第三方",
"Token URL": "Token URL",
"Token URL - Tooltip": "自定义OAuth的Token URL",
"Type": "类型",
@@ -621,6 +636,7 @@
"The input is not valid Email!": "您输入的电子邮箱格式有误!",
"The input is not valid Phone!": "您输入的手机号格式有误!",
"Username": "用户名",
"Username - Tooltip": "用户名",
"Your account has been created!": "您的账号已成功创建!",
"Your confirmed password is inconsistent with the password!": "您两次输入的密码不一致!",
"sign in now": "立即登录"

View File

@@ -15,7 +15,7 @@
import React from "react";
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Row, Select, Switch, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
const {Option} = Select;

View File

@@ -14,11 +14,11 @@
import React from "react";
import {Button, Col, Row, Table} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
import * as LdapBackend from "./backend/LdapBackend";
import * as LdapBackend from "../backend/LdapBackend";
import {Link} from "react-router-dom";
import PopconfirmModal from "./PopconfirmModal";
import PopconfirmModal from "../PopconfirmModal";
class LdapTable extends React.Component {
constructor(props) {

View File

@@ -15,7 +15,7 @@
import React from "react";
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Input, Row, Select, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
const {Option} = Select;

View File

@@ -15,9 +15,9 @@
import React from "react";
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Row, Select, Switch, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
import * as Provider from "./auth/Provider";
import * as Provider from "../auth/Provider";
const {Option} = Select;

View File

@@ -15,7 +15,7 @@
import React from "react";
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Row, Select, Switch, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
const {Option} = Select;
@@ -172,25 +172,25 @@ class SignupTable extends React.Component {
let options = [];
if (record.name === "ID") {
options = [
{id: "Random", name: "Random"},
{id: "Incremental", name: "Incremental"},
{id: "Random", name: i18next.t("application:Random")},
{id: "Incremental", name: i18next.t("application:Incremental")},
];
} else if (record.name === "Display name") {
options = [
{id: "None", name: "None"},
{id: "Real name", name: "Real name"},
{id: "First, last", name: "First, last"},
{id: "None", name: i18next.t("application:None")},
{id: "Real name", name: i18next.t("application:Real name")},
{id: "First, last", name: i18next.t("application:First, last")},
];
} else if (record.name === "Email") {
options = [
{id: "Normal", name: "Normal"},
{id: "No verification", name: "No verification"},
{id: "Normal", name: i18next.t("application:Normal")},
{id: "No verification", name: i18next.t("application:No verification")},
];
} else if (record.name === "Agreement") {
options = [
{id: "None", name: "None"},
{id: "Signin", name: "Signin"},
{id: "Signin (Default True)", name: "Signin (Default True)"},
{id: "None", name: i18next.t("application:Only signup")},
{id: "Signin", name: i18next.t("application:Signin")},
{id: "Signin (Default True)", name: i18next.t("application:Signin (Default True)")},
];
}

View File

@@ -15,7 +15,7 @@
import React from "react";
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Input, Row, Select, Switch, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
const {Option} = Select;

View File

@@ -15,7 +15,7 @@
import React from "react";
import {DeleteOutlined, DownOutlined, LinkOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Input, Row, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
class UrlTable extends React.Component {

View File

@@ -15,8 +15,8 @@
import React from "react";
import {Button, Table} from "antd";
import i18next from "i18next";
import * as UserWebauthnBackend from "./backend/UserWebauthnBackend";
import * as Setting from "./Setting";
import * as UserWebauthnBackend from "../backend/UserWebauthnBackend";
import * as Setting from "../Setting";
class WebAuthnCredentialTable extends React.Component {
deleteRow(table, i) {

View File

@@ -15,7 +15,7 @@
import React from "react";
import {DeleteOutlined, DownOutlined, UpOutlined} from "@ant-design/icons";
import {Button, Col, Input, Row, Table, Tooltip} from "antd";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
import i18next from "i18next";
class WebhookHeaderTable extends React.Component {

View File

@@ -16,7 +16,7 @@ import React from "react";
import {Button, Input, Table} from "antd";
import i18next from "i18next";
import {DeleteOutlined} from "@ant-design/icons";
import * as Setting from "./Setting";
import * as Setting from "../Setting";
class PropertyTable extends React.Component {
constructor(props) {