mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-23 06:23:22 +08:00
Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
79b393afee | |||
5bb12a30d4 | |||
fdb68bf9c8 | |||
37748850c8 | |||
8968396ae5 | |||
f5395f15f9 | |||
73e44df867 | |||
0b575ccf84 | |||
9b7f465a47 | |||
b1fe28fb83 | |||
530d054adb | |||
a2b9f9baaf | |||
a2d20fcb63 | |||
b118a3bb76 | |||
280867d0cb | |||
30fa2f7d81 | |||
518288691d | |||
ffa54247cd | |||
0199ad9aaa | |||
b9d171718f | |||
e841d0ba8e | |||
e5a9594f90 | |||
c542929835 | |||
86dea71efd | |||
9e536850fd | |||
fddd4a12b8 | |||
2d6fae32be | |||
741cff99df | |||
cad9c28e92 | |||
524cf4dda5 | |||
077a1cb8b7 | |||
00efdf1d03 | |||
aa543f1abb | |||
1d1d3049bd | |||
4f497d44a5 | |||
369de36987 |
37
.github/workflows/build.yml
vendored
37
.github/workflows/build.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
|
||||
@ -167,10 +167,8 @@ 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
|
||||
@ -208,3 +206,36 @@ jobs:
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: casbin/casdoor-all-in-one:${{steps.get-current-tag.outputs.tag }},casbin/casdoor-all-in-one:latest
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
if: steps.should_push.outputs.push=='true'
|
||||
with:
|
||||
repository: casdoor/casdoor-helm
|
||||
ref: 'master'
|
||||
token: ${{ secrets.GH_BOT_TOKEN }}
|
||||
|
||||
- name: Update Helm Chart
|
||||
if: steps.should_push.outputs.push=='true'
|
||||
run: |
|
||||
# Set the appVersion of the chart to the current tag
|
||||
sed -i "s/appVersion: .*/appVersion: ${{steps.get-current-tag.outputs.tag }}/g" ./charts/casdoor/Chart.yaml
|
||||
|
||||
# increase the patch version of the chart
|
||||
currentChartVersion=$(cat ./charts/casdoor/Chart.yaml | grep ^version | awk '{print $2}')
|
||||
newChartVersion=$(echo $currentChartVersion | awk -F. -v OFS=. '{$NF++;print}')
|
||||
sed -i "s/version: .*/version: $newChartVersion/g" ./charts/casdoor/Chart.yaml
|
||||
|
||||
REGISTRY=oci://registry-1.docker.io/casbin
|
||||
cd charts/casdoor
|
||||
helm package .
|
||||
PKG_NAME=$(ls *.tgz)
|
||||
helm repo index . --url $REGISTRY --merge index.yaml
|
||||
helm push $PKG_NAME $REGISTRY
|
||||
rm $PKG_NAME
|
||||
|
||||
# Commit and push the changes back to the repository
|
||||
git config --global user.name "casbin-bot"
|
||||
git config --global user.email "casbin-bot@github.com"
|
||||
git add Chart.yaml index.yaml
|
||||
git commit -m "chore(helm): bump helm charts appVersion to ${{steps.get-current-tag.outputs.tag }}"
|
||||
git push origin HEAD:master
|
||||
|
40
.github/workflows/helm.yml
vendored
40
.github/workflows/helm.yml
vendored
@ -1,40 +0,0 @@
|
||||
name: Helm Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'manifests/casdoor/Chart.yaml'
|
||||
|
||||
jobs:
|
||||
release-helm-chart:
|
||||
name: Release Helm Chart
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Helm
|
||||
uses: azure/setup-helm@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Release Helm Chart
|
||||
run: |
|
||||
cd manifests/casdoor
|
||||
REGISTRY=oci://registry-1.docker.io/casbin
|
||||
helm package .
|
||||
PKG_NAME=$(ls *.tgz)
|
||||
helm repo index . --url $REGISTRY --merge index.yaml
|
||||
helm push $PKG_NAME $REGISTRY
|
||||
rm $PKG_NAME
|
||||
|
||||
- name: Commit updated helm index.yaml
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_message: 'ci: update helm index.yaml'
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -18,7 +18,7 @@ bin/
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
.vscode/
|
||||
.vscode/settings.json
|
||||
|
||||
tmp/
|
||||
tmpFiles/
|
||||
@ -31,3 +31,6 @@ commentsRouter*.go
|
||||
# ignore build result
|
||||
casdoor
|
||||
server
|
||||
|
||||
# include helm-chart
|
||||
!manifests/casdoor
|
||||
|
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"debugAdapter": "dlv-dap",
|
||||
"args": ["--createDatabase=true"]
|
||||
}
|
||||
]
|
||||
}
|
3
Makefile
3
Makefile
@ -86,6 +86,9 @@ docker-build: ## Build docker image with the manager.
|
||||
docker-push: ## Push docker image with the manager.
|
||||
docker push ${REGISTRY}/${IMG}:${IMG_TAG}
|
||||
|
||||
deps: ## Run dependencies for local development
|
||||
docker compose up -d db
|
||||
|
||||
lint-install: ## Install golangci-lint
|
||||
@# The following installs a specific version of golangci-lint, which is appropriate for a CI server to avoid different results from build to build
|
||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.40.1
|
||||
|
@ -110,14 +110,6 @@ func (c *ApiController) GetApplication() {
|
||||
}
|
||||
}
|
||||
|
||||
// 0 as an initialization value, corresponding to the default configuration parameters
|
||||
if application.FailedSigninLimit == 0 {
|
||||
application.FailedSigninLimit = object.DefaultFailedSigninLimit
|
||||
}
|
||||
if application.FailedSigninfrozenTime == 0 {
|
||||
application.FailedSigninfrozenTime = object.DefaultFailedSigninfrozenTime
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetMaskedApplication(application, userId))
|
||||
}
|
||||
|
||||
|
@ -399,10 +399,14 @@ func (c *ApiController) Login() {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
|
||||
return
|
||||
}
|
||||
if !application.IsPasswordEnabled() {
|
||||
if authForm.SigninMethod == "Password" && !application.IsPasswordEnabled() {
|
||||
c.ResponseError(c.T("auth:The login method: login with password is not enabled for the application"))
|
||||
return
|
||||
}
|
||||
if authForm.SigninMethod == "LDAP" && !application.IsLdapEnabled() {
|
||||
c.ResponseError(c.T("auth:The login method: login with LDAP is not enabled for the application"))
|
||||
return
|
||||
}
|
||||
var enableCaptcha bool
|
||||
if enableCaptcha, err = object.CheckToEnableCaptcha(application, authForm.Organization, authForm.Username); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
@ -432,7 +436,14 @@ func (c *ApiController) Login() {
|
||||
}
|
||||
|
||||
password := authForm.Password
|
||||
user, err = object.CheckUserPassword(authForm.Organization, authForm.Username, password, c.GetAcceptLanguage(), enableCaptcha)
|
||||
isSigninViaLdap := authForm.SigninMethod == "LDAP"
|
||||
var isPasswordWithLdapEnabled bool
|
||||
if authForm.SigninMethod == "Password" {
|
||||
isPasswordWithLdapEnabled = application.IsPasswordWithLdapEnabled()
|
||||
} else {
|
||||
isPasswordWithLdapEnabled = false
|
||||
}
|
||||
user, err = object.CheckUserPassword(authForm.Organization, authForm.Username, password, c.GetAcceptLanguage(), enableCaptcha, isSigninViaLdap, isPasswordWithLdapEnabled)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
// @Param permissionId query string false "permission id"
|
||||
// @Param modelId query string false "model id"
|
||||
// @Param resourceId query string false "resource id"
|
||||
// @Param owner query string false "owner"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /enforce [post]
|
||||
func (c *ApiController) Enforce() {
|
||||
@ -37,6 +38,7 @@ func (c *ApiController) Enforce() {
|
||||
modelId := c.Input().Get("modelId")
|
||||
resourceId := c.Input().Get("resourceId")
|
||||
enforcerId := c.Input().Get("enforcerId")
|
||||
owner := c.Input().Get("owner")
|
||||
|
||||
if len(c.Ctx.Input.RequestBody) == 0 {
|
||||
c.ResponseError("The request body should not be empty")
|
||||
@ -117,6 +119,8 @@ func (c *ApiController) Enforce() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if owner != "" {
|
||||
permissions, err = object.GetPermissions(owner)
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
@ -152,12 +156,14 @@ func (c *ApiController) Enforce() {
|
||||
// @Param body body []string true "array of casbin requests"
|
||||
// @Param permissionId query string false "permission id"
|
||||
// @Param modelId query string false "model id"
|
||||
// @Param owner query string false "owner"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /batch-enforce [post]
|
||||
func (c *ApiController) BatchEnforce() {
|
||||
permissionId := c.Input().Get("permissionId")
|
||||
modelId := c.Input().Get("modelId")
|
||||
enforcerId := c.Input().Get("enforcerId")
|
||||
owner := c.Input().Get("owner")
|
||||
|
||||
var requests [][]string
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &requests)
|
||||
@ -227,6 +233,8 @@ func (c *ApiController) BatchEnforce() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if owner != "" {
|
||||
permissions, err = object.GetPermissions(owner)
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
|
@ -54,7 +54,7 @@ type NotificationForm struct {
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /api/send-email [post]
|
||||
func (c *ApiController) SendEmail() {
|
||||
user, ok := c.RequireSignedInUser()
|
||||
userId, ok := c.RequireSignedIn()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@ -116,8 +116,17 @@ func (c *ApiController) SendEmail() {
|
||||
|
||||
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
|
||||
content := strings.Replace(provider.Content, "%s", code, 1)
|
||||
if user != nil {
|
||||
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
|
||||
if !strings.HasPrefix(userId, "app/") {
|
||||
var user *object.User
|
||||
user, err = object.GetUser(userId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if user != nil {
|
||||
content = strings.Replace(content, "%{user.friendlyName}", user.GetFriendlyName(), 1)
|
||||
}
|
||||
}
|
||||
|
||||
for _, receiver := range emailForm.Receivers {
|
||||
|
@ -15,7 +15,8 @@
|
||||
package form
|
||||
|
||||
type AuthForm struct {
|
||||
Type string `json:"type"`
|
||||
Type string `json:"type"`
|
||||
SigninMethod string `json:"signinMethod"`
|
||||
|
||||
Organization string `json:"organization"`
|
||||
Username string `json:"username"`
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "Die Anmeldeart \"Anmeldung mit Passwort\" ist für die Anwendung nicht aktiviert",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"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",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"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",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "Metode login: login dengan kata sandi tidak diaktifkan untuk aplikasi tersebut",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "ログイン方法:パスワードでのログインはアプリケーションで有効になっていません",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "어플리케이션에서는 암호를 사용한 로그인 방법이 활성화되어 있지 않습니다",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "Метод входа: вход с паролем не включен для приложения",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "The login method: login with LDAP is not enabled for the application",
|
||||
"The login method: login with SMS is not enabled for the application": "The login method: login with SMS is not enabled for the application",
|
||||
"The login method: login with email is not enabled for the application": "The login method: login with email is not enabled for the application",
|
||||
"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",
|
||||
|
@ -15,6 +15,7 @@
|
||||
"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 LDAP is not enabled for the application": "该应用禁止采用LDAP登录方式",
|
||||
"The login method: login with SMS is not enabled for the application": "该应用禁止采用短信登录方式",
|
||||
"The login method: login with email is not enabled for the application": "该应用禁止采用邮箱登录方式",
|
||||
"The login method: login with password is not enabled for the application": "该应用禁止采用密码登录方式",
|
||||
|
@ -49,7 +49,7 @@
|
||||
{
|
||||
"name": "Password",
|
||||
"displayName": "Password",
|
||||
"rule": "None",
|
||||
"rule": "All",
|
||||
},
|
||||
{
|
||||
"name": "Verification code",
|
||||
@ -123,7 +123,7 @@
|
||||
"redirectUris": [""],
|
||||
"expireInHours": 168,
|
||||
"failedSigninLimit": 5,
|
||||
"failedSigninfrozenTime": 15
|
||||
"failedSigninFrozenTime": 15
|
||||
}
|
||||
],
|
||||
"users": [
|
||||
|
147
ldap/server.go
147
ldap/server.go
@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@ -49,7 +50,17 @@ func handleBind(w ldap.ResponseWriter, m *ldap.Message) {
|
||||
res := ldap.NewBindResponse(ldap.LDAPResultSuccess)
|
||||
|
||||
if r.AuthenticationChoice() == "simple" {
|
||||
bindUsername, bindOrg, err := getNameAndOrgFromDN(string(r.Name()))
|
||||
bindDN := string(r.Name())
|
||||
bindPassword := string(r.AuthenticationSimple())
|
||||
|
||||
if bindDN == "" && bindPassword == "" {
|
||||
res.SetResultCode(ldap.LDAPResultInappropriateAuthentication)
|
||||
res.SetDiagnosticMessage("Anonymous bind disallowed")
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
|
||||
bindUsername, bindOrg, err := getNameAndOrgFromDN(bindDN)
|
||||
if err != nil {
|
||||
log.Printf("getNameAndOrgFromDN() error: %s", err.Error())
|
||||
res.SetResultCode(ldap.LDAPResultInvalidDNSyntax)
|
||||
@ -58,7 +69,6 @@ func handleBind(w ldap.ResponseWriter, m *ldap.Message) {
|
||||
return
|
||||
}
|
||||
|
||||
bindPassword := string(r.AuthenticationSimple())
|
||||
bindUser, err := object.CheckUserPassword(bindOrg, bindUsername, bindPassword, "en")
|
||||
if err != nil {
|
||||
log.Printf("Bind failed User=%s, Pass=%#v, ErrMsg=%s", string(r.Name()), r.Authentication(), err)
|
||||
@ -93,7 +103,46 @@ func handleSearch(w ldap.ResponseWriter, m *ldap.Message) {
|
||||
}
|
||||
|
||||
r := m.GetSearchRequest()
|
||||
if r.FilterString() == "(objectClass=*)" {
|
||||
|
||||
// case insensitive match
|
||||
if strings.EqualFold(r.FilterString(), "(objectClass=*)") {
|
||||
if len(r.Attributes()) == 0 {
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
first_attr := string(r.Attributes()[0])
|
||||
|
||||
if string(r.BaseObject()) == "" {
|
||||
// handle special search requests
|
||||
|
||||
if first_attr == "namingContexts" {
|
||||
orgs, code := GetFilteredOrganizations(m)
|
||||
if code != ldap.LDAPResultSuccess {
|
||||
res.SetResultCode(code)
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
e := ldap.NewSearchResultEntry(string(r.BaseObject()))
|
||||
dnlist := make([]message.AttributeValue, len(orgs))
|
||||
for i, org := range orgs {
|
||||
dnlist[i] = message.AttributeValue(fmt.Sprintf("ou=%s", org.Name))
|
||||
}
|
||||
e.AddAttribute("namingContexts", dnlist...)
|
||||
w.Write(e)
|
||||
} else if first_attr == "subschemaSubentry" {
|
||||
e := ldap.NewSearchResultEntry(string(r.BaseObject()))
|
||||
e.AddAttribute("subschemaSubentry", message.AttributeValue("cn=Subschema"))
|
||||
w.Write(e)
|
||||
}
|
||||
} else if strings.EqualFold(first_attr, "objectclasses") && string(r.BaseObject()) == "cn=Subschema" {
|
||||
e := ldap.NewSearchResultEntry(string(r.BaseObject()))
|
||||
e.AddAttribute("objectClasses", []message.AttributeValue{
|
||||
"( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC 'Abstraction of an account with POSIX attributes' SUP top AUXILIARY MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ gecos $ description ) )",
|
||||
"( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction of a group of accounts' SUP top STRUCTURAL MUST ( cn $ gidNumber ) MAY ( userPassword $ memberUid $ description ) )",
|
||||
}...)
|
||||
w.Write(e)
|
||||
}
|
||||
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
@ -106,38 +155,72 @@ func handleSearch(w ldap.ResponseWriter, m *ldap.Message) {
|
||||
default:
|
||||
}
|
||||
|
||||
users, code := GetFilteredUsers(m)
|
||||
if code != ldap.LDAPResultSuccess {
|
||||
res.SetResultCode(code)
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
dn := fmt.Sprintf("uid=%s,cn=%s,%s", user.Id, user.Name, string(r.BaseObject()))
|
||||
e := ldap.NewSearchResultEntry(dn)
|
||||
uidNumberStr := fmt.Sprintf("%v", hash(user.Name))
|
||||
e.AddAttribute("uidNumber", message.AttributeValue(uidNumberStr))
|
||||
e.AddAttribute("gidNumber", message.AttributeValue(uidNumberStr))
|
||||
e.AddAttribute("homeDirectory", message.AttributeValue("/home/"+user.Name))
|
||||
e.AddAttribute("cn", message.AttributeValue(user.Name))
|
||||
e.AddAttribute("uid", message.AttributeValue(user.Id))
|
||||
attrs := r.Attributes()
|
||||
for _, attr := range attrs {
|
||||
if string(attr) == "*" {
|
||||
attrs = AdditionalLdapAttributes
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, attr := range attrs {
|
||||
e.AddAttribute(message.AttributeDescription(attr), getAttribute(string(attr), user))
|
||||
if string(attr) == "cn" {
|
||||
e.AddAttribute(message.AttributeDescription(attr), getAttribute("title", user))
|
||||
}
|
||||
objectClass := searchFilterForEquality(r.Filter(), "objectClass", "posixAccount", "posixGroup")
|
||||
switch objectClass {
|
||||
case "posixAccount":
|
||||
users, code := GetFilteredUsers(m)
|
||||
if code != ldap.LDAPResultSuccess {
|
||||
res.SetResultCode(code)
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(e)
|
||||
// log.Printf("Handling posixAccount filter=%s", r.FilterString())
|
||||
for _, user := range users {
|
||||
dn := fmt.Sprintf("uid=%s,cn=users,%s", user.Name, string(r.BaseObject()))
|
||||
e := ldap.NewSearchResultEntry(dn)
|
||||
attrs := r.Attributes()
|
||||
for _, attr := range attrs {
|
||||
if string(attr) == "*" {
|
||||
attrs = AdditionalLdapUserAttributes
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, attr := range attrs {
|
||||
if strings.HasSuffix(string(attr), ";binary") {
|
||||
// unsupported: userCertificate;binary
|
||||
continue
|
||||
}
|
||||
field, ok := ldapUserAttributesMapping.CaseInsensitiveGet(string(attr))
|
||||
if ok {
|
||||
e.AddAttribute(message.AttributeDescription(attr), field.GetAttributeValues(user)...)
|
||||
}
|
||||
}
|
||||
w.Write(e)
|
||||
}
|
||||
|
||||
case "posixGroup":
|
||||
// log.Printf("Handling posixGroup filter=%s", r.FilterString())
|
||||
groups, code := GetFilteredGroups(m)
|
||||
if code != ldap.LDAPResultSuccess {
|
||||
res.SetResultCode(code)
|
||||
w.Write(res)
|
||||
return
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
dn := fmt.Sprintf("cn=%s,cn=groups,%s", group.Name, string(r.BaseObject()))
|
||||
e := ldap.NewSearchResultEntry(dn)
|
||||
attrs := r.Attributes()
|
||||
for _, attr := range attrs {
|
||||
if string(attr) == "*" {
|
||||
attrs = AdditionalLdapGroupAttributes
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, attr := range attrs {
|
||||
field, ok := ldapGroupAttributesMapping.CaseInsensitiveGet(string(attr))
|
||||
if ok {
|
||||
e.AddAttribute(message.AttributeDescription(attr), field.GetAttributeValues(group)...)
|
||||
}
|
||||
}
|
||||
w.Write(e)
|
||||
}
|
||||
|
||||
case "":
|
||||
log.Printf("Unmatched search request. filter=%s", r.FilterString())
|
||||
}
|
||||
|
||||
w.Write(res)
|
||||
}
|
||||
|
||||
|
364
ldap/util.go
364
ldap/util.go
@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@ -28,65 +29,259 @@ import (
|
||||
"github.com/xorm-io/builder"
|
||||
)
|
||||
|
||||
type AttributeMapper func(user *object.User) message.AttributeValue
|
||||
type V = message.AttributeValue
|
||||
|
||||
type FieldRelation struct {
|
||||
type UserAttributeMapper func(user *object.User) []V
|
||||
|
||||
type UserFieldRelation struct {
|
||||
userField string
|
||||
ldapField string
|
||||
notSearchable bool
|
||||
hideOnStarOp bool
|
||||
fieldMapper AttributeMapper
|
||||
fieldMapper UserAttributeMapper
|
||||
constantValue []V
|
||||
}
|
||||
|
||||
func (rel FieldRelation) GetField() (string, error) {
|
||||
func (rel UserFieldRelation) GetField() (string, error) {
|
||||
if rel.notSearchable {
|
||||
return "", fmt.Errorf("attribute %s not supported", rel.userField)
|
||||
}
|
||||
return rel.userField, nil
|
||||
}
|
||||
|
||||
func (rel FieldRelation) GetAttributeValue(user *object.User) message.AttributeValue {
|
||||
func (rel UserFieldRelation) GetAttributeValues(user *object.User) []V {
|
||||
if rel.constantValue != nil && rel.fieldMapper == nil {
|
||||
return rel.constantValue
|
||||
}
|
||||
return rel.fieldMapper(user)
|
||||
}
|
||||
|
||||
var ldapAttributesMapping = map[string]FieldRelation{
|
||||
"cn": {userField: "name", hideOnStarOp: true, fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(user.Name)
|
||||
}},
|
||||
"uid": {userField: "name", hideOnStarOp: true, fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(user.Name)
|
||||
}},
|
||||
"displayname": {userField: "displayName", fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(user.DisplayName)
|
||||
}},
|
||||
"email": {userField: "email", fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(user.Email)
|
||||
}},
|
||||
"mail": {userField: "email", fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(user.Email)
|
||||
}},
|
||||
"mobile": {userField: "phone", fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(user.Phone)
|
||||
}},
|
||||
"title": {userField: "tag", fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(user.Tag)
|
||||
}},
|
||||
"userPassword": {
|
||||
userField: "userPassword",
|
||||
notSearchable: true,
|
||||
fieldMapper: func(user *object.User) message.AttributeValue {
|
||||
return message.AttributeValue(getUserPasswordWithType(user))
|
||||
},
|
||||
},
|
||||
type UserFieldRelationMap map[string]UserFieldRelation
|
||||
|
||||
func (m UserFieldRelationMap) CaseInsensitiveGet(key string) (UserFieldRelation, bool) {
|
||||
lowerKey := strings.ToLower(key)
|
||||
ret, ok := m[lowerKey]
|
||||
return ret, ok
|
||||
}
|
||||
|
||||
var AdditionalLdapAttributes []message.LDAPString
|
||||
type GroupAttributeMapper func(group *object.Group) []V
|
||||
|
||||
type GroupFieldRelation struct {
|
||||
groupField string
|
||||
ldapField string
|
||||
notSearchable bool
|
||||
hideOnStarOp bool
|
||||
fieldMapper GroupAttributeMapper
|
||||
constantValue []V
|
||||
}
|
||||
|
||||
func (rel GroupFieldRelation) GetField() (string, error) {
|
||||
if rel.notSearchable {
|
||||
return "", fmt.Errorf("attribute %s not supported", rel.groupField)
|
||||
}
|
||||
return rel.groupField, nil
|
||||
}
|
||||
|
||||
func (rel GroupFieldRelation) GetAttributeValues(group *object.Group) []V {
|
||||
if rel.constantValue != nil && rel.fieldMapper == nil {
|
||||
return rel.constantValue
|
||||
}
|
||||
return rel.fieldMapper(group)
|
||||
}
|
||||
|
||||
type GroupFieldRelationMap map[string]GroupFieldRelation
|
||||
|
||||
func (m GroupFieldRelationMap) CaseInsensitiveGet(key string) (GroupFieldRelation, bool) {
|
||||
lowerKey := strings.ToLower(key)
|
||||
ret, ok := m[lowerKey]
|
||||
return ret, ok
|
||||
}
|
||||
|
||||
var ldapUserAttributesMapping = UserFieldRelationMap{
|
||||
"cn": {ldapField: "cn", userField: "name", hideOnStarOp: true, fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.Name)}
|
||||
}},
|
||||
"uid": {ldapField: "uid", userField: "name", hideOnStarOp: true, fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.Name)}
|
||||
}},
|
||||
"displayname": {ldapField: "displayName", userField: "displayName", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.DisplayName)}
|
||||
}},
|
||||
"email": {ldapField: "email", userField: "email", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.Email)}
|
||||
}},
|
||||
"mail": {ldapField: "mail", userField: "email", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.Email)}
|
||||
}},
|
||||
"mobile": {ldapField: "mobile", userField: "phone", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.Phone)}
|
||||
}},
|
||||
"telephonenumber": {ldapField: "telephoneNumber", userField: "phone", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.Phone)}
|
||||
}},
|
||||
"postaladdress": {ldapField: "postalAddress", userField: "address", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(strings.Join(user.Address, " "))}
|
||||
}},
|
||||
"title": {ldapField: "title", userField: "title", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.Title)}
|
||||
}},
|
||||
"gecos": {ldapField: "gecos", userField: "displayName", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.DisplayName)}
|
||||
}},
|
||||
"description": {ldapField: "description", userField: "displayName", fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(user.DisplayName)}
|
||||
}},
|
||||
"logindisabled": {ldapField: "loginDisabled", userField: "isForbidden", fieldMapper: func(user *object.User) []V {
|
||||
if user.IsForbidden {
|
||||
return []V{V("1")}
|
||||
} else {
|
||||
return []V{V("0")}
|
||||
}
|
||||
}},
|
||||
"userpassword": {
|
||||
ldapField: "userPassword",
|
||||
userField: "userPassword",
|
||||
notSearchable: true,
|
||||
fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(getUserPasswordWithType(user))}
|
||||
},
|
||||
},
|
||||
"uidnumber": {ldapField: "uidNumber", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
return []V{V(fmt.Sprintf("%v", hash(user.Name)))}
|
||||
}},
|
||||
"gidnumber": {ldapField: "gidNumber", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
if len(user.Groups) == 0 {
|
||||
return []V{V("")}
|
||||
}
|
||||
group, err := object.GetGroup(user.Groups[0])
|
||||
if err != nil {
|
||||
log.Printf("gidnumber object.GetGroup error: %s", err)
|
||||
return []V{V("")}
|
||||
}
|
||||
return []V{V(fmt.Sprintf("%v", hash(group.Name)))}
|
||||
}},
|
||||
"homedirectory": {ldapField: "homeDirectory", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
return []V{V("/home/" + user.Name)}
|
||||
}},
|
||||
"loginshell": {ldapField: "loginShell", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
if user.IsForbidden || user.IsDeleted {
|
||||
return []V{V("/sbin/nologin")}
|
||||
} else {
|
||||
return []V{V("/bin/bash")}
|
||||
}
|
||||
}},
|
||||
"shadowlastchange": {ldapField: "shadowLastChange", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
// "this attribute specifies number of days between January 1, 1970, and the date that the password was last modified"
|
||||
updatedTime, err := time.Parse(time.RFC3339, user.UpdatedTime)
|
||||
if err != nil {
|
||||
log.Printf("shadowlastchange time.Parse error: %s", err)
|
||||
updatedTime = time.Now()
|
||||
}
|
||||
return []V{V(fmt.Sprint(updatedTime.Unix() / 86400))}
|
||||
}},
|
||||
"pwdchangedtime": {ldapField: "pwdChangedTime", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
updatedTime, err := time.Parse(time.RFC3339, user.UpdatedTime)
|
||||
if err != nil {
|
||||
log.Printf("pwdchangedtime time.Parse error: %s", err)
|
||||
updatedTime = time.Now()
|
||||
}
|
||||
return []V{V(updatedTime.UTC().Format("20060102030405Z"))}
|
||||
}},
|
||||
"shadowmin": {ldapField: "shadowMin", notSearchable: true, constantValue: []V{V("0")}},
|
||||
"shadowmax": {ldapField: "shadowMax", notSearchable: true, constantValue: []V{V("99999")}},
|
||||
"shadowwarning": {ldapField: "shadowWarning", notSearchable: true, constantValue: []V{V("7")}},
|
||||
"shadowexpire": {ldapField: "shadowExpire", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
if user.IsForbidden {
|
||||
return []V{V("1")}
|
||||
} else {
|
||||
return []V{V("-1")}
|
||||
}
|
||||
}},
|
||||
"shadowinactive": {ldapField: "shadowInactive", notSearchable: true, constantValue: []V{V("0")}},
|
||||
"shadowflag": {ldapField: "shadowFlag", notSearchable: true, constantValue: []V{V("0")}},
|
||||
"memberof": {ldapField: "memberOf", notSearchable: true, fieldMapper: func(user *object.User) []V {
|
||||
var groupdn []V
|
||||
for _, groupId := range user.Groups {
|
||||
group, err := object.GetGroup(groupId)
|
||||
if err != nil {
|
||||
log.Printf("memberOf object.GetGroup error: %s", err)
|
||||
continue
|
||||
}
|
||||
groupdn = append(groupdn, V(fmt.Sprintf("cn=%s,cn=groups,ou=%s", group.Name, group.Owner)))
|
||||
}
|
||||
return groupdn
|
||||
}},
|
||||
"objectclass": {ldapField: "objectClass", notSearchable: true, constantValue: []V{
|
||||
V("top"),
|
||||
V("posixAccount"),
|
||||
V("shadowAccount"),
|
||||
V("person"),
|
||||
V("organizationalPerson"),
|
||||
V("inetOrgPerson"),
|
||||
V("apple-user"),
|
||||
V("sambaSamAccount"),
|
||||
V("sambaIdmapEntry"),
|
||||
V("extensibleObject"),
|
||||
}},
|
||||
}
|
||||
|
||||
var ldapGroupAttributesMapping = GroupFieldRelationMap{
|
||||
"cn": {ldapField: "cn", hideOnStarOp: true, fieldMapper: func(group *object.Group) []V {
|
||||
return []V{V(group.Name)}
|
||||
}},
|
||||
"gidnumber": {ldapField: "gidNumber", hideOnStarOp: true, fieldMapper: func(group *object.Group) []V {
|
||||
return []V{V(fmt.Sprintf("%v", hash(group.Name)))}
|
||||
}},
|
||||
"member": {ldapField: "member", fieldMapper: func(group *object.Group) []V {
|
||||
users, err := object.GetGroupUsers(group.GetId())
|
||||
if err != nil {
|
||||
log.Printf("member object.GetGroupUsers error: %s", err)
|
||||
return []V{V("")}
|
||||
}
|
||||
var members []V
|
||||
for _, user := range users {
|
||||
members = append(members, V(fmt.Sprintf("uid=%s,cn=users,ou=%s", user.Name, user.Owner)))
|
||||
}
|
||||
return members
|
||||
}},
|
||||
"memberuid": {ldapField: "memberUid", fieldMapper: func(group *object.Group) []V {
|
||||
users, err := object.GetGroupUsers(group.GetId())
|
||||
if err != nil {
|
||||
log.Printf("member object.GetGroupUsers error: %s", err)
|
||||
return []V{V("")}
|
||||
}
|
||||
var members []message.AttributeValue
|
||||
for _, user := range users {
|
||||
members = append(members, message.AttributeValue(user.Name))
|
||||
}
|
||||
return members
|
||||
}},
|
||||
"description": {ldapField: "description", hideOnStarOp: true, fieldMapper: func(group *object.Group) []V {
|
||||
return []V{V(group.DisplayName)}
|
||||
}},
|
||||
"objectclass": {ldapField: "objectClass", hideOnStarOp: true, constantValue: []V{
|
||||
V("top"),
|
||||
V("posixGroup"),
|
||||
}},
|
||||
}
|
||||
|
||||
var (
|
||||
AdditionalLdapUserAttributes []message.LDAPString
|
||||
AdditionalLdapGroupAttributes []message.LDAPString
|
||||
)
|
||||
|
||||
func init() {
|
||||
for k, v := range ldapAttributesMapping {
|
||||
for _, v := range ldapUserAttributesMapping {
|
||||
if v.hideOnStarOp {
|
||||
continue
|
||||
}
|
||||
AdditionalLdapAttributes = append(AdditionalLdapAttributes, message.LDAPString(k))
|
||||
AdditionalLdapUserAttributes = append(AdditionalLdapUserAttributes, message.LDAPString(v.ldapField))
|
||||
}
|
||||
for _, v := range ldapGroupAttributesMapping {
|
||||
if v.hideOnStarOp {
|
||||
continue
|
||||
}
|
||||
AdditionalLdapGroupAttributes = append(AdditionalLdapGroupAttributes, message.LDAPString(v.ldapField))
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,6 +502,52 @@ func GetFilteredUsers(m *ldap.Message) (filteredUsers []*object.User, code int)
|
||||
}
|
||||
}
|
||||
|
||||
func GetFilteredOrganizations(m *ldap.Message) ([]*object.Organization, int) {
|
||||
if m.Client.IsGlobalAdmin {
|
||||
organizations, err := object.GetOrganizations("")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return organizations, ldap.LDAPResultSuccess
|
||||
} else if m.Client.IsOrgAdmin {
|
||||
requestUserId := util.GetId(m.Client.OrgName, m.Client.UserName)
|
||||
user, err := object.GetUser(requestUserId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
organization, err := object.GetOrganizationByUser(user)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return []*object.Organization{organization}, ldap.LDAPResultSuccess
|
||||
} else {
|
||||
return nil, ldap.LDAPResultInsufficientAccessRights
|
||||
}
|
||||
}
|
||||
|
||||
func GetFilteredGroups(m *ldap.Message) ([]*object.Group, int) {
|
||||
if m.Client.IsGlobalAdmin {
|
||||
groups, err := object.GetGroups("")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return groups, ldap.LDAPResultSuccess
|
||||
} else if m.Client.IsOrgAdmin {
|
||||
requestUserId := util.GetId(m.Client.OrgName, m.Client.UserName)
|
||||
user, err := object.GetUser(requestUserId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
groups, err := object.GetGroups(user.Owner)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return groups, ldap.LDAPResultSuccess
|
||||
} else {
|
||||
return nil, ldap.LDAPResultInsufficientAccessRights
|
||||
}
|
||||
}
|
||||
|
||||
// get user password with hash type prefix
|
||||
// TODO not handle salt yet
|
||||
// @return {md5}5f4dcc3b5aa765d61d8327deb882cf99
|
||||
@ -330,18 +571,49 @@ func getUserPasswordWithType(user *object.User) string {
|
||||
return fmt.Sprintf("{%s}%s", prefix, user.Password)
|
||||
}
|
||||
|
||||
func getAttribute(attributeName string, user *object.User) message.AttributeValue {
|
||||
v, ok := ldapAttributesMapping[attributeName]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return v.GetAttributeValue(user)
|
||||
}
|
||||
|
||||
func getUserFieldFromAttribute(attributeName string) (string, error) {
|
||||
v, ok := ldapAttributesMapping[attributeName]
|
||||
v, ok := ldapUserAttributesMapping.CaseInsensitiveGet(attributeName)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("attribute %s not supported", attributeName)
|
||||
}
|
||||
return v.GetField()
|
||||
}
|
||||
|
||||
func searchFilterForEquality(filter message.Filter, desc string, values ...string) string {
|
||||
switch f := filter.(type) {
|
||||
case message.FilterAnd:
|
||||
for _, child := range f {
|
||||
if val := searchFilterForEquality(child, desc, values...); val != "" {
|
||||
return val
|
||||
}
|
||||
}
|
||||
case message.FilterOr:
|
||||
for _, child := range f {
|
||||
if val := searchFilterForEquality(child, desc, values...); val != "" {
|
||||
return val
|
||||
}
|
||||
}
|
||||
case message.FilterNot:
|
||||
return searchFilterForEquality(f.Filter, desc, values...)
|
||||
case message.FilterSubstrings:
|
||||
// Handle FilterSubstrings case if needed
|
||||
case message.FilterEqualityMatch:
|
||||
if strings.EqualFold(string(f.AttributeDesc()), desc) {
|
||||
for _, value := range values {
|
||||
if val := string(f.AssertionValue()); val == value {
|
||||
return val
|
||||
}
|
||||
}
|
||||
}
|
||||
case message.FilterGreaterOrEqual:
|
||||
// Handle FilterGreaterOrEqual case if needed
|
||||
case message.FilterLessOrEqual:
|
||||
// Handle FilterLessOrEqual case if needed
|
||||
case message.FilterPresent:
|
||||
// Handle FilterPresent case if needed
|
||||
case message.FilterApproxMatch:
|
||||
// Handle FilterApproxMatch case if needed
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
@ -1,24 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: casdoor-helm-charts
|
||||
description: A Helm chart for Kubernetes
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.3.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "1.18.0"
|
@ -1,22 +0,0 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "casdoor.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "casdoor.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "casdoor.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "casdoor.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
@ -1,62 +0,0 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "casdoor.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "casdoor.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "casdoor.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "casdoor.labels" -}}
|
||||
helm.sh/chart: {{ include "casdoor.chart" . }}
|
||||
{{ include "casdoor.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "casdoor.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "casdoor.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "casdoor.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "casdoor.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
@ -1,8 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ printf "%s-config" (include "casdoor.fullname" .) }}
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
data:
|
||||
app.conf: {{ tpl .Values.config . | toYaml | nindent 4 }}
|
@ -1,86 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "casdoor.fullname" . }}
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "casdoor.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: {{ tpl .Values.config . | toYaml | sha256sum }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "casdoor.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "casdoor.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}/{{ .Values.image.name }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
# command: ["sleep", "100000000"]
|
||||
env:
|
||||
- name: RUNNING_IN_DOCKER
|
||||
value: "true"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
{{ if .Values.probe.liveness.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
{{ end }}
|
||||
{{ if .Values.probe.readiness.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
{{ end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config-volume
|
||||
mountPath: /conf
|
||||
{{ if .Values.extraContainersEnabled }}
|
||||
{{- .Values.extraContainers | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: config-volume
|
||||
projected:
|
||||
defaultMode: 420
|
||||
sources:
|
||||
- configMap:
|
||||
items:
|
||||
- key: app.conf
|
||||
path: app.conf
|
||||
name: {{ printf "%s-config" (include "casdoor.fullname" .) }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
@ -1,28 +0,0 @@
|
||||
{{- if .Values.autoscaling.enabled }}
|
||||
apiVersion: autoscaling/v2beta1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "casdoor.fullname" . }}
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "casdoor.fullname" . }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- end }}
|
@ -1,61 +0,0 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "casdoor.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "casdoor.fullname" . }}
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "casdoor.selectorLabels" . | nindent 4 }}
|
@ -1,12 +0,0 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "casdoor.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
@ -1,15 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "casdoor.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "casdoor.fullname" . }}:{{ .Values.service.port }}']
|
||||
restartPolicy: Never
|
@ -1,117 +0,0 @@
|
||||
# Default values for casdoor.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: casbin
|
||||
name: casdoor
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
||||
# ref: https://casdoor.org/docs/basic/server-installation#via-ini-file
|
||||
config: |
|
||||
appname = casdoor
|
||||
httpport = {{ .Values.service.port }}
|
||||
runmode = dev
|
||||
SessionOn = true
|
||||
copyrequestbody = true
|
||||
driverName = sqlite
|
||||
dataSourceName = "file:ent?mode=memory&cache=shared&_fk=1"
|
||||
dbName = casdoor
|
||||
redisEndpoint =
|
||||
defaultStorageProvider =
|
||||
isCloudIntranet = false
|
||||
authState = "casdoor"
|
||||
socks5Proxy = ""
|
||||
verificationCodeTimeout = 10
|
||||
initScore = 0
|
||||
logPostOnly = true
|
||||
origin =
|
||||
enableGzip = true
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
probe:
|
||||
readiness:
|
||||
enabled: true
|
||||
liveness:
|
||||
enabled: true
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8000
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
# -- Optionally add extra sidecar containers.
|
||||
extraContainersEnabled: false
|
||||
extraContainers: ""
|
||||
# extraContainers: |
|
||||
# - name: ...
|
||||
# image: ...
|
@ -37,12 +37,13 @@ type SignupItem struct {
|
||||
Prompted bool `json:"prompted"`
|
||||
Label string `json:"label"`
|
||||
Placeholder string `json:"placeholder"`
|
||||
Regex string `json:"regex"`
|
||||
Rule string `json:"rule"`
|
||||
}
|
||||
|
||||
type SamlItem struct {
|
||||
Name string `json:"name"`
|
||||
NameFormat string `json:"nameformat"`
|
||||
NameFormat string `json:"nameFormat"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
@ -82,6 +83,7 @@ type Application struct {
|
||||
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
|
||||
RedirectUris []string `xorm:"varchar(1000)" json:"redirectUris"`
|
||||
TokenFormat string `xorm:"varchar(100)" json:"tokenFormat"`
|
||||
TokenFields []string `xorm:"varchar(1000)" json:"tokenFields"`
|
||||
ExpireInHours int `json:"expireInHours"`
|
||||
RefreshExpireInHours int `json:"refreshExpireInHours"`
|
||||
SignupUrl string `xorm:"varchar(200)" json:"signupUrl"`
|
||||
@ -99,7 +101,7 @@ type Application struct {
|
||||
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
|
||||
|
||||
FailedSigninLimit int `json:"failedSigninLimit"`
|
||||
FailedSigninfrozenTime int `json:"failedSigninfrozenTime"`
|
||||
FailedSigninFrozenTime int `json:"failedSigninFrozenTime"`
|
||||
}
|
||||
|
||||
func GetApplicationCount(owner, field, value string) (int64, error) {
|
||||
@ -201,7 +203,7 @@ func extendApplicationWithOrg(application *Application) (err error) {
|
||||
func extendApplicationWithSigninMethods(application *Application) (err error) {
|
||||
if len(application.SigninMethods) == 0 {
|
||||
if application.EnablePassword {
|
||||
signinMethod := &SigninMethod{Name: "Password", DisplayName: "Password", Rule: "None"}
|
||||
signinMethod := &SigninMethod{Name: "Password", DisplayName: "Password", Rule: "All"}
|
||||
application.SigninMethods = append(application.SigninMethods, signinMethod)
|
||||
}
|
||||
if application.EnableCodeSignin {
|
||||
@ -214,6 +216,11 @@ func extendApplicationWithSigninMethods(application *Application) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(application.SigninMethods) == 0 {
|
||||
signinMethod := &SigninMethod{Name: "Password", DisplayName: "Password", Rule: "All"}
|
||||
application.SigninMethods = append(application.SigninMethods, signinMethod)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -341,6 +348,17 @@ func GetMaskedApplication(application *Application, userId string) *Application
|
||||
return nil
|
||||
}
|
||||
|
||||
if application.TokenFields == nil {
|
||||
application.TokenFields = []string{}
|
||||
}
|
||||
|
||||
if application.FailedSigninLimit == 0 {
|
||||
application.FailedSigninLimit = DefaultFailedSigninLimit
|
||||
}
|
||||
if application.FailedSigninFrozenTime == 0 {
|
||||
application.FailedSigninFrozenTime = DefaultFailedSigninFrozenTime
|
||||
}
|
||||
|
||||
if userId != "" {
|
||||
if isUserIdGlobalAdmin(userId) {
|
||||
return application
|
||||
@ -539,6 +557,19 @@ func (application *Application) IsPasswordEnabled() bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (application *Application) IsPasswordWithLdapEnabled() bool {
|
||||
if len(application.SigninMethods) == 0 {
|
||||
return application.EnablePassword
|
||||
} else {
|
||||
for _, signinMethod := range application.SigninMethods {
|
||||
if signinMethod.Name == "Password" && signinMethod.Rule == "All" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (application *Application) IsCodeSigninViaEmailEnabled() bool {
|
||||
if len(application.SigninMethods) == 0 {
|
||||
return application.EnableCodeSignin
|
||||
@ -565,6 +596,17 @@ func (application *Application) IsCodeSigninViaSmsEnabled() bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (application *Application) IsLdapEnabled() bool {
|
||||
if len(application.SigninMethods) > 0 {
|
||||
for _, signinMethod := range application.SigninMethods {
|
||||
if signinMethod.Name == "LDAP" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsOriginAllowed(origin string) (bool, error) {
|
||||
applications, err := GetApplications("")
|
||||
if err != nil {
|
||||
@ -659,7 +701,7 @@ func applicationChangeTrigger(oldName string, newName string) error {
|
||||
}
|
||||
}
|
||||
permissions[i].Resources = permissionResoureces
|
||||
_, err = session.Where("name=?", permissions[i].Name).Update(permissions[i])
|
||||
_, err = session.Where("owner=?", permissions[i].Owner).Where("name=?", permissions[i].Name).Update(permissions[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -28,9 +28,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultFailedSigninLimit = 5
|
||||
// DefaultFailedSigninfrozenTime The unit of frozen time is minutes
|
||||
DefaultFailedSigninfrozenTime = 15
|
||||
DefaultFailedSigninLimit = 5
|
||||
DefaultFailedSigninFrozenTime = 15
|
||||
)
|
||||
|
||||
func CheckUserSignup(application *Application, organization *Organization, form *form.AuthForm, lang string) string {
|
||||
@ -144,7 +143,7 @@ func CheckUserSignup(application *Application, organization *Organization, form
|
||||
}
|
||||
|
||||
func checkSigninErrorTimes(user *User, lang string) error {
|
||||
failedSigninLimit, failedSigninfrozenTime, err := GetFailedSigninConfigByUser(user)
|
||||
failedSigninLimit, failedSigninFrozenTime, err := GetFailedSigninConfigByUser(user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -152,7 +151,7 @@ func checkSigninErrorTimes(user *User, lang string) error {
|
||||
if user.SigninWrongTimes >= failedSigninLimit {
|
||||
lastSignWrongTime, _ := time.Parse(time.RFC3339, user.LastSigninWrongTime)
|
||||
passedTime := time.Now().UTC().Sub(lastSignWrongTime)
|
||||
minutes := failedSigninfrozenTime - int(passedTime.Minutes())
|
||||
minutes := failedSigninFrozenTime - int(passedTime.Minutes())
|
||||
|
||||
// deny the login if the error times is greater than the limit and the last login time is less than the duration
|
||||
if minutes > 0 {
|
||||
@ -278,8 +277,12 @@ func checkLdapUserPassword(user *User, password string, lang string) error {
|
||||
|
||||
func CheckUserPassword(organization string, username string, password string, lang string, options ...bool) (*User, error) {
|
||||
enableCaptcha := false
|
||||
isSigninViaLdap := false
|
||||
isPasswordWithLdapEnabled := false
|
||||
if len(options) > 0 {
|
||||
enableCaptcha = options[0]
|
||||
isSigninViaLdap = options[1]
|
||||
isPasswordWithLdapEnabled = options[2]
|
||||
}
|
||||
user, err := GetUserByFields(organization, username)
|
||||
if err != nil {
|
||||
@ -294,14 +297,33 @@ func CheckUserPassword(organization string, username string, password string, la
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "check:The user is forbidden to sign in, please contact the administrator"))
|
||||
}
|
||||
|
||||
if isSigninViaLdap {
|
||||
if user.Ldap == "" {
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "check:The user: %s doesn't exist in LDAP server"), username)
|
||||
}
|
||||
}
|
||||
|
||||
if user.Ldap != "" {
|
||||
if !isSigninViaLdap && !isPasswordWithLdapEnabled {
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "check:password or code is incorrect"))
|
||||
}
|
||||
|
||||
// check the login error times
|
||||
if !enableCaptcha {
|
||||
err = checkSigninErrorTimes(user, lang)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// only for LDAP users
|
||||
err = checkLdapUserPassword(user, password, lang)
|
||||
if err != nil {
|
||||
if err.Error() == "user not exist" {
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "check:The user: %s doesn't exist in LDAP server"), username)
|
||||
}
|
||||
return nil, err
|
||||
|
||||
return nil, recordSigninErrorInfo(user, lang, enableCaptcha)
|
||||
}
|
||||
} else {
|
||||
err = CheckPassword(user, password, lang, enableCaptcha)
|
||||
@ -486,12 +508,11 @@ func CheckToEnableCaptcha(application *Application, organization, username strin
|
||||
return false, err
|
||||
}
|
||||
|
||||
var failedSigninLimit int
|
||||
if application.FailedSigninLimit == 0 {
|
||||
failedSigninLimit = 5
|
||||
} else {
|
||||
failedSigninLimit = application.FailedSigninLimit
|
||||
failedSigninLimit := application.FailedSigninLimit
|
||||
if failedSigninLimit == 0 {
|
||||
failedSigninLimit = DefaultFailedSigninLimit
|
||||
}
|
||||
|
||||
return user != nil && user.SigninWrongTimes >= failedSigninLimit, nil
|
||||
}
|
||||
return providerItem.Rule == "Always", nil
|
||||
|
@ -52,18 +52,18 @@ func GetFailedSigninConfigByUser(user *User) (int, int, error) {
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
failedSigninLimit := application.FailedSigninLimit
|
||||
failedSigninfrozenTime := application.FailedSigninfrozenTime
|
||||
|
||||
// 0 as an initialization value, corresponding to the default configuration parameters
|
||||
failedSigninLimit := application.FailedSigninLimit
|
||||
if failedSigninLimit == 0 {
|
||||
failedSigninLimit = DefaultFailedSigninLimit
|
||||
}
|
||||
if failedSigninfrozenTime == 0 {
|
||||
failedSigninfrozenTime = DefaultFailedSigninfrozenTime
|
||||
|
||||
failedSigninFrozenTime := application.FailedSigninFrozenTime
|
||||
if failedSigninFrozenTime == 0 {
|
||||
failedSigninFrozenTime = DefaultFailedSigninFrozenTime
|
||||
}
|
||||
|
||||
return failedSigninLimit, failedSigninfrozenTime, nil
|
||||
return failedSigninLimit, failedSigninFrozenTime, nil
|
||||
}
|
||||
|
||||
func recordSigninErrorInfo(user *User, lang string, options ...bool) error {
|
||||
@ -72,7 +72,7 @@ func recordSigninErrorInfo(user *User, lang string, options ...bool) error {
|
||||
enableCaptcha = options[0]
|
||||
}
|
||||
|
||||
failedSigninLimit, failedSigninfrozenTime, errSignin := GetFailedSigninConfigByUser(user)
|
||||
failedSigninLimit, failedSigninFrozenTime, errSignin := GetFailedSigninConfigByUser(user)
|
||||
if errSignin != nil {
|
||||
return errSignin
|
||||
}
|
||||
@ -101,5 +101,5 @@ func recordSigninErrorInfo(user *User, lang string, options ...bool) error {
|
||||
}
|
||||
|
||||
// don't show the chance error message if the user has no chance left
|
||||
return fmt.Errorf(i18n.Translate(lang, "check:You have entered the wrong password or code too many times, please wait for %d minutes and try again"), failedSigninfrozenTime)
|
||||
return fmt.Errorf(i18n.Translate(lang, "check:You have entered the wrong password or code too many times, please wait for %d minutes and try again"), failedSigninFrozenTime)
|
||||
}
|
||||
|
@ -242,7 +242,8 @@ func GetPaginationGroupUsers(groupId string, offset, limit int, field, value, so
|
||||
}
|
||||
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
session := ormer.Engine.Table(tableNamePrefix+"user").
|
||||
prefixedUserTable := tableNamePrefix + "user"
|
||||
session := ormer.Engine.Table(prefixedUserTable).
|
||||
Where("owner = ?", owner).In("name", names)
|
||||
|
||||
if offset != -1 && limit != -1 {
|
||||
@ -250,16 +251,19 @@ func GetPaginationGroupUsers(groupId string, offset, limit int, field, value, so
|
||||
}
|
||||
|
||||
if field != "" && value != "" {
|
||||
session = session.And(fmt.Sprintf("user.%s like ?", util.CamelToSnakeCase(field)), "%"+value+"%")
|
||||
session = session.And(fmt.Sprintf("%s.%s like ?", prefixedUserTable, util.CamelToSnakeCase(field)), "%"+value+"%")
|
||||
}
|
||||
|
||||
if sortField == "" || sortOrder == "" {
|
||||
sortField = "created_time"
|
||||
}
|
||||
|
||||
orderQuery := fmt.Sprintf("%s.%s", prefixedUserTable, util.SnakeString(sortField))
|
||||
|
||||
if sortOrder == "ascend" {
|
||||
session = session.Asc(fmt.Sprintf("user.%s", util.SnakeString(sortField)))
|
||||
session = session.Asc(orderQuery)
|
||||
} else {
|
||||
session = session.Desc(fmt.Sprintf("user.%s", util.SnakeString(sortField)))
|
||||
session = session.Desc(orderQuery)
|
||||
}
|
||||
|
||||
err = session.Find(&users)
|
||||
|
@ -197,6 +197,7 @@ func initBuiltInApplication() {
|
||||
},
|
||||
Tags: []string{},
|
||||
RedirectUris: []string{},
|
||||
TokenFields: []string{},
|
||||
ExpireInHours: 168,
|
||||
FormOffset: 2,
|
||||
}
|
||||
|
@ -145,11 +145,14 @@ func readInitDataFromFile(filePath string) (*InitData, error) {
|
||||
if application.GrantTypes == nil {
|
||||
application.GrantTypes = []string{}
|
||||
}
|
||||
if application.Tags == nil {
|
||||
application.Tags = []string{}
|
||||
}
|
||||
if application.RedirectUris == nil {
|
||||
application.RedirectUris = []string{}
|
||||
}
|
||||
if application.Tags == nil {
|
||||
application.Tags = []string{}
|
||||
if application.TokenFields == nil {
|
||||
application.TokenFields = []string{}
|
||||
}
|
||||
}
|
||||
for _, permission := range data.Permissions {
|
||||
|
@ -36,16 +36,14 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ormer *Ormer = nil
|
||||
isCreateDatabaseDefined = false
|
||||
createDatabase = true
|
||||
ormer *Ormer = nil
|
||||
createDatabase = true
|
||||
configPath = "conf/app.conf"
|
||||
)
|
||||
|
||||
func InitFlag() {
|
||||
if !isCreateDatabaseDefined {
|
||||
isCreateDatabaseDefined = true
|
||||
createDatabase = getCreateDatabaseFlag()
|
||||
}
|
||||
createDatabase = getCreateDatabaseFlag()
|
||||
configPath = getConfigFlag()
|
||||
}
|
||||
|
||||
func getCreateDatabaseFlag() bool {
|
||||
@ -54,6 +52,12 @@ func getCreateDatabaseFlag() bool {
|
||||
return *res
|
||||
}
|
||||
|
||||
func getConfigFlag() string {
|
||||
res := flag.String("config", "conf/app.conf", "set it to \"/your/path/app.conf\" if your config file is not in: \"/conf/app.conf\"")
|
||||
flag.Parse()
|
||||
return *res
|
||||
}
|
||||
|
||||
func InitConfig() {
|
||||
err := beego.LoadAppConfig("ini", "../conf/app.conf")
|
||||
if err != nil {
|
||||
@ -68,7 +72,7 @@ func InitConfig() {
|
||||
|
||||
func InitAdapter() {
|
||||
if conf.GetConfigString("driverName") == "" {
|
||||
if !util.FileExist("conf/app.conf") {
|
||||
if !util.FileExist(configPath) {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -308,7 +308,7 @@ func BatchEnforce(permission *Permission, requests [][]string, permissionIds ...
|
||||
return enforcer.BatchEnforce(interfaceRequests)
|
||||
}
|
||||
|
||||
func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) ([]string, error) {
|
||||
func getEnforcers(userId string) ([]*casbin.Enforcer, error) {
|
||||
permissions, _, err := getPermissionsAndRolesByUser(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -320,7 +320,8 @@ func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) ([
|
||||
}
|
||||
|
||||
for _, role := range allRoles {
|
||||
permissionsByRole, err := GetPermissionsByRole(role)
|
||||
var permissionsByRole []*Permission
|
||||
permissionsByRole, err = GetPermissionsByRole(role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -328,29 +329,45 @@ func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) ([
|
||||
permissions = append(permissions, permissionsByRole...)
|
||||
}
|
||||
|
||||
var values []string
|
||||
var enforcers []*casbin.Enforcer
|
||||
for _, permission := range permissions {
|
||||
enforcer, err := getPermissionEnforcer(permission)
|
||||
var enforcer *casbin.Enforcer
|
||||
enforcer, err = getPermissionEnforcer(permission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
values = append(values, fn(enforcer)...)
|
||||
enforcers = append(enforcers, enforcer)
|
||||
}
|
||||
|
||||
return values, nil
|
||||
return enforcers, nil
|
||||
}
|
||||
|
||||
func GetAllObjects(userId string) ([]string, error) {
|
||||
return getAllValues(userId, func(enforcer *casbin.Enforcer) []string {
|
||||
return enforcer.GetAllObjects()
|
||||
})
|
||||
enforcers, err := getEnforcers(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := []string{}
|
||||
for _, enforcer := range enforcers {
|
||||
items := enforcer.GetAllObjects()
|
||||
res = append(res, items...)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func GetAllActions(userId string) ([]string, error) {
|
||||
return getAllValues(userId, func(enforcer *casbin.Enforcer) []string {
|
||||
return enforcer.GetAllActions()
|
||||
})
|
||||
enforcers, err := getEnforcers(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := []string{}
|
||||
for _, enforcer := range enforcers {
|
||||
items := enforcer.GetAllObjects()
|
||||
res = append(res, items...)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func GetAllRoles(userId string) ([]string, error) {
|
||||
|
@ -266,10 +266,9 @@ func (role *Role) GetId() string {
|
||||
}
|
||||
|
||||
func getRolesByUserInternal(userId string) ([]*Role, error) {
|
||||
roles := []*Role{}
|
||||
user, err := GetUser(userId)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
return nil, err
|
||||
}
|
||||
if user == nil {
|
||||
return nil, fmt.Errorf("The user: %s doesn't exist", userId)
|
||||
@ -280,9 +279,10 @@ func getRolesByUserInternal(userId string) ([]*Role, error) {
|
||||
query = query.Or("r.groups like ?", fmt.Sprintf("%%%s%%", group))
|
||||
}
|
||||
|
||||
roles := []*Role{}
|
||||
err = query.Find(&roles)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := []*Role{}
|
||||
@ -291,14 +291,13 @@ func getRolesByUserInternal(userId string) ([]*Role, error) {
|
||||
res = append(res, role)
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func getRolesByUser(userId string) ([]*Role, error) {
|
||||
roles, err := getRolesByUserInternal(userId)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
allRolesIds := []string{}
|
||||
@ -379,15 +378,11 @@ func GetMaskedRoles(roles []*Role) []*Role {
|
||||
|
||||
// GetAncestorRoles returns a list of roles that contain the given roleIds
|
||||
func GetAncestorRoles(roleIds ...string) ([]*Role, error) {
|
||||
var (
|
||||
result = []*Role{}
|
||||
roleMap = make(map[string]*Role)
|
||||
visited = make(map[string]bool)
|
||||
)
|
||||
if len(roleIds) == 0 {
|
||||
return result, nil
|
||||
return []*Role{}, nil
|
||||
}
|
||||
|
||||
visited := map[string]bool{}
|
||||
for _, roleId := range roleIds {
|
||||
visited[roleId] = true
|
||||
}
|
||||
@ -399,25 +394,26 @@ func GetAncestorRoles(roleIds ...string) ([]*Role, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roleMap := map[string]*Role{}
|
||||
for _, r := range allRoles {
|
||||
roleMap[r.GetId()] = r
|
||||
}
|
||||
|
||||
// Second, find all the roles that contain father roles
|
||||
// find all the roles that contain father roles
|
||||
res := []*Role{}
|
||||
for _, r := range allRoles {
|
||||
isContain, ok := visited[r.GetId()]
|
||||
if isContain {
|
||||
result = append(result, r)
|
||||
res = append(res, r)
|
||||
} else if !ok {
|
||||
rId := r.GetId()
|
||||
visited[rId] = containsRole(r, roleMap, visited, roleIds...)
|
||||
if visited[rId] {
|
||||
result = append(result, r)
|
||||
res = append(res, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// containsRole is a helper function to check if a roles is related to any role in the given list roles
|
||||
|
@ -54,6 +54,15 @@ func (syncer *Syncer) syncUsers() error {
|
||||
var affiliationMap map[int]string
|
||||
if syncer.AffiliationTable != "" {
|
||||
_, affiliationMap, err = syncer.getAffiliationMap()
|
||||
if err != nil {
|
||||
line := fmt.Sprintf("[%s] %s\n", util.GetCurrentTime(), err.Error())
|
||||
_, err2 := updateSyncerErrorText(syncer, line)
|
||||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
key := syncer.getKey()
|
||||
|
@ -16,6 +16,7 @@ package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@ -270,6 +271,34 @@ func getClaimsWithoutThirdIdp(claims Claims) ClaimsWithoutThirdIdp {
|
||||
return res
|
||||
}
|
||||
|
||||
func getClaimsCustom(claims Claims, tokenField []string) jwt.MapClaims {
|
||||
res := make(jwt.MapClaims)
|
||||
|
||||
userValue := reflect.ValueOf(claims.User).Elem()
|
||||
|
||||
res["iss"] = claims.RegisteredClaims.Issuer
|
||||
res["sub"] = claims.RegisteredClaims.Subject
|
||||
res["aud"] = claims.RegisteredClaims.Audience
|
||||
res["exp"] = claims.RegisteredClaims.ExpiresAt
|
||||
res["nbf"] = claims.RegisteredClaims.NotBefore
|
||||
res["iat"] = claims.RegisteredClaims.IssuedAt
|
||||
res["jti"] = claims.RegisteredClaims.ID
|
||||
res["tokenType"] = claims.TokenType
|
||||
res["nonce"] = claims.Nonce
|
||||
res["tag"] = claims.Tag
|
||||
res["scope"] = claims.Scope
|
||||
|
||||
for _, field := range tokenField {
|
||||
userField := userValue.FieldByName(field)
|
||||
if userField.IsValid() {
|
||||
newfield := util.SnakeToCamel(util.CamelToSnakeCase(field))
|
||||
res[newfield] = userField.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func refineUser(user *User) *User {
|
||||
user.Password = ""
|
||||
|
||||
@ -329,20 +358,30 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
||||
var refreshToken *jwt.Token
|
||||
|
||||
// the JWT token length in "JWT-Empty" mode will be very short, as User object only has two properties: owner and name
|
||||
if application.TokenFormat == "JWT-Empty" {
|
||||
claimsShort := getShortClaims(claims)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsShort)
|
||||
claimsShort.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||
claimsShort.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsShort)
|
||||
} else {
|
||||
if application.TokenFormat == "JWT" {
|
||||
claimsWithoutThirdIdp := getClaimsWithoutThirdIdp(claims)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsWithoutThirdIdp)
|
||||
claimsWithoutThirdIdp.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||
claimsWithoutThirdIdp.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsWithoutThirdIdp)
|
||||
} else if application.TokenFormat == "JWT-Empty" {
|
||||
claimsShort := getShortClaims(claims)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsShort)
|
||||
claimsShort.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||
claimsShort.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsShort)
|
||||
} else if application.TokenFormat == "JWT-Custom" {
|
||||
claimsCustom := getClaimsCustom(claims, application.TokenFields)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsCustom)
|
||||
refreshClaims := getClaimsCustom(claims, application.TokenFields)
|
||||
refreshClaims["exp"] = jwt.NewNumericDate(refreshExpireTime)
|
||||
refreshClaims["TokenType"] = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, refreshClaims)
|
||||
} else {
|
||||
return "", "", "", fmt.Errorf("unknown application TokenFormat: %s", application.TokenFormat)
|
||||
}
|
||||
|
||||
cert, err := getCertByApplication(application)
|
||||
|
@ -867,7 +867,8 @@ func GetUserInfo(user *User, scope string, aud string, host string) *Userinfo {
|
||||
}
|
||||
if strings.Contains(scope, "email") {
|
||||
resp.Email = user.Email
|
||||
resp.EmailVerified = user.EmailVerified
|
||||
// resp.EmailVerified = user.EmailVerified
|
||||
resp.EmailVerified = true
|
||||
}
|
||||
if strings.Contains(scope, "address") {
|
||||
resp.Address = user.Location
|
||||
|
@ -5418,7 +5418,7 @@
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"failedSigninfrozenTime": {
|
||||
"failedSigninFrozenTime": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
@ -6761,7 +6761,7 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"nameformat": {
|
||||
"nameFormat": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
|
@ -3549,7 +3549,7 @@ definitions:
|
||||
failedSigninLimit:
|
||||
type: integer
|
||||
format: int64
|
||||
failedSigninfrozenTime:
|
||||
failedSigninFrozenTime:
|
||||
type: integer
|
||||
format: int64
|
||||
forgetUrl:
|
||||
@ -4451,7 +4451,7 @@ definitions:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
nameformat:
|
||||
nameFormat:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
|
@ -392,7 +392,7 @@ class App extends Component {
|
||||
</div>
|
||||
</Tooltip>
|
||||
<OpenTour />
|
||||
{Setting.isAdminUser(this.state.account) && !Setting.isMobile() &&
|
||||
{Setting.isAdminUser(this.state.account) && !Setting.isMobile() && (this.state.uri.indexOf("/trees") === -1) &&
|
||||
<OrganizationSelect
|
||||
initValue={Setting.getOrganization()}
|
||||
withAll={true}
|
||||
|
@ -27,7 +27,7 @@ import LoginPage from "./auth/LoginPage";
|
||||
import i18next from "i18next";
|
||||
import UrlTable from "./table/UrlTable";
|
||||
import ProviderTable from "./table/ProviderTable";
|
||||
import SigninTable from "./table/SigninTable";
|
||||
import SigninMethodTable from "./table/SigninMethodTable";
|
||||
import SignupTable from "./table/SignupTable";
|
||||
import SamlAttributeTable from "./table/SamlAttributeTable";
|
||||
import PromptPage from "./auth/PromptPage";
|
||||
@ -386,10 +386,22 @@ class ApplicationEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.application.tokenFormat} onChange={(value => {this.updateApplicationField("tokenFormat", value);})}
|
||||
options={["JWT", "JWT-Empty"].map((item) => Setting.getOption(item, item))}
|
||||
options={["JWT", "JWT-Empty", "JWT-Custom"].map((item) => Setting.getOption(item, item))}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("application:Token fields"), i18next.t("application:Token fields - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} disabled={this.state.application.tokenFormat !== "JWT-Custom"} mode="tags" showSearch style={{width: "100%"}} value={this.state.application.tokenFields} onChange={(value => {this.updateApplicationField("tokenFields", value);})}>
|
||||
{
|
||||
Setting.getUserCommonFields().map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("application:Token expire"), i18next.t("application:Token expire - Tooltip"))} :
|
||||
@ -425,8 +437,8 @@ class ApplicationEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("application:Failed signin frozen time"), i18next.t("application:Failed signin frozen time - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<InputNumber style={{width: "150px"}} value={this.state.application.failedSigninfrozenTime} min={1} step={1} precision={0} addonAfter="Minutes" onChange={value => {
|
||||
this.updateApplicationField("failedSigninfrozenTime", value);
|
||||
<InputNumber style={{width: "150px"}} value={this.state.application.failedSigninFrozenTime} min={1} step={1} precision={0} addonAfter="Minutes" onChange={value => {
|
||||
this.updateApplicationField("failedSigninFrozenTime", value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
@ -475,7 +487,7 @@ class ApplicationEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("application:Signin methods"), i18next.t("application:Signin methods - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<SigninTable
|
||||
<SigninMethodTable
|
||||
title={i18next.t("application:Signin methods")}
|
||||
table={this.state.application.signinMethods}
|
||||
onUpdateTable={(value) => {
|
||||
@ -785,7 +797,7 @@ class ApplicationEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Radio.Group onChange={e => {this.updateApplicationField("formOffset", e.target.value);}} value={this.state.application.formOffset}>
|
||||
<Radio.Group buttonStyle="solid" onChange={e => {this.updateApplicationField("formOffset", e.target.value);}} value={this.state.application.formOffset}>
|
||||
<Radio.Button value={1}>{i18next.t("application:Left")}</Radio.Button>
|
||||
<Radio.Button value={2}>{i18next.t("application:Center")}</Radio.Button>
|
||||
<Radio.Button value={3}>{i18next.t("application:Right")}</Radio.Button>
|
||||
@ -825,7 +837,7 @@ class ApplicationEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} style={{marginTop: "5px"}}>
|
||||
<Row>
|
||||
<Radio.Group value={this.state.application.themeData?.isEnabled ?? false} onChange={e => {
|
||||
<Radio.Group buttonStyle="solid" value={this.state.application.themeData?.isEnabled ?? false} onChange={e => {
|
||||
const {_, ...theme} = this.state.application.themeData ?? {...Conf.ThemeDefault, isEnabled: false};
|
||||
this.updateApplicationField("themeData", {...theme, isEnabled: e.target.value});
|
||||
}} >
|
||||
@ -1034,7 +1046,7 @@ class ApplicationEditPage extends React.Component {
|
||||
submitApplicationEdit(exitAfterSave) {
|
||||
const application = Setting.deepCopy(this.state.application);
|
||||
application.providers = application.providers?.filter(provider => this.state.providers.map(provider => provider.name).includes(provider.name));
|
||||
application.signinMethods = application.signinMethods?.filter(signinMethod => ["Password", "Verification code", "WebAuthn"].includes(signinMethod.name));
|
||||
application.signinMethods = application.signinMethods?.filter(signinMethod => ["Password", "Verification code", "WebAuthn", "LDAP"].includes(signinMethod.name));
|
||||
|
||||
ApplicationBackend.updateApplication("admin", this.state.applicationName, application)
|
||||
.then((res) => {
|
||||
|
@ -47,7 +47,7 @@ class ApplicationListPage extends BaseListPage {
|
||||
{name: "provider_captcha_default", canSignUp: false, canSignIn: false, canUnlink: false, prompted: false, signupGroup: "", rule: ""},
|
||||
],
|
||||
SigninMethods: [
|
||||
{name: "Password", displayName: "Password", rule: "None"},
|
||||
{name: "Password", displayName: "Password", rule: "All"},
|
||||
{name: "Verification code", displayName: "Verification code", rule: "All"},
|
||||
{name: "WebAuthn", displayName: "WebAuthn", rule: "None"},
|
||||
],
|
||||
@ -64,6 +64,7 @@ class ApplicationListPage extends BaseListPage {
|
||||
cert: "cert-built-in",
|
||||
redirectUris: ["http://localhost:9000/callback"],
|
||||
tokenFormat: "JWT",
|
||||
tokenFields: [],
|
||||
expireInHours: 24 * 7,
|
||||
refreshExpireInHours: 24 * 7,
|
||||
formOffset: 2,
|
||||
|
@ -25,6 +25,7 @@ class BaseListPage extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
classes: props,
|
||||
organizationName: this.props.match?.params.organizationName || Setting.getRequestOrganization(this.props.account),
|
||||
data: [],
|
||||
pagination: {
|
||||
current: 1,
|
||||
@ -39,6 +40,10 @@ class BaseListPage extends React.Component {
|
||||
}
|
||||
|
||||
handleOrganizationChange = () => {
|
||||
this.setState({
|
||||
organizationName: this.props.match?.params.organizationName || Setting.getRequestOrganization(this.props.account),
|
||||
});
|
||||
|
||||
const {pagination} = this.state;
|
||||
this.fetch({pagination});
|
||||
};
|
||||
|
@ -393,7 +393,7 @@ class OrganizationEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} style={{marginTop: "5px"}}>
|
||||
<Row>
|
||||
<Radio.Group value={this.state.organization.themeData?.isEnabled ?? false} onChange={e => {
|
||||
<Radio.Group buttonStyle="solid" value={this.state.organization.themeData?.isEnabled ?? false} onChange={e => {
|
||||
const {_, ...theme} = this.state.organization.themeData ?? {...Conf.ThemeDefault, isEnabled: false};
|
||||
this.updateOrganizationField("themeData", {...theme, isEnabled: e.target.value});
|
||||
}} >
|
||||
|
@ -1131,28 +1131,28 @@ export function renderLogo(application) {
|
||||
}
|
||||
}
|
||||
|
||||
export function isPasswordEnabled(application) {
|
||||
if (application) {
|
||||
return application.signinMethods.filter(item => item.name === "Password").length > 0;
|
||||
function isSigninMethodEnabled(application, signinMethod) {
|
||||
if (application && application.signinMethods) {
|
||||
return application.signinMethods.filter(item => item.name === signinMethod).length > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isPasswordEnabled(application) {
|
||||
return isSigninMethodEnabled(application, "Password");
|
||||
}
|
||||
|
||||
export function isCodeSigninEnabled(application) {
|
||||
if (application) {
|
||||
return application.signinMethods.filter(item => item.name === "Verification code").length > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return isSigninMethodEnabled(application, "Verification code");
|
||||
}
|
||||
|
||||
export function isWebAuthnEnabled(application) {
|
||||
if (application) {
|
||||
return application.signinMethods.filter(item => item.name === "WebAuthn").length > 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return isSigninMethodEnabled(application, "WebAuthn");
|
||||
}
|
||||
|
||||
export function isLdapEnabled(application) {
|
||||
return isSigninMethodEnabled(application, "LDAP");
|
||||
}
|
||||
|
||||
export function getLoginLink(application) {
|
||||
@ -1442,6 +1442,13 @@ export function getFriendlyUserName(account) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getUserCommonFields() {
|
||||
return ["Owner", "Name", "CreatedTime", "UpdatedTime", "Id", "Type", "Password", "PasswordSalt", "DisplayName", "FirstName", "LastName", "Avatar", "PermanentAvatar",
|
||||
"Email", "EmailVerified", "Phone", "Location", "Address", "Affiliation", "Title", "IdCardType", "IdCard", "Homepage", "Bio", "Tag", "Region",
|
||||
"Language", "Gender", "Birthday", "Education", "Score", "Ranking", "IsDefaultAvatar", "IsOnline", "IsAdmin", "IsForbidden", "IsDeleted", "CreatedIp",
|
||||
"PreferredMfaType", "TotpSecret", "SignupApplication"];
|
||||
}
|
||||
|
||||
export function getDefaultHtmlEmailContent() {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
@ -30,7 +30,6 @@ class UserListPage extends BaseListPage {
|
||||
super(props);
|
||||
this.state = {
|
||||
...this.state,
|
||||
organizationName: this.props.organizationName ?? this.props.match?.params.organizationName ?? this.props.account.owner,
|
||||
organization: null,
|
||||
};
|
||||
}
|
||||
@ -62,7 +61,7 @@ class UserListPage extends BaseListPage {
|
||||
|
||||
newUser() {
|
||||
const randomName = Setting.getRandomName();
|
||||
const owner = Setting.isDefaultOrganizationSelected(this.props.account) ? this.state.organizationName : Setting.getRequestOrganization(this.props.account);
|
||||
const owner = (Setting.isDefaultOrganizationSelected(this.props.account) || this.props.groupName) ? this.state.organizationName : Setting.getRequestOrganization(this.props.account);
|
||||
return {
|
||||
owner: owner,
|
||||
name: `user_${randomName}`,
|
||||
@ -85,7 +84,7 @@ class UserListPage extends BaseListPage {
|
||||
score: this.state.organization.initScore,
|
||||
isDeleted: false,
|
||||
properties: {},
|
||||
signupApplication: "app-built-in",
|
||||
signupApplication: this.state.organization.defaultApplication,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
|
||||
getDefaultLoginMethod(application) {
|
||||
if (application?.signinMethods.length > 0) {
|
||||
if (application?.signinMethods?.length > 0) {
|
||||
switch (application?.signinMethods[0].name) {
|
||||
case "Password": return "password";
|
||||
case "Verification code": {
|
||||
@ -213,6 +213,7 @@ class LoginPage extends React.Component {
|
||||
break;
|
||||
}
|
||||
case "WebAuthn": return "webAuthn";
|
||||
case "LDAP": return "ldap";
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,6 +225,7 @@ class LoginPage extends React.Component {
|
||||
case "verificationCode": return i18next.t("login:Email or phone");
|
||||
case "verificationCodeEmail": return i18next.t("login:Email");
|
||||
case "verificationCodePhone": return i18next.t("login:Phone");
|
||||
case "ldap": return i18next.t("login:LDAP username, Email or phone");
|
||||
default: return i18next.t("login:username, Email or phone");
|
||||
}
|
||||
}
|
||||
@ -253,6 +255,15 @@ class LoginPage extends React.Component {
|
||||
values["organization"] = this.getApplicationObj().organization;
|
||||
}
|
||||
|
||||
if (this.state.loginMethod === "password") {
|
||||
values["signinMethod"] = "Password";
|
||||
} else if (this.state.loginMethod?.includes("verificationCode")) {
|
||||
values["signinMethod"] = "Verification code";
|
||||
} else if (this.state.loginMethod === "webAuthn") {
|
||||
values["signinMethod"] = "WebAuthn";
|
||||
} else if (this.state.loginMethod === "ldap") {
|
||||
values["signinMethod"] = "LDAP";
|
||||
}
|
||||
const oAuthParams = Util.getOAuthGetParameters();
|
||||
|
||||
values["type"] = oAuthParams?.responseType ?? this.state.type;
|
||||
@ -329,7 +340,7 @@ class LoginPage extends React.Component {
|
||||
this.signInWithWebAuthn(username, values);
|
||||
return;
|
||||
}
|
||||
if (this.state.loginMethod === "password") {
|
||||
if (this.state.loginMethod === "password" || this.state.loginMethod === "ldap") {
|
||||
if (this.state.enableCaptchaModal === CaptchaRule.Always) {
|
||||
this.setState({
|
||||
openCaptchaModal: true,
|
||||
@ -468,6 +479,10 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
|
||||
renderOtherFormProvider(application) {
|
||||
if (Setting.inIframe()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const providerConf of application.providers) {
|
||||
if (providerConf.provider?.type === "Google" && providerConf.rule === "OneTap" && this.props.preview !== "auto") {
|
||||
return (
|
||||
@ -475,6 +490,8 @@ class LoginPage extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
renderForm(application) {
|
||||
@ -501,7 +518,7 @@ class LoginPage extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
const showForm = Setting.isPasswordEnabled(application) || Setting.isCodeSigninEnabled(application) || Setting.isWebAuthnEnabled(application);
|
||||
const showForm = Setting.isPasswordEnabled(application) || Setting.isCodeSigninEnabled(application) || Setting.isWebAuthnEnabled(application) || Setting.isLdapEnabled(application);
|
||||
if (showForm) {
|
||||
let loginWidth = 320;
|
||||
if (Setting.getLanguage() === "fr") {
|
||||
@ -564,12 +581,17 @@ class LoginPage extends React.Component {
|
||||
switch (this.state.loginMethod) {
|
||||
case "verificationCodeEmail": return i18next.t("login:Please input your Email!");
|
||||
case "verificationCodePhone": return i18next.t("login:Please input your Phone!");
|
||||
case "ldap": return i18next.t("login:Please input your LDAP username!");
|
||||
default: return i18next.t("login:Please input your Email or Phone!");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (value === "") {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (this.state.loginMethod === "verificationCode") {
|
||||
if (!Setting.isValidEmail(value) && !Setting.isValidPhone(value)) {
|
||||
this.setState({validEmailOrPhone: false});
|
||||
@ -864,7 +886,7 @@ class LoginPage extends React.Component {
|
||||
|
||||
renderPasswordOrCodeInput() {
|
||||
const application = this.getApplicationObj();
|
||||
if (this.state.loginMethod === "password") {
|
||||
if (this.state.loginMethod === "password" || this.state.loginMethod === "ldap") {
|
||||
return (
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
@ -875,7 +897,7 @@ class LoginPage extends React.Component {
|
||||
prefix={<LockOutlined className="site-form-item-icon" />}
|
||||
type="password"
|
||||
placeholder={i18next.t("general:Password")}
|
||||
disabled={!Setting.isPasswordEnabled(application)}
|
||||
disabled={this.state.loginMethod === "password" ? !Setting.isPasswordEnabled(application) : !Setting.isLdapEnabled(application)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
@ -910,14 +932,16 @@ class LoginPage extends React.Component {
|
||||
};
|
||||
|
||||
const itemsMap = new Map([
|
||||
[generateItemKey("Password", "None"), {label: i18next.t("general:Password"), key: "password"}],
|
||||
[generateItemKey("Password", "All"), {label: i18next.t("general:Password"), key: "password"}],
|
||||
[generateItemKey("Password", "Non-LDAP"), {label: i18next.t("general:Password"), key: "password"}],
|
||||
[generateItemKey("Verification code", "All"), {label: i18next.t("login:Verification code"), key: "verificationCode"}],
|
||||
[generateItemKey("Verification code", "Email only"), {label: i18next.t("login:Verification code"), key: "verificationCodeEmail"}],
|
||||
[generateItemKey("Verification code", "Phone only"), {label: i18next.t("login:Verification code"), key: "verificationCodePhone"}],
|
||||
[generateItemKey("WebAuthn", "None"), {label: i18next.t("login:WebAuthn"), key: "webAuthn"}],
|
||||
[generateItemKey("LDAP", "None"), {label: i18next.t("login:LDAP"), key: "ldap"}],
|
||||
]);
|
||||
|
||||
application?.signinMethods.forEach((signinMethod) => {
|
||||
application?.signinMethods?.forEach((signinMethod) => {
|
||||
const item = itemsMap.get(generateItemKey(signinMethod.name, signinMethod.rule));
|
||||
if (item) {
|
||||
const label = signinMethod.name === signinMethod.displayName ? item.label : signinMethod.displayName;
|
||||
@ -1053,7 +1077,7 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
|
||||
const visibleOAuthProviderItems = (application.providers === null) ? [] : application.providers.filter(providerItem => this.isProviderVisible(providerItem));
|
||||
if (this.props.preview !== "auto" && !Setting.isPasswordEnabled(application) && !Setting.isCodeSigninEnabled(application) && !Setting.isWebAuthnEnabled(application) && visibleOAuthProviderItems.length === 1) {
|
||||
if (this.props.preview !== "auto" && !Setting.isPasswordEnabled(application) && !Setting.isCodeSigninEnabled(application) && !Setting.isWebAuthnEnabled(application) && !Setting.isLdapEnabled(application) && visibleOAuthProviderItems.length === 1) {
|
||||
Setting.goToLink(Provider.getAuthUrl(application, visibleOAuthProviderItems[0].provider, "signup"));
|
||||
return (
|
||||
<div style={{display: "flex", justifyContent: "center", alignItems: "center", width: "100%"}}>
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"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 Access-Tokens",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token-Format",
|
||||
"Token format - Tooltip": "Das Format des Access-Tokens",
|
||||
"You are unexpected to see this prompt page": "Sie sind unerwartet auf diese Aufforderungsseite gelangt"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Modelle",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Eindeutige, auf Strings basierende ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth-Provider",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Passwort vergessen?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Laden",
|
||||
"Logging out...": "Ausloggen...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Bitte geben Sie Ihre E-Mail oder Telefonnummer ein!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Bitte geben Sie Ihren Code ein!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Bitte geben Sie Ihren richtigen Namen ein!",
|
||||
"Please select your country code!": "Bitte wählen Sie Ihren Ländercode aus!",
|
||||
"Please select your country/region!": "Bitte wählen Sie Ihr Land/Ihre Region aus!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Nutzungsbedingungen",
|
||||
"Terms of Use - Tooltip": "Nutzungsbedingungen, die Benutzer während der Registrierung lesen und akzeptieren müssen",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Verwaltete Konten",
|
||||
"Modify password...": "Passwort ändern...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "Neue E-Mail",
|
||||
"New Password": "Neues Passwort",
|
||||
"New User": "Neuer Benutzer",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Lade ein Foto hoch",
|
||||
"Value": "Value",
|
||||
"Values": "Werte",
|
||||
"Verification code sent": "Bestätigungscode gesendet",
|
||||
"WebAuthn credentials": "WebAuthn-Anmeldeinformationen",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "The user fields included in the token",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "La aplicación no permite registrarse una cuenta nueva",
|
||||
"Token expire": "Token expirado",
|
||||
"Token expire - Tooltip": "Tiempo de expiración del token de acceso",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Formato del token",
|
||||
"Token format - Tooltip": "El formato del token de acceso",
|
||||
"You are unexpected to see this prompt page": "Es inesperado ver esta página de inicio"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Modelos",
|
||||
"Name": "Nombre",
|
||||
"Name - Tooltip": "ID único basado en cadenas",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "Proveedores de OAuth",
|
||||
"OK": "Vale",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "¿Olvidaste tu contraseña?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Cargando",
|
||||
"Logging out...": "Cerrando sesión...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "¡Por favor introduzca su correo electrónico o teléfono!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "¡Por favor ingrese su código!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "¡Por favor, ingresa tu nombre real!",
|
||||
"Please select your country code!": "¡Por favor seleccione su código de país!",
|
||||
"Please select your country/region!": "¡Por favor seleccione su país/región!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Términos de uso",
|
||||
"Terms of Use - Tooltip": "Términos de uso que los usuarios necesitan leer y aceptar durante el registro",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Cuentas gestionadas",
|
||||
"Modify password...": "Modificar contraseña...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "Nuevo correo electrónico",
|
||||
"New Password": "Nueva contraseña",
|
||||
"New User": "Nuevo Usuario",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Subir una foto",
|
||||
"Value": "Value",
|
||||
"Values": "Valores",
|
||||
"Verification code sent": "Código de verificación enviado",
|
||||
"WebAuthn credentials": "Credenciales de WebAuthn",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "L'application ne permet pas de créer un nouveau compte",
|
||||
"Token expire": "Expiration du jeton",
|
||||
"Token expire - Tooltip": "Durée avant expiration du jeton d'accès",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Format de jeton",
|
||||
"Token format - Tooltip": "Le format du jeton d'accès",
|
||||
"You are unexpected to see this prompt page": "Il n'était pas prévu que vous voyez cette page de saisie"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Modèles",
|
||||
"Name": "Nom",
|
||||
"Name - Tooltip": "Identifiant unique à base de chaîne",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "Aucun",
|
||||
"OAuth providers": "Fournisseurs OAuth",
|
||||
"OK": "Ok",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Échec de l'obtention de l'autorisation MetaMask",
|
||||
"Failed to obtain Web3-Onboard authorization": "Échec de l'obtention de l'autorisation MetaMask",
|
||||
"Forgot password?": "Mot de passe oublié ?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Chargement",
|
||||
"Logging out...": "Déconnexion...",
|
||||
"MetaMask plugin not detected": "Le plugin MetaMask n'a pas été détecté",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Veuillez saisir votre adresse e-mail ou votre numéro de téléphone !",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Veuillez saisir votre code !",
|
||||
"Please input your organization name!": "Veuillez saisir le nom de votre organisation !",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Veuillez saisir votre nom complet !",
|
||||
"Please select your country code!": "Sélectionnez votre code de pays, s'il vous plaît !",
|
||||
"Please select your country/region!": "Veuillez sélectionner votre pays/région !",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Conditions d'utilisation",
|
||||
"Terms of Use - Tooltip": "Conditions d'utilisation qui doivent être lus acceptés lors de l'enregistrement du compte",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Comptes gérés",
|
||||
"Modify password...": "Modifier le mot de passe...",
|
||||
"Multi-factor authentication": "Authentification multifacteur",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "Nouvelle adresse e-mail",
|
||||
"New Password": "Nouveau mot de passe",
|
||||
"New User": "Nouveau compte",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Télécharger une photo de l'endroit de la pièce d'identité",
|
||||
"Upload ID card with person picture": "Télécharger une photo la pièce d'identité avec une personne",
|
||||
"Upload a photo": "Télécharger une photo",
|
||||
"Value": "Value",
|
||||
"Values": "Valeurs",
|
||||
"Verification code sent": "Code de vérification envoyé",
|
||||
"WebAuthn credentials": "Identifiants WebAuthn",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "Aplikasi tidak memperbolehkan untuk mendaftar akun baru",
|
||||
"Token expire": "Token kadaluarsa",
|
||||
"Token expire - Tooltip": "Waktu kadaluwarsa token akses",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Format token",
|
||||
"Token format - Tooltip": "Format dari token akses",
|
||||
"You are unexpected to see this prompt page": "Anda tidak mengharapkan untuk melihat halaman prompt ini"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Model-model",
|
||||
"Name": "Nama",
|
||||
"Name - Tooltip": "ID unik berbasis string",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "Penyedia OAuth",
|
||||
"OK": "Baik atau Oke",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Lupa kata sandi?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Memuat",
|
||||
"Logging out...": "Keluar...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Silahkan masukkan email atau nomor telepon Anda!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Silakan masukkan kode Anda!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Silakan masukkan nama asli Anda!",
|
||||
"Please select your country code!": "Tolong pilih kode negara Anda!",
|
||||
"Please select your country/region!": "Silakan pilih negara/region Anda!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Syarat Penggunaan",
|
||||
"Terms of Use - Tooltip": "Syarat penggunaan yang harus dibaca dan disetujui oleh pengguna selama proses registrasi",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Akun yang dikelola",
|
||||
"Modify password...": "Mengubah kata sandi...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "Email baru",
|
||||
"New Password": "Kata Sandi Baru",
|
||||
"New User": "Pengguna Baru",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Unggah foto",
|
||||
"Value": "Value",
|
||||
"Values": "Nilai-nilai",
|
||||
"Verification code sent": "Kode verifikasi telah dikirim",
|
||||
"WebAuthn credentials": "Kredensial WebAuthn",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "アプリケーションでは新しいアカウントの登録ができません",
|
||||
"Token expire": "トークンの有効期限が切れました",
|
||||
"Token expire - Tooltip": "アクセストークンの有効期限",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "トークン形式",
|
||||
"Token format - Tooltip": "アクセストークンのフォーマット",
|
||||
"You are unexpected to see this prompt page": "このプロンプトページを見ることは予期せぬことである"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "モデル",
|
||||
"Name": "名前",
|
||||
"Name - Tooltip": "ユニークで文字列ベースのID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuthプロバイダー",
|
||||
"OK": "了解",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "パスワードを忘れましたか?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "ローディング",
|
||||
"Logging out...": "ログアウト中...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "あなたのメールアドレスまたは電話番号を入力してください!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "あなたのコードを入力してください!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "正しい名前を入力してください!",
|
||||
"Please select your country code!": "あなたの国コードを選択してください!",
|
||||
"Please select your country/region!": "あなたの国/地域を選択してください!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "利用規約",
|
||||
"Terms of Use - Tooltip": "ユーザーが登録する際に読んで同意する必要がある利用規約",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "管理アカウント",
|
||||
"Modify password...": "パスワードを変更する...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "新しいメール",
|
||||
"New Password": "新しいパスワード",
|
||||
"New User": "新しいユーザー",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "写真をアップロードしてください",
|
||||
"Value": "Value",
|
||||
"Values": "価値観",
|
||||
"Verification code sent": "確認コードを送信しました",
|
||||
"WebAuthn credentials": "WebAuthnの資格情報",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "이 어플리케이션은 새 계정 등록을 허용하지 않습니다",
|
||||
"Token expire": "토큰 만료",
|
||||
"Token expire - Tooltip": "액세스 토큰 만료 시간",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "토큰 형식",
|
||||
"Token format - Tooltip": "접근 토큰의 형식",
|
||||
"You are unexpected to see this prompt page": "당신은 이 프롬프트 페이지를 볼 것을 예상하지 못했습니다"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "모델들",
|
||||
"Name": "이름",
|
||||
"Name - Tooltip": "고유한 문자열 기반 ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth 공급자",
|
||||
"OK": "예",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "비밀번호를 잊으셨나요?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "로딩 중입니다",
|
||||
"Logging out...": "로그아웃 중...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "이메일 또는 전화번호를 입력해주세요!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "코드를 입력해주세요!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "진짜 이름을 입력해주세요!",
|
||||
"Please select your country code!": "국가 코드를 선택해 주세요!",
|
||||
"Please select your country/region!": "국가 / 지역을 선택해주세요!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "사용 약관",
|
||||
"Terms of Use - Tooltip": "등록 중 사용자가 읽어야 하고 동의해야하는 이용 약관",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "관리 계정",
|
||||
"Modify password...": "비밀번호 수정하기...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "새 이메일",
|
||||
"New Password": "새로운 비밀번호",
|
||||
"New User": "새로운 사용자",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "사진을 업로드하세요",
|
||||
"Value": "Value",
|
||||
"Values": "가치들",
|
||||
"Verification code sent": "인증 코드가 전송되었습니다",
|
||||
"WebAuthn credentials": "웹 인증 자격증명",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "A aplicação não permite o registro de novas contas",
|
||||
"Token expire": "Expiração do Token",
|
||||
"Token expire - Tooltip": "Tempo de expiração do token de acesso",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Formato do token",
|
||||
"Token format - Tooltip": "O formato do token de acesso",
|
||||
"You are unexpected to see this prompt page": "Você não deveria ver esta página de prompt"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Modelos",
|
||||
"Name": "Nome",
|
||||
"Name - Tooltip": "ID único em formato de string",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "Provedores OAuth",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Esqueceu a senha?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Carregando",
|
||||
"Logging out...": "Saindo...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Por favor, informe seu email ou telefone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Por favor, informe o código!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Por favor, insira seu nome real!",
|
||||
"Please select your country code!": "Por favor, selecione o código do seu país!",
|
||||
"Please select your country/region!": "Por favor, selecione seu país/região!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Termos de Uso",
|
||||
"Terms of Use - Tooltip": "Termos de uso que os usuários precisam ler e concordar durante o registro",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Contas gerenciadas",
|
||||
"Modify password...": "Modificar senha...",
|
||||
"Multi-factor authentication": "Autenticação de vários fatores",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "Novo E-mail",
|
||||
"New Password": "Nova Senha",
|
||||
"New User": "Novo Usuário",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Enviar uma foto",
|
||||
"Value": "Value",
|
||||
"Values": "Valores",
|
||||
"Verification code sent": "Código de verificação enviado",
|
||||
"WebAuthn credentials": "Credenciais WebAuthn",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "Приложение не позволяет зарегистрироваться новому аккаунту",
|
||||
"Token expire": "Срок действия токена истекает",
|
||||
"Token expire - Tooltip": "Время истечения токена доступа",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Формат жетона",
|
||||
"Token format - Tooltip": "Формат токена доступа",
|
||||
"You are unexpected to see this prompt page": "Вы не ожидали увидеть эту страницу-подсказку"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Модели",
|
||||
"Name": "Имя",
|
||||
"Name - Tooltip": "Уникальный идентификатор на основе строки",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "Провайдеры OAuth",
|
||||
"OK": "OK - Хорошо",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Забыли пароль?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Загрузка",
|
||||
"Logging out...": "Выход...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Пожалуйста, введите свой адрес электронной почты или номер телефона!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Пожалуйста, введите свой код!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Пожалуйста, введите своё настоящее имя!",
|
||||
"Please select your country code!": "Пожалуйста, выберите код своей страны!",
|
||||
"Please select your country/region!": "Пожалуйста, выберите свою страну / регион!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Условия использования",
|
||||
"Terms of Use - Tooltip": "Условия использования, которые пользователи должны прочитать и согласиться с ними при регистрации",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Управляемые счета",
|
||||
"Modify password...": "Изменить пароль...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "Новое электронное письмо",
|
||||
"New Password": "Новый пароль",
|
||||
"New User": "Новый пользователь",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Загрузить фото",
|
||||
"Value": "Value",
|
||||
"Values": "Значения",
|
||||
"Verification code sent": "Код подтверждения отправлен",
|
||||
"WebAuthn credentials": "WebAuthn удостоверения",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||
"Token expire": "Token expire",
|
||||
"Token expire - Tooltip": "Access token expiration time",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Token format",
|
||||
"Token format - Tooltip": "The format of access token",
|
||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Models",
|
||||
"Name": "Name",
|
||||
"Name - Tooltip": "Unique, string-based ID",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "OAuth providers",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Forgot password?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Loading",
|
||||
"Logging out...": "Logging out...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Please input your code!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Please input your real name!",
|
||||
"Please select your country code!": "Please select your country code!",
|
||||
"Please select your country/region!": "Please select your country/region!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Terms of Use",
|
||||
"Terms of Use - Tooltip": "Terms of use that users need to read and agree to during registration",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Managed accounts",
|
||||
"Modify password...": "Modify password...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "New Email",
|
||||
"New Password": "New Password",
|
||||
"New User": "New User",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Upload a photo",
|
||||
"Value": "Value",
|
||||
"Values": "Values",
|
||||
"Verification code sent": "Verification code sent",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"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",
|
||||
"Token expire": "Mã thông báo hết hạn",
|
||||
"Token expire - Tooltip": "Thời gian hết hạn của mã truy cập",
|
||||
"Token fields": "Token fields",
|
||||
"Token fields - Tooltip": "Token fields - Tooltip",
|
||||
"Token format": "Định dạng mã thông báo",
|
||||
"Token format - Tooltip": "Định dạng của mã thông báo truy cập",
|
||||
"You are unexpected to see this prompt page": "Bạn không mong đợi thấy trang này hiện lên"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Mô hình",
|
||||
"Name": "Tên",
|
||||
"Name - Tooltip": "ID duy nhất dựa trên chuỗi",
|
||||
"Name format": "Name format",
|
||||
"Non-LDAP": "Non-LDAP",
|
||||
"None": "None",
|
||||
"OAuth providers": "Nhà cung cấp OAuth",
|
||||
"OK": "Được rồi",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "Failed to obtain MetaMask authorization",
|
||||
"Failed to obtain Web3-Onboard authorization": "Failed to obtain Web3-Onboard authorization",
|
||||
"Forgot password?": "Quên mật khẩu?",
|
||||
"LDAP": "LDAP",
|
||||
"LDAP username, Email or phone": "LDAP username, Email or phone",
|
||||
"Loading": "Đang tải",
|
||||
"Logging out...": "Đăng xuất ...",
|
||||
"MetaMask plugin not detected": "MetaMask plugin not detected",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "Phone",
|
||||
"Please input your Email or Phone!": "Vui lòng nhập địa chỉ Email hoặc số điện thoại của bạn!",
|
||||
"Please input your Email!": "Please input your Email!",
|
||||
"Please input your LDAP username!": "Please input your LDAP username!",
|
||||
"Please input your Phone!": "Please input your Phone!",
|
||||
"Please input your code!": "Vui lòng nhập mã của bạn!",
|
||||
"Please input your organization name!": "Please input your organization name!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "Vui lòng nhập tên thật của bạn!",
|
||||
"Please select your country code!": "Vui lòng chọn mã quốc gia của bạn!",
|
||||
"Please select your country/region!": "Vui lòng chọn quốc gia/vùng của bạn!",
|
||||
"Regex": "Regex",
|
||||
"Terms of Use": "Điều khoản sử dụng",
|
||||
"Terms of Use - Tooltip": "Điều khoản sử dụng mà người dùng cần đọc và đồng ý trong quá trình đăng ký",
|
||||
"Text 1": "Text 1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "Quản lý tài khoản",
|
||||
"Modify password...": "Sửa đổi mật khẩu...",
|
||||
"Multi-factor authentication": "Multi-factor authentication",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "Email mới",
|
||||
"New Password": "Mật khẩu mới",
|
||||
"New User": "Người dùng mới",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "Upload ID card front picture",
|
||||
"Upload ID card with person picture": "Upload ID card with person picture",
|
||||
"Upload a photo": "Tải lên một bức ảnh",
|
||||
"Value": "Value",
|
||||
"Values": "Giá trị",
|
||||
"Verification code sent": "Mã xác minh đã được gửi",
|
||||
"WebAuthn credentials": "Chứng chỉ WebAuthn",
|
||||
|
@ -103,6 +103,8 @@
|
||||
"The application does not allow to sign up new account": "该应用不允许注册新账户",
|
||||
"Token expire": "Access Token过期",
|
||||
"Token expire - Tooltip": "Access Token过期时间",
|
||||
"Token fields": "Token字段",
|
||||
"Token fields - Tooltip": "Token中所包含的用户字段",
|
||||
"Token format": "Access Token格式",
|
||||
"Token format - Tooltip": "Access Token格式",
|
||||
"You are unexpected to see this prompt page": "错误:该提醒页面不应出现"
|
||||
@ -265,6 +267,8 @@
|
||||
"Models": "Casbin模型",
|
||||
"Name": "名称",
|
||||
"Name - Tooltip": "唯一的、字符串式的ID",
|
||||
"Name format": "名称格式",
|
||||
"Non-LDAP": "禁用LDAP",
|
||||
"None": "无",
|
||||
"OAuth providers": "OAuth提供方",
|
||||
"OK": "OK",
|
||||
@ -431,6 +435,8 @@
|
||||
"Failed to obtain MetaMask authorization": "获取MetaMask授权失败",
|
||||
"Failed to obtain Web3-Onboard authorization": "获取 Web3-Onboard 授权失败",
|
||||
"Forgot password?": "忘记密码?",
|
||||
"LDAP": "LDAP登录",
|
||||
"LDAP username, Email or phone": "LDAP用户名, Email或手机号",
|
||||
"Loading": "加载中",
|
||||
"Logging out...": "正在退出登录...",
|
||||
"MetaMask plugin not detected": "未检测到MetaMask插件",
|
||||
@ -439,6 +445,7 @@
|
||||
"Phone": "手机号",
|
||||
"Please input your Email or Phone!": "请输入您的Email或手机号!",
|
||||
"Please input your Email!": "请输入您的Email!",
|
||||
"Please input your LDAP username!": "请输入您的LDAP用户名!",
|
||||
"Please input your Phone!": "请输入您的手机号!",
|
||||
"Please input your code!": "请输入您的验证码!",
|
||||
"Please input your organization name!": "请输入组织的名字!",
|
||||
@ -881,6 +888,7 @@
|
||||
"Please input your real name!": "请输入您的姓名!",
|
||||
"Please select your country code!": "请选择国家代码!",
|
||||
"Please select your country/region!": "请选择您的国家或地区",
|
||||
"Regex": "正则表达式",
|
||||
"Terms of Use": "《用户协议》",
|
||||
"Terms of Use - Tooltip": "用户注册时需要阅读并同意的使用条款",
|
||||
"Text 1": "文本1",
|
||||
@ -1047,8 +1055,6 @@
|
||||
"Managed accounts": "托管账户",
|
||||
"Modify password...": "编辑密码...",
|
||||
"Multi-factor authentication": "多因素认证",
|
||||
"Name": "Name",
|
||||
"Name format": "Name format",
|
||||
"New Email": "新邮箱",
|
||||
"New Password": "新密码",
|
||||
"New User": "添加用户",
|
||||
@ -1086,7 +1092,6 @@
|
||||
"Upload ID card front picture": "上传身份证正面照片",
|
||||
"Upload ID card with person picture": "上传手持身份证照片",
|
||||
"Upload a photo": "上传头像",
|
||||
"Value": "值",
|
||||
"Values": "值",
|
||||
"Verification code sent": "验证码已发送",
|
||||
"WebAuthn credentials": "WebAuthn凭据",
|
||||
|
@ -38,7 +38,7 @@ class SamlAttributeTable extends React.Component {
|
||||
}
|
||||
|
||||
addRow(table) {
|
||||
const row = {Name: "", nameformat: "", value: ""};
|
||||
const row = {Name: "", nameFormat: "", value: ""};
|
||||
if (table === undefined || table === null) {
|
||||
table = [];
|
||||
}
|
||||
@ -64,7 +64,7 @@ class SamlAttributeTable extends React.Component {
|
||||
renderTable(table) {
|
||||
const columns = [
|
||||
{
|
||||
title: i18next.t("user:Name"),
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
width: "200px",
|
||||
@ -77,9 +77,9 @@ class SamlAttributeTable extends React.Component {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("user:Name format"),
|
||||
dataIndex: "nameformat",
|
||||
key: "nameformat",
|
||||
title: i18next.t("general:Name format"),
|
||||
dataIndex: "nameFormat",
|
||||
key: "nameFormat",
|
||||
width: "200px",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
@ -87,7 +87,7 @@ class SamlAttributeTable extends React.Component {
|
||||
value={text}
|
||||
defaultValue="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"
|
||||
onChange={value => {
|
||||
this.updateField(table, index, "nameformat", value);
|
||||
this.updateField(table, index, "nameFormat", value);
|
||||
}} >
|
||||
<Option key="Unspecified" value="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">Unspecified</Option>
|
||||
<Option key="Basic" value="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">Basic</Option>
|
||||
@ -98,7 +98,7 @@ class SamlAttributeTable extends React.Component {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("user:Value"),
|
||||
title: i18next.t("webhook:Value"),
|
||||
dataIndex: "value",
|
||||
key: "value",
|
||||
width: "200px",
|
||||
|
@ -20,7 +20,7 @@ import i18next from "i18next";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
class SigninTable extends React.Component {
|
||||
class SigninMethodTable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -70,6 +70,7 @@ class SigninTable extends React.Component {
|
||||
{name: "Password", displayName: i18next.t("general:Password")},
|
||||
{name: "Verification code", displayName: i18next.t("login:Verification code")},
|
||||
{name: "WebAuthn", displayName: i18next.t("login:WebAuthn")},
|
||||
{name: "LDAP", displayName: i18next.t("login:LDAP")},
|
||||
];
|
||||
const columns = [
|
||||
{
|
||||
@ -91,7 +92,7 @@ class SigninTable extends React.Component {
|
||||
onChange={value => {
|
||||
this.updateField(table, index, "name", value);
|
||||
this.updateField(table, index, "displayName", value);
|
||||
if (value === "Verification code") {
|
||||
if (value === "Verification code" || value === "Password") {
|
||||
this.updateField(table, index, "rule", "All");
|
||||
} else {
|
||||
this.updateField(table, index, "rule", "None");
|
||||
@ -130,6 +131,11 @@ class SigninTable extends React.Component {
|
||||
{id: "Email only", name: i18next.t("general:Email only")},
|
||||
{id: "Phone only", name: i18next.t("general:Phone only")},
|
||||
];
|
||||
} else if (record.name === "Password") {
|
||||
options = [
|
||||
{id: "All", name: i18next.t("general:All")},
|
||||
{id: "Non-LDAP", name: i18next.t("general:Non-LDAP")},
|
||||
];
|
||||
}
|
||||
|
||||
if (options.length === 0) {
|
||||
@ -157,7 +163,7 @@ class SigninTable extends React.Component {
|
||||
<Button style={{marginRight: "5px"}} disabled={index === table.length - 1} icon={<DownOutlined />} size="small" onClick={() => this.downRow(table, index)} />
|
||||
</Tooltip>
|
||||
<Tooltip placement="topLeft" title={i18next.t("general:Delete")}>
|
||||
<Button icon={<DeleteOutlined />} size="small" disabled={Setting.getDeduplicatedArray(items, table, "name").length >= items.length - 1} onClick={() => this.deleteRow(items, table, index)} />
|
||||
<Button icon={<DeleteOutlined />} size="small" disabled={table.length <= 1} onClick={() => this.deleteRow(items, table, index)} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
@ -192,4 +198,4 @@ class SigninTable extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default SigninTable;
|
||||
export default SigninMethodTable;
|
@ -224,6 +224,23 @@ class SignupTable extends React.Component {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("signup:Regex"),
|
||||
dataIndex: "regex",
|
||||
key: "regex",
|
||||
width: "200px",
|
||||
render: (text, record, index) => {
|
||||
if (record.name.startsWith("Text ") || record.name === "Password" || record.name === "Confirm password") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Input value={text} onChange={e => {
|
||||
this.updateField(table, index, "regex", e.target.value);
|
||||
}} />
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("application:Rule"),
|
||||
dataIndex: "rule",
|
||||
|
@ -98,11 +98,7 @@ class SyncerTableColumnTable extends React.Component {
|
||||
return (
|
||||
<Select virtual={false} showSearch style={{width: "100%"}} value={text} onChange={(value => {this.updateField(table, index, "casdoorName", value);})}>
|
||||
{
|
||||
["Owner", "Name", "CreatedTime", "UpdatedTime", "Id", "Type", "Password", "PasswordSalt", "DisplayName", "FirstName", "LastName", "Avatar", "PermanentAvatar",
|
||||
"Email", "EmailVerified", "Phone", "Location", "Address", "Affiliation", "Title", "IdCardType", "IdCard", "Homepage", "Bio", "Tag", "Region",
|
||||
"Language", "Gender", "Birthday", "Education", "Score", "Ranking", "IsDefaultAvatar", "IsOnline", "IsAdmin", "IsForbidden", "IsDeleted", "CreatedIp",
|
||||
"PreferredMfaType", "TotpSecret", "SignupApplication"]
|
||||
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
||||
Setting.getUserCommonFields().map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
||||
}
|
||||
</Select>
|
||||
);
|
||||
|
Reference in New Issue
Block a user