Compare commits

..

18 Commits

Author SHA1 Message Date
hsluoyz
1161310f81 feat: improve README.md 2024-01-15 10:14:01 +08:00
xiao-kong-long
48ba5f91ed feat: add Synology NAS storage provider (#2605) 2024-01-14 22:38:31 +08:00
Satinder Singh
53df2c2704 fix: add semantic versioning for helm charts (#2603) 2024-01-14 09:44:16 +08:00
Yang Luo
78066da208 Improve setCorsHeaders() for "include" mode 2024-01-13 23:46:05 +08:00
Yang Luo
60096468fe fix: fix CI email 2024-01-13 18:12:52 +08:00
Yang Luo
39d6bc10f7 Fix GetCaptchaStatus() crash if not logged in 2024-01-13 18:04:38 +08:00
Yang Luo
177f2f2f11 Add userId param to GetAllObjects() API 2024-01-13 18:03:40 +08:00
Yang Luo
79b393afee feat: add regex to SignupTable 2024-01-13 16:08:49 +08:00
Yang Luo
5bb12a30d4 Don't show two errors in verificationCode login page 2024-01-13 16:01:22 +08:00
Yang Luo
fdb68bf9c8 Rename to SigninMethodTable 2024-01-13 15:53:01 +08:00
Yang Luo
37748850c8 Fix nameFormat in SamlItem 2024-01-13 15:32:49 +08:00
Yang Luo
8968396ae5 Fix bug in getDefaultLoginMethod() 2024-01-13 12:13:09 +08:00
Yang Luo
f5395f15f9 feat: fix isSigninMethodEnabled() bug in frontend 2024-01-13 11:35:06 +08:00
Yang Luo
73e44df867 Improve GetAllRoles() error handling 2024-01-13 10:06:08 +08:00
Yang Luo
0b575ccf84 Refactor getAllValues() 2024-01-13 09:58:55 +08:00
Yang Luo
9b7f465a47 Fix failedSigninFrozenTime typo 2024-01-13 02:12:29 +08:00
Yang Luo
b1fe28fb83 Refactor application.FailedSigninLimit code 2024-01-13 02:09:18 +08:00
Satinder Singh
530d054adb feat: ci should commit index.yaml and push to docker hub (#2600) 2024-01-11 16:10:08 +08:00
51 changed files with 269 additions and 203 deletions

View File

@@ -217,17 +217,22 @@ jobs:
- name: Update Helm Chart
if: steps.should_push.outputs.push=='true'
run: |
# Set the appVersion of the chart to the current tag
# Set the appVersion and version of the chart to the current tag
sed -i "s/appVersion: .*/appVersion: ${{steps.get-current-tag.outputs.tag }}/g" ./charts/casdoor/Chart.yaml
sed -i "s/version: .*/version: ${{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 ./charts/casdoor/Chart.yaml
git config --global user.email "bot@casbin.org"
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
git tag ${{steps.get-current-tag.outputs.tag }}
git push origin HEAD:master --follow-tags

View File

@@ -69,6 +69,7 @@ https://casdoor.org
- By source code: https://casdoor.org/docs/basic/server-installation
- By Docker: https://casdoor.org/docs/basic/try-with-docker
- By Kubernetes Helm: https://casdoor.org/docs/basic/try-with-helm
## How to connect to Casdoor?

View File

@@ -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))
}

View File

@@ -973,23 +973,27 @@ func (c *ApiController) GetWebhookEventType() {
// @router /api/get-captcha-status [get]
func (c *ApiController) GetCaptchaStatus() {
organization := c.Input().Get("organization")
userId := c.Input().Get("user_id")
userId := c.Input().Get("userId")
user, err := object.GetUserByFields(organization, userId)
if err != nil {
c.ResponseError(err.Error())
return
}
failedSigninLimit, _, err := object.GetFailedSigninConfigByUser(user)
if err != nil {
c.ResponseError(err.Error())
return
captchaEnabled := false
if user != nil {
var failedSigninLimit int
failedSigninLimit, _, err = object.GetFailedSigninConfigByUser(user)
if err != nil {
c.ResponseError(err.Error())
return
}
if user.SigninWrongTimes >= failedSigninLimit {
captchaEnabled = true
}
}
var captchaEnabled bool
if user != nil && user.SigninWrongTimes >= failedSigninLimit {
captchaEnabled = true
}
c.ResponseOk(captchaEnabled)
}

View File

@@ -264,10 +264,13 @@ func (c *ApiController) BatchEnforce() {
}
func (c *ApiController) GetAllObjects() {
userId := c.GetSessionUsername()
userId := c.Input().Get("userId")
if userId == "" {
c.ResponseError(c.T("general:Please login first"))
return
userId = c.GetSessionUsername()
if userId == "" {
c.ResponseError(c.T("general:Please login first"))
return
}
}
objects, err := object.GetAllObjects(userId)
@@ -280,10 +283,13 @@ func (c *ApiController) GetAllObjects() {
}
func (c *ApiController) GetAllActions() {
userId := c.GetSessionUsername()
userId := c.Input().Get("userId")
if userId == "" {
c.ResponseError(c.T("general:Please login first"))
return
userId = c.GetSessionUsername()
if userId == "" {
c.ResponseError(c.T("general:Please login first"))
return
}
}
actions, err := object.GetAllActions(userId)
@@ -296,10 +302,13 @@ func (c *ApiController) GetAllActions() {
}
func (c *ApiController) GetAllRoles() {
userId := c.GetSessionUsername()
userId := c.Input().Get("userId")
if userId == "" {
c.ResponseError(c.T("general:Please login first"))
return
userId = c.GetSessionUsername()
if userId == "" {
c.ResponseError(c.T("general:Please login first"))
return
}
}
roles, err := object.GetAllRoles(userId)

2
go.mod
View File

@@ -12,7 +12,7 @@ require (
github.com/casdoor/go-sms-sender v0.19.0
github.com/casdoor/gomail/v2 v2.0.1
github.com/casdoor/notify v0.45.0
github.com/casdoor/oss v1.4.1
github.com/casdoor/oss v1.5.0
github.com/casdoor/xorm-adapter/v3 v3.1.0
github.com/casvisor/casvisor-go-sdk v1.0.3
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f

2
go.sum
View File

@@ -1091,6 +1091,8 @@ github.com/casdoor/notify v0.45.0 h1:OlaFvcQFjGOgA4mRx07M8AH1gvb5xNo21mcqrVGlLgk
github.com/casdoor/notify v0.45.0/go.mod h1:wNHQu0tiDROMBIvz0j3Om3Lhd5yZ+AIfnFb8MYb8OLQ=
github.com/casdoor/oss v1.4.1 h1:/P2JCyGzB2TtpJ3LocKocI1VAme2YdvVau2wpMQGt7I=
github.com/casdoor/oss v1.4.1/go.mod h1:rJAWA0hLhtu94t6IRpotLUkXO1NWMASirywQYaGizJE=
github.com/casdoor/oss v1.5.0 h1:mi1htaXR5fynskDry1S3wk+Dd2nRY1z1pVcnGsqMqP4=
github.com/casdoor/oss v1.5.0/go.mod h1:rJAWA0hLhtu94t6IRpotLUkXO1NWMASirywQYaGizJE=
github.com/casdoor/xorm-adapter/v3 v3.1.0 h1:NodWayRtSLVSeCvL9H3Hc61k0G17KhV9IymTCNfh3kk=
github.com/casdoor/xorm-adapter/v3 v3.1.0/go.mod h1:4WTcUw+bTgBylGHeGHzTtBvuTXRS23dtwzFLl9tsgFM=
github.com/casvisor/casvisor-go-sdk v1.0.3 h1:TKJQWKnhtznEBhzLPEdNsp7nJK2GgdD8JsB0lFPMW7U=

View File

@@ -123,7 +123,7 @@
"redirectUris": [""],
"expireInHours": 168,
"failedSigninLimit": 5,
"failedSigninfrozenTime": 15
"failedSigninFrozenTime": 15
}
],
"users": [

View File

@@ -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"`
}
@@ -100,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) {
@@ -347,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

View File

@@ -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 {
@@ -509,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

View File

@@ -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)
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -24,16 +24,18 @@ import (
)
const (
headerOrigin = "Origin"
headerAllowOrigin = "Access-Control-Allow-Origin"
headerAllowMethods = "Access-Control-Allow-Methods"
headerAllowHeaders = "Access-Control-Allow-Headers"
headerOrigin = "Origin"
headerAllowOrigin = "Access-Control-Allow-Origin"
headerAllowMethods = "Access-Control-Allow-Methods"
headerAllowHeaders = "Access-Control-Allow-Headers"
headerAllowCredentials = "Access-Control-Allow-Credentials"
)
func setCorsHeaders(ctx *context.Context, origin string) {
ctx.Output.Header(headerAllowOrigin, origin)
ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS, DELETE")
ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization")
ctx.Output.Header(headerAllowCredentials, "true")
if ctx.Input.Method() == "OPTIONS" {
ctx.ResponseWriter.WriteHeader(http.StatusOK)

View File

@@ -34,6 +34,8 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin
return NewQiniuCloudKodoStorageProvider(clientId, clientSecret, region, bucket, endpoint)
case "Google Cloud Storage":
return NewGoogleCloudStorageProvider(clientSecret, bucket, endpoint)
case "Synology":
return NewSynologyNasStorageProvider(clientId, clientSecret, endpoint)
}
return nil

31
storage/synology_nas.go Normal file
View File

@@ -0,0 +1,31 @@
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package storage
import (
"github.com/casdoor/oss"
"github.com/casdoor/oss/synology"
)
func NewSynologyNasStorageProvider(clientId string, clientSecret string, endpoint string) oss.StorageInterface {
sp := synology.New(&synology.Config{
AccessID: clientId,
AccessKey: clientSecret,
Endpoint: endpoint,
SharedFolder: "/home",
})
return sp
}

View File

@@ -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": {

View File

@@ -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

View File

@@ -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";
@@ -437,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>
@@ -487,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) => {
@@ -797,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>
@@ -837,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});
}} >

View File

@@ -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});
}} >

View File

@@ -796,7 +796,7 @@ class ProviderEditPage extends React.Component {
</Col>
</Row>
)}
{["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? null : (
{["Custom HTTP SMS", "Local File System", "MinIO", "Tencent Cloud COS", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology"].includes(this.state.provider.type) ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={2}>
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
@@ -832,7 +832,7 @@ class ProviderEditPage extends React.Component {
</Col>
</Row>
)}
{["Custom HTTP SMS", "MinIO", "Google Cloud Storage", "Qiniu Cloud Kodo"].includes(this.state.provider.type) ? null : (
{["Custom HTTP SMS", "MinIO", "Google Cloud Storage", "Qiniu Cloud Kodo", "Synology"].includes(this.state.provider.type) ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={2}>
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :

View File

@@ -207,6 +207,10 @@ export const OtherProviderInfo = {
logo: `${StaticBaseUrl}/img/social_google_cloud.png`,
url: "https://cloud.google.com/storage",
},
"Synology": {
logo: `${StaticBaseUrl}/img/social_synology.png`,
url: "https://www.synology.com/en-global/dsm/feature/file_sharing",
},
},
SAML: {
"Aliyun IDaaS": {
@@ -1024,6 +1028,7 @@ export function getProviderTypeOptions(category) {
{id: "Azure Blob", name: "Azure Blob"},
{id: "Qiniu Cloud Kodo", name: "Qiniu Cloud Kodo"},
{id: "Google Cloud Storage", name: "Google Cloud Storage"},
{id: "Synology", name: "Synology"},
]
);
} else if (category === "SAML") {
@@ -1131,36 +1136,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) {
if (application) {
return application.signinMethods.filter(item => item.name === "LDAP").length > 0;
} else {
return false;
}
return isSigninMethodEnabled(application, "LDAP");
}
export function getLoginLink(application) {

View File

@@ -146,7 +146,7 @@ export function getWechatMessageEvent() {
}
export function getCaptchaStatus(values) {
return fetch(`${Setting.ServerUrl}/api/get-captcha-status?organization=${values["organization"]}&user_id=${values["username"]}`, {
return fetch(`${Setting.ServerUrl}/api/get-captcha-status?organization=${values["organization"]}&userId=${values["username"]}`, {
method: "GET",
credentials: "include",
headers: {

View File

@@ -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": {
@@ -588,6 +588,10 @@ class LoginPage extends React.Component {
},
{
validator: (_, value) => {
if (value === "") {
return Promise.resolve();
}
if (this.state.loginMethod === "verificationCode") {
if (!Setting.isValidEmail(value) && !Setting.isValidPhone(value)) {
this.setState({validEmailOrPhone: false});
@@ -937,7 +941,7 @@ class LoginPage extends React.Component {
[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;

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"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",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"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",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"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",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"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",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "モデル",
"Name": "名前",
"Name - Tooltip": "ユニークで文字列ベースのID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuthプロバイダー",
@@ -887,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",
@@ -1053,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": "新しいユーザー",
@@ -1092,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の資格情報",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "모델들",
"Name": "이름",
"Name - Tooltip": "고유한 문자열 기반 ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth 공급자",
@@ -887,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",
@@ -1053,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": "새로운 사용자",
@@ -1092,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": "웹 인증 자격증명",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"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",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Модели",
"Name": "Имя",
"Name - Tooltip": "Уникальный идентификатор на основе строки",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "Провайдеры OAuth",
@@ -887,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",
@@ -1053,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": "Новый пользователь",
@@ -1092,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 удостоверения",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Models",
"Name": "Name",
"Name - Tooltip": "Unique, string-based ID",
"Name format": "Name format",
"Non-LDAP": "Non-LDAP",
"None": "None",
"OAuth providers": "OAuth providers",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"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",
@@ -887,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",
@@ -1053,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",
@@ -1092,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",

View File

@@ -267,6 +267,7 @@
"Models": "Casbin模型",
"Name": "名称",
"Name - Tooltip": "唯一的、字符串式的ID",
"Name format": "名称格式",
"Non-LDAP": "禁用LDAP",
"None": "无",
"OAuth providers": "OAuth提供方",
@@ -887,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",
@@ -1053,8 +1055,6 @@
"Managed accounts": "托管账户",
"Modify password...": "编辑密码...",
"Multi-factor authentication": "多因素认证",
"Name": "Name",
"Name format": "Name format",
"New Email": "新邮箱",
"New Password": "新密码",
"New User": "添加用户",
@@ -1092,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凭据",

View File

@@ -193,7 +193,7 @@ class ProviderTable extends React.Component {
title: i18next.t("application:Rule"),
dataIndex: "rule",
key: "rule",
width: "100px",
width: "120px",
render: (text, record, index) => {
if (record.provider?.type === "Google") {
if (text === "None") {

View File

@@ -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",

View File

@@ -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 = {
@@ -163,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>
);
@@ -198,4 +198,4 @@ class SigninTable extends React.Component {
}
}
export default SigninTable;
export default SigninMethodTable;

View File

@@ -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",