mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-16 02:43:50 +08:00
Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
404382f2e0 | |||
71db1f62a9 | |||
07dc6bf7cd | |||
2de3f6772d | |||
3f623570fd | |||
a5dfe54a33 | |||
7c4a6fea02 | |||
ff4af6bb4e | |||
5bdede5596 | |||
ed052b0e6a | |||
16b1d0e1f0 | |||
fea2a8cdbe | |||
9d55238cef | |||
8427d63872 | |||
e8a7b7ee9c | |||
f8bc87eb4e | |||
3e6ef9e666 | |||
ef3d323f63 | |||
aad9201b24 | |||
46f090361e | |||
1ae6adff8e | |||
59c95ca8a0 | |||
ca1b5feb78 | |||
e50c832ff9 | |||
8696b08db2 | |||
d21ae8a478 | |||
db401b2046 | |||
7181489da0 | |||
e21087aa50 | |||
b38f2218a3 | |||
afd3c4ed25 | |||
5caceb4ae2 | |||
f5672357e6 | |||
181e7c8c7d | |||
36c5a9d09b | |||
9acb3c499e | |||
0e9a3b0f30 | |||
d104a292e7 | |||
8fbd5b1a74 | |||
f5a05ac534 | |||
05fade1d05 | |||
8aefa02036 | |||
3b6ec3e7c4 | |||
910816c7a3 |
61
.github/workflows/migrate.yml
vendored
Normal file
61
.github/workflows/migrate.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
name: Migration Test
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'object/migrator**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'object/migrator**'
|
||||
|
||||
jobs:
|
||||
|
||||
db-migrator-test:
|
||||
name: db-migrator-test
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
env:
|
||||
MYSQL_DATABASE: casdoor
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
ports:
|
||||
- 3306:3306
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16.5'
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
- name: pull casdoor-master-latest
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install git
|
||||
sudo apt install net-tools
|
||||
sudo mkdir tmp
|
||||
cd tmp
|
||||
sudo git clone https://github.com/casdoor/casdoor.git
|
||||
cd ..
|
||||
working-directory: ./
|
||||
- name: run casdoor-master-latest
|
||||
run: |
|
||||
sudo nohup go run main.go &
|
||||
sudo sleep 2m
|
||||
working-directory: ./tmp/casdoor
|
||||
- name: stop casdoor-master-latest
|
||||
run: |
|
||||
sudo kill -9 `sudo netstat -anltp | grep 8000 | awk '{print $7}' | cut -d / -f 1`
|
||||
working-directory: ./
|
||||
- name: run casdoor-current-version
|
||||
run: |
|
||||
sudo nohup go run ./main.go &
|
||||
sudo sleep 2m
|
||||
working-directory: ./
|
||||
- name: test port-8000
|
||||
run: |
|
||||
if [[ `sudo netstat -anltp | grep 8000 | awk '{print $7}'` == "" ]];then echo 'db-migrator-test fail' && exit 1;fi;
|
||||
echo 'db-migrator-test pass'
|
||||
working-directory: ./
|
@ -80,7 +80,7 @@ m = (r.subOwner == p.subOwner || p.subOwner == "*") && \
|
||||
p, built-in, *, *, *, *, *
|
||||
p, app, *, *, *, *, *
|
||||
p, *, *, POST, /api/signup, *, *
|
||||
p, *, *, POST, /api/get-email-and-phone, *, *
|
||||
p, *, *, GET, /api/get-email-and-phone, *, *
|
||||
p, *, *, POST, /api/login, *, *
|
||||
p, *, *, GET, /api/get-app-login, *, *
|
||||
p, *, *, POST, /api/logout, *, *
|
||||
@ -160,7 +160,7 @@ func IsAllowed(subOwner string, subName string, method string, urlPath string, o
|
||||
|
||||
func isAllowedInDemoMode(subOwner string, subName string, method string, urlPath string, objOwner string, objName string) bool {
|
||||
if method == "POST" {
|
||||
if strings.HasPrefix(urlPath, "/api/login") || urlPath == "/api/logout" || urlPath == "/api/signup" || urlPath == "/api/send-verification-code" || urlPath == "/api/send-email" {
|
||||
if strings.HasPrefix(urlPath, "/api/login") || urlPath == "/api/logout" || urlPath == "/api/signup" || urlPath == "/api/send-verification-code" || urlPath == "/api/send-email" || urlPath == "/api/verify-captcha" {
|
||||
return true
|
||||
} else if urlPath == "/api/update-user" {
|
||||
// Allow ordinary users to update their own information
|
||||
|
@ -31,6 +31,16 @@ import (
|
||||
|
||||
const AliyunCaptchaVerifyUrl = "http://afs.aliyuncs.com"
|
||||
|
||||
type captchaSuccessResponse struct {
|
||||
Code int `json:"Code"`
|
||||
Msg string `json:"Msg"`
|
||||
}
|
||||
|
||||
type captchaFailResponse struct {
|
||||
Code string `json:"Code"`
|
||||
Message string `json:"Message"`
|
||||
}
|
||||
|
||||
type AliyunCaptchaProvider struct{}
|
||||
|
||||
func NewAliyunCaptchaProvider() *AliyunCaptchaProvider {
|
||||
@ -85,19 +95,20 @@ func (captcha *AliyunCaptchaProvider) VerifyCaptcha(token, clientSecret string)
|
||||
return false, err
|
||||
}
|
||||
|
||||
type captchaResponse struct {
|
||||
Code int `json:"Code"`
|
||||
Msg string `json:"Msg"`
|
||||
return handleCaptchaResponse(body)
|
||||
}
|
||||
captchaResp := &captchaResponse{}
|
||||
|
||||
err = json.Unmarshal(body, captchaResp)
|
||||
func handleCaptchaResponse(body []byte) (bool, error) {
|
||||
captchaResp := &captchaSuccessResponse{}
|
||||
err := json.Unmarshal(body, captchaResp)
|
||||
if err != nil {
|
||||
captchaFailResp := &captchaFailResponse{}
|
||||
err = json.Unmarshal(body, captchaFailResp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if captchaResp.Code != 100 {
|
||||
return false, errors.New(captchaResp.Msg)
|
||||
return false, errors.New(captchaFailResp.Message)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
|
@ -106,12 +106,15 @@ func GetConfigDataSourceName() string {
|
||||
}
|
||||
|
||||
func GetLanguage(language string) string {
|
||||
if language == "" {
|
||||
if language == "" || language == "*" {
|
||||
return "en"
|
||||
}
|
||||
|
||||
if len(language) < 2 {
|
||||
return "en"
|
||||
}
|
||||
|
||||
language = language[0:2]
|
||||
|
||||
if strings.Contains(GetConfigString("languages"), language) {
|
||||
return language
|
||||
} else {
|
||||
|
@ -246,19 +246,24 @@ func (c *ApiController) Signup() {
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /logout [get,post]
|
||||
func (c *ApiController) Logout() {
|
||||
user := c.GetSessionUsername()
|
||||
|
||||
// https://openid.net/specs/openid-connect-rpinitiated-1_0-final.html
|
||||
accessToken := c.Input().Get("id_token_hint")
|
||||
redirectUri := c.Input().Get("post_logout_redirect_uri")
|
||||
state := c.Input().Get("state")
|
||||
|
||||
if accessToken == "" && redirectUri == "" {
|
||||
c.ClearUserSession()
|
||||
// TODO https://github.com/casdoor/casdoor/pull/1494#discussion_r1095675265
|
||||
owner, username := util.GetOwnerAndNameFromId(user)
|
||||
user := c.GetSessionUsername()
|
||||
|
||||
if accessToken == "" && redirectUri == "" {
|
||||
// TODO https://github.com/casdoor/casdoor/pull/1494#discussion_r1095675265
|
||||
if user == "" {
|
||||
c.ResponseOk()
|
||||
return
|
||||
}
|
||||
|
||||
c.ClearUserSession()
|
||||
owner, username := util.GetOwnerAndNameFromId(user)
|
||||
object.DeleteSessionId(util.GetSessionId(owner, username, object.CasdoorApplication), c.Ctx.Input.CruSession.SessionID())
|
||||
|
||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||
|
||||
application := c.GetSessionApplication()
|
||||
@ -296,7 +301,9 @@ func (c *ApiController) Logout() {
|
||||
|
||||
c.ClearUserSession()
|
||||
// TODO https://github.com/casdoor/casdoor/pull/1494#discussion_r1095675265
|
||||
object.DeleteSessionId(util.GetSessionId(object.CasdoorOrganization, object.CasdoorApplication, user), c.Ctx.Input.CruSession.SessionID())
|
||||
owner, username := util.GetOwnerAndNameFromId(user)
|
||||
|
||||
object.DeleteSessionId(util.GetSessionId(owner, username, object.CasdoorApplication), c.Ctx.Input.CruSession.SessionID())
|
||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||
|
||||
c.Ctx.Redirect(http.StatusFound, fmt.Sprintf("%s?state=%s", strings.TrimRight(redirectUri, "/"), state))
|
||||
|
@ -97,8 +97,7 @@ func (c *ApiController) GetLdapUser() {
|
||||
})
|
||||
}
|
||||
|
||||
c.Data["json"] = Response{Status: "ok", Data: resp}
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(resp)
|
||||
}
|
||||
|
||||
// GetLdaps
|
||||
@ -108,8 +107,7 @@ func (c *ApiController) GetLdapUser() {
|
||||
func (c *ApiController) GetLdaps() {
|
||||
owner := c.Input().Get("owner")
|
||||
|
||||
c.Data["json"] = Response{Status: "ok", Data: object.GetLdaps(owner)}
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetLdaps(owner))
|
||||
}
|
||||
|
||||
// GetLdap
|
||||
@ -124,8 +122,8 @@ func (c *ApiController) GetLdap() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = Response{Status: "ok", Data: object.GetLdap(id)}
|
||||
c.ServeJSON()
|
||||
_, name := util.GetOwnerAndNameFromId(id)
|
||||
c.ResponseOk(object.GetLdap(name))
|
||||
}
|
||||
|
||||
// AddLdap
|
||||
@ -159,8 +157,7 @@ func (c *ApiController) AddLdap() {
|
||||
object.GetLdapAutoSynchronizer().StartAutoSync(ldap.Id)
|
||||
}
|
||||
|
||||
c.Data["json"] = resp
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(resp)
|
||||
}
|
||||
|
||||
// UpdateLdap
|
||||
@ -187,8 +184,7 @@ func (c *ApiController) UpdateLdap() {
|
||||
object.GetLdapAutoSynchronizer().StopAutoSync(ldap.Id)
|
||||
}
|
||||
|
||||
c.Data["json"] = resp
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(resp)
|
||||
}
|
||||
|
||||
// DeleteLdap
|
||||
@ -204,8 +200,7 @@ func (c *ApiController) DeleteLdap() {
|
||||
}
|
||||
|
||||
object.GetLdapAutoSynchronizer().StopAutoSync(ldap.Id)
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteLdap(&ldap))
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(wrapActionResponse(object.DeleteLdap(&ldap)))
|
||||
}
|
||||
|
||||
// SyncLdapUsers
|
||||
@ -225,11 +220,11 @@ func (c *ApiController) SyncLdapUsers() {
|
||||
object.UpdateLdapSyncTime(ldapId)
|
||||
|
||||
exist, failed := object.SyncLdapUsers(owner, users, ldapId)
|
||||
c.Data["json"] = &Response{Status: "ok", Data: &LdapSyncResp{
|
||||
|
||||
c.ResponseOk(&LdapSyncResp{
|
||||
Exist: *exist,
|
||||
Failed: *failed,
|
||||
}}
|
||||
c.ServeJSON()
|
||||
})
|
||||
}
|
||||
|
||||
// CheckLdapUsersExist
|
||||
@ -246,6 +241,5 @@ func (c *ApiController) CheckLdapUsersExist() {
|
||||
}
|
||||
|
||||
exist := object.CheckLdapUuidExist(owner, uuids)
|
||||
c.Data["json"] = &Response{Status: "ok", Data: exist}
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(exist)
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@ -97,8 +98,11 @@ func (c *ApiController) SendEmail() {
|
||||
return
|
||||
}
|
||||
|
||||
code := "123456"
|
||||
// "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes."
|
||||
content := fmt.Sprintf(emailForm.Content, code)
|
||||
for _, receiver := range emailForm.Receivers {
|
||||
err = object.SendEmail(provider, emailForm.Title, emailForm.Content, receiver, emailForm.Sender)
|
||||
err = object.SendEmail(provider, emailForm.Title, content, receiver, emailForm.Sender)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
@ -130,18 +134,9 @@ func (c *ApiController) SendSms() {
|
||||
return
|
||||
}
|
||||
|
||||
var invalidReceivers []string
|
||||
for idx, receiver := range smsForm.Receivers {
|
||||
// The receiver phone format: E164 like +8613854673829 +441932567890
|
||||
if !util.IsPhoneValid(receiver, "") {
|
||||
invalidReceivers = append(invalidReceivers, receiver)
|
||||
} else {
|
||||
smsForm.Receivers[idx] = receiver
|
||||
}
|
||||
}
|
||||
|
||||
invalidReceivers := getInvalidSmsReceivers(smsForm)
|
||||
if len(invalidReceivers) != 0 {
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), invalidReceivers))
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), strings.Join(invalidReceivers, ", ")))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -15,16 +15,9 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
type SystemInfo struct {
|
||||
MemoryUsed uint64 `json:"memory_used"`
|
||||
MemoryTotal uint64 `json:"memory_total"`
|
||||
CpuUsage []float64 `json:"cpu_usage"`
|
||||
}
|
||||
|
||||
// GetSystemInfo
|
||||
// @Title GetSystemInfo
|
||||
// @Tag System API
|
||||
@ -33,50 +26,32 @@ type SystemInfo struct {
|
||||
// @Success 200 {object} object.SystemInfo The Response object
|
||||
// @router /get-system-info [get]
|
||||
func (c *ApiController) GetSystemInfo() {
|
||||
id := c.GetString("id")
|
||||
if id == "" {
|
||||
id = c.GetSessionUsername()
|
||||
}
|
||||
|
||||
user := object.GetUser(id)
|
||||
if user == nil || !user.IsGlobalAdmin {
|
||||
c.ResponseError(c.T("auth:Unauthorized operation"))
|
||||
_, ok := c.RequireAdmin()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
cpuUsage, err := util.GetCpuUsage()
|
||||
systemInfo, err := util.GetSystemInfo()
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
memoryUsed, memoryTotal, err := util.GetMemoryUsage()
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
c.ResponseOk(systemInfo)
|
||||
}
|
||||
|
||||
c.Data["json"] = SystemInfo{
|
||||
CpuUsage: cpuUsage,
|
||||
MemoryUsed: memoryUsed,
|
||||
MemoryTotal: memoryTotal,
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GitRepoVersion
|
||||
// @Title GitRepoVersion
|
||||
// GetVersionInfo
|
||||
// @Title GetVersionInfo
|
||||
// @Tag System API
|
||||
// @Description get local github repo's latest release version info
|
||||
// @Success 200 {string} local latest version hash of casdoor
|
||||
// @router /get-release [get]
|
||||
func (c *ApiController) GitRepoVersion() {
|
||||
version, err := util.GetGitRepoVersion()
|
||||
// @Description get local git repo's latest release version info
|
||||
// @Success 200 {string} local latest version hash of Casdoor
|
||||
// @router /get-version-info [get]
|
||||
func (c *ApiController) GetVersionInfo() {
|
||||
versionInfo, err := util.GetVersionInfo()
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = version
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(versionInfo)
|
||||
}
|
||||
|
@ -231,24 +231,20 @@ func (c *ApiController) DeleteUser() {
|
||||
// @Param username formData string true "The username of the user"
|
||||
// @Param organization formData string true "The organization of the user"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /get-email-and-phone [post]
|
||||
// @router /get-email-and-phone [get]
|
||||
func (c *ApiController) GetEmailAndPhone() {
|
||||
var form RequestForm
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &form)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
organization := c.Ctx.Request.Form.Get("organization")
|
||||
username := c.Ctx.Request.Form.Get("username")
|
||||
|
||||
user := object.GetUserByFields(form.Organization, form.Username)
|
||||
user := object.GetUserByFields(organization, username)
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(organization, username)))
|
||||
return
|
||||
}
|
||||
|
||||
respUser := object.User{Name: user.Name}
|
||||
var contentType string
|
||||
switch form.Username {
|
||||
switch username {
|
||||
case user.Email:
|
||||
contentType = "email"
|
||||
respUser.Email = user.Email
|
||||
@ -281,7 +277,7 @@ func (c *ApiController) SetPassword() {
|
||||
newPassword := c.Ctx.Request.Form.Get("newPassword")
|
||||
|
||||
requestUserId := c.GetSessionUsername()
|
||||
userId := fmt.Sprintf("%s/%s", userOwner, userName)
|
||||
userId := util.GetId(userOwner, userName)
|
||||
|
||||
hasPermission, err := object.CheckUserPermission(requestUserId, userId, userOwner, true, c.GetAcceptLanguage())
|
||||
if !hasPermission {
|
||||
@ -311,8 +307,7 @@ func (c *ApiController) SetPassword() {
|
||||
|
||||
targetUser.Password = newPassword
|
||||
object.SetUserField(targetUser, "password", targetUser.Password)
|
||||
c.Data["json"] = Response{Status: "ok"}
|
||||
c.ServeJSON()
|
||||
c.ResponseOk()
|
||||
}
|
||||
|
||||
// CheckUserPassword
|
||||
|
@ -197,3 +197,14 @@ func checkQuotaForUser(count int) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getInvalidSmsReceivers(smsForm SmsForm) []string {
|
||||
var invalidReceivers []string
|
||||
for _, receiver := range smsForm.Receivers {
|
||||
// The receiver phone format: E164 like +8613854673829 +441932567890
|
||||
if !util.IsPhoneValid(receiver, "") {
|
||||
invalidReceivers = append(invalidReceivers, receiver)
|
||||
}
|
||||
}
|
||||
return invalidReceivers
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ func (c *ApiController) SendVerificationCode() {
|
||||
dest := c.Ctx.Request.Form.Get("dest")
|
||||
countryCode := c.Ctx.Request.Form.Get("countryCode")
|
||||
checkType := c.Ctx.Request.Form.Get("checkType")
|
||||
checkId := c.Ctx.Request.Form.Get("checkId")
|
||||
checkKey := c.Ctx.Request.Form.Get("checkKey")
|
||||
clientSecret := c.Ctx.Request.Form.Get("clientSecret")
|
||||
captchaToken := c.Ctx.Request.Form.Get("captchaToken")
|
||||
applicationId := c.Ctx.Request.Form.Get("applicationId")
|
||||
method := c.Ctx.Request.Form.Get("method")
|
||||
checkUser := c.Ctx.Request.Form.Get("checkUser")
|
||||
@ -76,15 +76,15 @@ func (c *ApiController) SendVerificationCode() {
|
||||
}
|
||||
|
||||
if checkType != "none" {
|
||||
if checkKey == "" {
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": checkKey.")
|
||||
if captchaToken == "" {
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": captchaToken.")
|
||||
return
|
||||
}
|
||||
|
||||
if captchaProvider := captcha.GetCaptchaProvider(checkType); captchaProvider == nil {
|
||||
c.ResponseError(c.T("general:don't support captchaProvider: ") + checkType)
|
||||
return
|
||||
} else if isHuman, err := captchaProvider.VerifyCaptcha(checkKey, checkId); err != nil {
|
||||
} else if isHuman, err := captchaProvider.VerifyCaptcha(captchaToken, clientSecret); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
} else if !isHuman {
|
||||
|
@ -21,8 +21,8 @@ import (
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/duo-labs/webauthn/protocol"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
"github.com/go-webauthn/webauthn/webauthn"
|
||||
)
|
||||
|
||||
// WebAuthnSignupBegin
|
||||
|
23
go.mod
23
go.mod
@ -3,27 +3,30 @@ module github.com/casdoor/casdoor
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Masterminds/squirrel v1.5.3
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.62.188 // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.4
|
||||
github.com/beego/beego v1.12.11
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/casbin/casbin/v2 v2.30.1
|
||||
github.com/casdoor/go-sms-sender v0.5.2
|
||||
github.com/casdoor/go-sms-sender v0.6.1
|
||||
github.com/casdoor/gomail/v2 v2.0.1
|
||||
github.com/casdoor/oss v1.2.0
|
||||
github.com/casdoor/xorm-adapter/v3 v3.0.4
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
github.com/denisenkom/go-mssqldb v0.9.0
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
|
||||
github.com/forestmgy/ldapserver v1.1.0
|
||||
github.com/go-git/go-git/v5 v5.6.0
|
||||
github.com/go-ldap/ldap/v3 v3.3.0
|
||||
github.com/go-mysql-org/go-mysql v1.7.0
|
||||
github.com/go-pay/gopay v1.5.72
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-webauthn/webauthn v0.8.2
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/lestrrat-go/jwx v1.2.21
|
||||
github.com/lib/pq v1.8.0
|
||||
@ -37,18 +40,18 @@ require (
|
||||
github.com/russellhaering/goxmldsig v1.1.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/tealeg/xlsx v1.0.5
|
||||
github.com/thanhpk/randstr v1.0.4
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/xorm-io/core v0.7.4
|
||||
github.com/xorm-io/xorm v1.1.6
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
|
||||
golang.org/x/crypto v0.6.0
|
||||
golang.org/x/net v0.6.0
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||
|
284
go.sum
284
go.sum
@ -58,8 +58,17 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Masterminds/squirrel v1.5.3 h1:YPpoceAcxuzIljlr5iWpNKaql7hLeG1KLSrhvdHpkZc=
|
||||
github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b h1:EgJ6N2S0h1WfFIjU5/VVHWbMSVYXAluop97Qxpr/lfQ=
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b/go.mod h1:3SAoF0F5EbcOuBD5WT9nYkbIJieBS84cUQXADbXeBsU=
|
||||
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
||||
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@ -68,10 +77,16 @@ github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387 h1:loy0fjI90v
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387/go.mod h1:GuR5j/NW7AU7tDAQUDGCtpiPxWIOy/c3kiRDnlwiCHc=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1075 h1:Z0SzZttfYI/raZ5O9WF3cezZJTSW4Yz4Kow9uWdyRwg=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1075/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.62.188 h1:8lIVcOlHW+fKCGMEf6nuGTTEFOt/EZJPZ8oq0kTlhGk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.62.188/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/aws/aws-sdk-go v1.44.4 h1:ePN0CVJMdiz2vYUcJH96eyxRrtKGSDMgyhP6rah2OgE=
|
||||
github.com/aws/aws-sdk-go v1.44.4/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
@ -83,19 +98,22 @@ github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkY
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
|
||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ=
|
||||
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||
github.com/casbin/casbin/v2 v2.1.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/casbin/casbin/v2 v2.28.3/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/casbin/casbin/v2 v2.30.1 h1:P5HWadDL7olwUXNdcuKUBk+x75Y2eitFxYTcLNKeKF0=
|
||||
github.com/casbin/casbin/v2 v2.30.1/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/casdoor/go-sms-sender v0.5.2 h1:LRjqoXBAOsH4yxXeJ7kINMesyoyEx5pEoiJz9d7lGJA=
|
||||
github.com/casdoor/go-sms-sender v0.5.2/go.mod h1:kBykbqwgRDXbXdMAIxmZKinVM1WjdqEbej5LAbUbcfI=
|
||||
github.com/casdoor/go-sms-sender v0.6.1 h1:35HuxpuQ0jGAoRE0/E5lAchYpeoFwaB5NGsEA52/t9c=
|
||||
github.com/casdoor/go-sms-sender v0.6.1/go.mod h1:kBykbqwgRDXbXdMAIxmZKinVM1WjdqEbej5LAbUbcfI=
|
||||
github.com/casdoor/gomail/v2 v2.0.1 h1:J+FG6x80s9e5lBHUn8Sv0Y56mud34KiWih5YdmudR/w=
|
||||
github.com/casdoor/gomail/v2 v2.0.1/go.mod h1:VnGPslEAtpix5FjHisR/WKB1qvZDBaujbikxDe9d+2Q=
|
||||
github.com/casdoor/oss v1.2.0 h1:ozLAE+nnNdFQBWbzH8U9spzaO8h8NrB57lBcdyMUUQ8=
|
||||
@ -103,21 +121,34 @@ github.com/casdoor/oss v1.2.0/go.mod h1:qii35VBuxnR/uEuYSKpS0aJ8htQFOcCVsZ4FHgHL
|
||||
github.com/casdoor/xorm-adapter/v3 v3.0.4 h1:vB04Ao8n2jA7aFBI9F+gGXo9+Aa1IQP6mTdo50913DM=
|
||||
github.com/casdoor/xorm-adapter/v3 v3.0.4/go.mod h1:4WTcUw+bTgBylGHeGHzTtBvuTXRS23dtwzFLl9tsgFM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7 h1:Puu1hUwfps3+1CUzYdAZXijuvLuRMirgiXdf3zsM2Ig=
|
||||
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY=
|
||||
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20201216133707-c04035124b17/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
|
||||
github.com/couchbase/gomemcached v0.1.2-0.20201224031647-c432ccf49f32/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo=
|
||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
|
||||
github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -128,14 +159,16 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b h1:L63RATZFZuFMXy6ixnKmv3eNAXwYQF6HW1vd4IYsQqQ=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@ -145,11 +178,23 @@ github.com/forestmgy/ldapserver v1.1.0/go.mod h1:1RZ8lox1QSY7rmbjdmy+sYQXY4Lp7Sp
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ=
|
||||
github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
|
||||
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
|
||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.4.0 h1:Vaw7LaSTRJOUric7pe4vnzBSgyuf2KrLsu2Y4ZpQBDE=
|
||||
github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
||||
github.com/go-git/go-git/v5 v5.6.0 h1:JvBdYfcttd+0kdpuWO7KTu0FYgCf5W0t5VwkWGobaa4=
|
||||
github.com/go-git/go-git/v5 v5.6.0/go.mod h1:6nmJ0tJ3N4noMV1Omv7rC5FG3/o8Cm51TB4CJp7mRmE=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@ -159,6 +204,8 @@ github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ
|
||||
github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-mysql-org/go-mysql v1.7.0 h1:qE5FTRb3ZeTQmlk3pjE+/m2ravGxxRDrVDTyDe9tvqI=
|
||||
github.com/go-mysql-org/go-mysql v1.7.0/go.mod h1:9cRWLtuXNKhamUPMkrDVzBhaomGvqLRLtBiyjvjc4pk=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-pay/gopay v1.5.72 h1:3zm64xMBhJBa8rXbm//q5UiGgOa4WO5XYEnU394N2Zw=
|
||||
@ -171,21 +218,28 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
|
||||
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-webauthn/revoke v0.1.9 h1:gSJ1ckA9VaKA2GN4Ukp+kiGTk1/EXtaDb1YE8RknbS0=
|
||||
github.com/go-webauthn/revoke v0.1.9/go.mod h1:j6WKPnv0HovtEs++paan9g3ar46gm1NarktkXBaPR+w=
|
||||
github.com/go-webauthn/webauthn v0.8.2 h1:8KLIbpldjz9KVGHfqEgJNbkhd7bbRXhNw4QWFJE15oA=
|
||||
github.com/go-webauthn/webauthn v0.8.2/go.mod h1:d+ezx/jMCNDiqSMzOchuynKb9CVU1NM9BumOnokfcVQ=
|
||||
github.com/goccy/go-json v0.9.6 h1:5/4CtRQdtsX0sal8fdVhTaiMN01Ri8BExZZ8iRmHQ6E=
|
||||
github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -221,8 +275,6 @@ github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNu
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
@ -232,8 +284,14 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-tpm v0.1.2-0.20190725015402-ae6dd98980d4/go.mod h1:H9HbmUG2YgV/PHITkO7p6wxEEj/v5nlsVWIwumwH2NI=
|
||||
github.com/google/go-tpm v0.3.0/go.mod h1:iVLWvrPp/bHeEkxTFi9WG6K9w0iy2yIszHwZGHPbzAw=
|
||||
github.com/google/go-tpm v0.3.3 h1:P/ZFNBZYXRxc+z7i5uyd8VP7MaDteuLZInzrH2idRGo=
|
||||
github.com/google/go-tpm v0.3.3/go.mod h1:9Hyn3rgnzWF9XBWVk6ml6A6hNkbWjNFlDQL51BeghL4=
|
||||
github.com/google/go-tpm-tools v0.0.0-20190906225433-1614c142f845/go.mod h1:AVfHadzbdzHo54inR2x1v640jdi1YSi3NauM2DUsxk0=
|
||||
github.com/google/go-tpm-tools v0.2.0/go.mod h1:npUd03rQ60lxN7tzeBJreG38RvWwme2N1reF/eeiBk4=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@ -247,8 +305,9 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
@ -260,15 +319,26 @@ github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5
|
||||
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk=
|
||||
github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jinzhu/configor v1.2.1 h1:OKk9dsR8i6HPOCZR8BcMtcEImAFjIhbJFZNyn5GCZko=
|
||||
github.com/jinzhu/configor v1.2.1/go.mod h1:nX89/MOmDba7ZX7GCyU/VIaQ2Ar2aizBl2d3JLF/rDc=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
@ -276,6 +346,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
@ -292,6 +364,9 @@ github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uia
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
@ -304,6 +379,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
|
||||
@ -319,15 +398,19 @@ github.com/lestrrat-go/jwx v1.2.21/go.mod h1:9cfxnOH7G1gN75CaJP2hKGcxFEx5sPh1abR
|
||||
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
|
||||
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3 h1:wIONC+HMNRqmWBjuMxhatuSzHaljStc4gjDeKycxy0A=
|
||||
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3/go.mod h1:37YR9jabpiIxsb8X9VCIx8qFOjTDIIrIHHODa8C4gz0=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0=
|
||||
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
|
||||
github.com/markbates/goth v1.75.2 h1:C7KloBMMk50JyXaHhzfqWYLW6+bDcSVIvUGHXneLWro=
|
||||
github.com/markbates/goth v1.75.2/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc=
|
||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911 h1:erppMjjp69Rertg1zlgRbLJH1u+eCmRPxKjMZ5I8/Ro=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
|
||||
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
|
||||
@ -340,8 +423,11 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJK
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@ -356,6 +442,7 @@ github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
|
||||
github.com/nyaruka/phonenumbers v1.1.5 h1:vYy2DI+z5hdaemqVzXYJ4CVyK92IG484CirEY+40GTo=
|
||||
github.com/nyaruka/phonenumbers v1.1.5/go.mod h1:yShPJHDSH3aTKzCbXyVxNpbl2kA+F+Ne5Pun/MvFRos=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
|
||||
@ -363,8 +450,22 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
|
||||
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg=
|
||||
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ=
|
||||
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOPik4N4lPDaUcLDF/EQPogxtlHB2ZZRM=
|
||||
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg=
|
||||
github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7 h1:k2BbABz9+TNpYRwsCCFS8pEEnFVOdbgEjL/kTlLuzZQ=
|
||||
github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM=
|
||||
github.com/pingcap/tidb/parser v0.0.0-20221126021158-6b02a5d8ba7d h1:1DyyRrgYeNjqPkgjrdEsaIbX+kHpuTTk5ZOCtrcRFcQ=
|
||||
github.com/pingcap/tidb/parser v0.0.0-20221126021158-6b02a5d8ba7d/go.mod h1:ElJiub4lRy6UZDb+0JHDkGEdr6aOli+ykhyej7VCLoI=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -373,6 +474,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U=
|
||||
github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
@ -381,13 +483,17 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0 h1:q0y8TPa/sTwtriJPRe8gWL++PuZ+XbOUuvKU+hvtTYs=
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0/go.mod h1:PElPB7b7HnGKTsuADAffFpOQXHqjEGJz1+U1a6yR5wA=
|
||||
github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
|
||||
@ -397,6 +503,7 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
@ -406,25 +513,51 @@ github.com/russellhaering/gosaml2 v0.6.0/go.mod h1:CtzxpPr4+bevsATaqR0rw3aqrNlX2
|
||||
github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o=
|
||||
github.com/russellhaering/goxmldsig v1.1.1 h1:vI0r2osGF1A9PLvsGdPUAGwEIrKa4Pj5sesSBsebIxM=
|
||||
github.com/russellhaering/goxmldsig v1.1.1/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4=
|
||||
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed h1:KMgQoLJGCq1IoZpLZE3AIffh9veYWoVlsvA4ib55TMM=
|
||||
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4=
|
||||
github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
|
||||
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@ -432,8 +565,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
@ -447,14 +581,25 @@ github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03O
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/twilio/twilio-go v0.26.0 h1:wFW4oTe3/LKt6bvByP7eio8JsjtaLHjMQKOUEzQry7U=
|
||||
github.com/twilio/twilio-go v0.26.0/go.mod h1:lz62Hopu4vicpQ056H5TJ0JE4AP0rS3sQ35/ejmgOwE=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.19 h1:jJp+aJgK0e//rZ9I0K2Y7ufJwvuZRo/AQsYDynXMNgA=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.19/go.mod h1:+GGi447k4p1I5PNdbpG2GLaF0Ui9vIInTojMM0IfSS4=
|
||||
github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xorm-io/builder v0.3.13 h1:J4oZxt4Gjgm/Si9iKazfzYwHB/ijEOD9EHInyjOSX+M=
|
||||
github.com/xorm-io/builder v0.3.13/go.mod h1:24o5riRwzre2WvjmN+LM4YpUtJg7W8MdvJ8H57rvrJA=
|
||||
github.com/xorm-io/core v0.7.4 h1:qIznlqqmYNEb03ewzRXCrNkbbxpkgc/44nVF8yoFV7Y=
|
||||
@ -466,21 +611,39 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.18.1 h1:CSUJ2mjFszzEWt4CdKISEuChVIXGBn3lAPwkRGyVrc4=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
@ -491,8 +654,15 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -514,6 +684,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
@ -523,18 +694,22 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@ -561,8 +736,13 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -582,10 +762,13 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -623,32 +806,51 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@ -665,6 +867,8 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@ -693,12 +897,14 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs=
|
||||
golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
@ -758,6 +964,7 @@ google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200929141702-51c3e5b607fe/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
@ -794,13 +1001,20 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@ -810,6 +1024,7 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@ -823,29 +1038,42 @@ modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009 h1:u0oCo5b9wyLr++HF3AN9J
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
|
||||
modernc.org/ccgo/v3 v3.9.0 h1:JbcEIqjw4Agf+0g3Tc85YvfYqkkFOv6xBwS4zkfqSoA=
|
||||
modernc.org/ccgo/v3 v3.9.0/go.mod h1:nQbgkn8mwzPdp4mm6BT6+p85ugQ7FrGgIcYaE7nSrpY=
|
||||
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
|
||||
modernc.org/golex v1.0.1/go.mod h1:QCA53QtsT1NdGkaZZkF5ezFwk4IXh4BGNafAARTC254=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/lex v1.0.0/go.mod h1:G6rxMTy3cH2iA0iXL/HRRv4Znu8MK4higxph/lE7ypk=
|
||||
modernc.org/lexer v1.0.0/go.mod h1:F/Dld0YKYdZCLQ7bD0USbWL4YKCyTDRDHiDTOs0q0vk=
|
||||
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.8.0 h1:Pp4uv9g0csgBMpGPABKtkieF6O5MGhfGo6ZiOdlYfR8=
|
||||
modernc.org/libc v1.8.0/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/parser v1.0.0/go.mod h1:H20AntYJ2cHHL6MHthJ8LZzXCdDCHMWt1KZXtIMjejA=
|
||||
modernc.org/parser v1.0.2/go.mod h1:TXNq3HABP3HMaqLK7brD1fLA/LfN0KS6JxZn71QdDqs=
|
||||
modernc.org/scanner v1.0.1/go.mod h1:OIzD2ZtjYk6yTuyqZr57FmifbM9fIH74SumloSsajuE=
|
||||
modernc.org/sortutil v1.0.0/go.mod h1:1QO0q8IlIlmjBIwm6t/7sof874+xCfZouyqZMLIAtxM=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84 h1:rgEUzE849tFlHSoeCrKyS9cZAljC+DY7MdMHKq6R6sY=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84/go.mod h1:PGzq6qlhyYjL6uVbSgS6WoF7ZopTW/sI7+7p+mb4ZVU=
|
||||
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/strutil v1.1.0 h1:+1/yCzZxY2pZwwrsbH+4T7BQMoLQ9QiBshRC9eicYsc=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/tcl v1.5.0 h1:euZSUNfE0Fd4W8VqXI1Ly1v7fqDJoBuAV88Ea+SnaSs=
|
||||
modernc.org/tcl v1.5.0/go.mod h1:gb57hj4pO8fRrK54zveIfFXBaMHK3SKJNWcmRw1cRzc=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/y v1.0.1/go.mod h1:Ho86I+LVHEI+LYXoUKlmOMAM1JTXOCfj8qi1T8PsClE=
|
||||
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc=
|
||||
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
@ -6,10 +6,18 @@
|
||||
"displayName": "",
|
||||
"websiteUrl": "",
|
||||
"favicon": "",
|
||||
"passwordType": "",
|
||||
"countryCodes": [""],
|
||||
"passwordType": "plain",
|
||||
"passwordSalt": "",
|
||||
"countryCodes": ["US", "ES", "CN", "FR", "DE", "GB", "JP", "KR", "VN", "ID", "SG", "IN"],
|
||||
"defaultAvatar": "",
|
||||
"tags": [""]
|
||||
"defaultApplication": "",
|
||||
"tags": [],
|
||||
"languages": ["en", "zh", "es", "fr", "de", "ja", "ko", "ru", "vi"],
|
||||
"masterPassword": "",
|
||||
"initScore": 2000,
|
||||
"enableSoftDeletion": false,
|
||||
"isProfilePublic": true,
|
||||
"accountItems": []
|
||||
}
|
||||
],
|
||||
"applications": [
|
||||
|
@ -1,23 +1,8 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: casdoor-config
|
||||
name: {{ printf "%s-config" (include "casdoor.fullname" .) }}
|
||||
labels:
|
||||
{{- include "casdoor.labels" . | nindent 4 }}
|
||||
data:
|
||||
app.conf: |
|
||||
appname = casdoor
|
||||
httpport = 80
|
||||
runmode = dev
|
||||
SessionOn = true
|
||||
copyrequestbody = true
|
||||
driverName = mysql
|
||||
dataSourceName = root:123456@tcp(localhost:3306)/
|
||||
dbName = casdoor
|
||||
redisEndpoint =
|
||||
defaultStorageProvider =
|
||||
isCloudIntranet = false
|
||||
authState = "casdoor"
|
||||
socks5Proxy = "127.0.0.1:10808"
|
||||
verificationCodeTimeout = 10
|
||||
initScore = 2000
|
||||
logPostOnly = true
|
||||
origin = "https://door.casbin.com"
|
||||
app.conf: {{ tpl .Values.config . | toYaml | nindent 4 }}
|
||||
|
@ -13,8 +13,9 @@ spec:
|
||||
{{- include "casdoor.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
checksum/config: {{ tpl .Values.config . | toYaml | sha256sum }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
@ -34,18 +35,25 @@ spec:
|
||||
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: 80
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
# livenessProbe:
|
||||
# httpGet:
|
||||
# path: /
|
||||
# port: http
|
||||
# readinessProbe:
|
||||
# httpGet:
|
||||
# path: /
|
||||
# port: http
|
||||
{{ 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:
|
||||
@ -60,7 +68,7 @@ spec:
|
||||
items:
|
||||
- key: app.conf
|
||||
path: app.conf
|
||||
name: casdoor-config
|
||||
name: {{ printf "%s-config" (include "casdoor.fullname" .) }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
|
@ -6,11 +6,31 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: casbin
|
||||
name: casdoor-all-in-one
|
||||
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 = 2000
|
||||
logPostOnly = true
|
||||
origin = "https://door.casbin.com"
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
@ -37,9 +57,15 @@ securityContext: {}
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
probe:
|
||||
readiness:
|
||||
enabled: true
|
||||
liveness:
|
||||
enabled: true
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
port: 8000
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
|
@ -380,7 +380,7 @@ func CheckToEnableCaptcha(application *Application) bool {
|
||||
if providerItem.Provider == nil {
|
||||
continue
|
||||
}
|
||||
if providerItem.Provider.Category == "Captcha" && providerItem.Provider.Type == "Default" {
|
||||
if providerItem.Provider.Category == "Captcha" {
|
||||
return providerItem.Rule == "Always"
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
"github.com/go-webauthn/webauthn/webauthn"
|
||||
)
|
||||
|
||||
func InitDb() {
|
||||
@ -86,12 +86,14 @@ func initBuiltInOrganization() bool {
|
||||
WebsiteUrl: "https://example.com",
|
||||
Favicon: fmt.Sprintf("%s/img/casbin/favicon.ico", conf.GetConfigString("staticBaseUrl")),
|
||||
PasswordType: "plain",
|
||||
CountryCodes: []string{"CN"},
|
||||
CountryCodes: []string{"US", "ES", "CN", "FR", "DE", "GB", "JP", "KR", "VN", "ID", "SG", "IN"},
|
||||
DefaultAvatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")),
|
||||
Tags: []string{},
|
||||
Languages: []string{"en", "zh", "es", "fr", "de", "ja", "ko", "ru", "vi"},
|
||||
InitScore: 2000,
|
||||
AccountItems: getBuiltInAccountItems(),
|
||||
EnableSoftDeletion: false,
|
||||
IsProfilePublic: false,
|
||||
}
|
||||
AddOrganization(organization)
|
||||
return false
|
||||
|
@ -43,7 +43,7 @@ type Payment struct {
|
||||
PayUrl string `xorm:"varchar(2000)" json:"payUrl"`
|
||||
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
|
||||
State string `xorm:"varchar(100)" json:"state"`
|
||||
Message string `xorm:"varchar(1000)" json:"message"`
|
||||
Message string `xorm:"varchar(2000)" json:"message"`
|
||||
|
||||
PersonName string `xorm:"varchar(100)" json:"personName"`
|
||||
PersonIdCard string `xorm:"varchar(100)" json:"personIdCard"`
|
||||
|
@ -80,7 +80,6 @@ func (p *PermissionRule) GetRequest(adapterName string, permissionId string) ([]
|
||||
if p.V5 != "" {
|
||||
return nil, fmt.Errorf("too many parameters. The maximum parameter number cannot exceed %d", builtInAvailableField)
|
||||
}
|
||||
request = append(request, permissionId)
|
||||
return request, nil
|
||||
} else {
|
||||
if p.V5 != "" {
|
||||
@ -245,6 +244,10 @@ func GetPermissionsByUser(userId string) []*Permission {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := range permissions {
|
||||
permissions[i].Users = nil
|
||||
}
|
||||
|
||||
return permissions
|
||||
}
|
||||
|
||||
|
@ -159,6 +159,10 @@ func GetRolesByUser(userId string) []*Role {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := range roles {
|
||||
roles[i].Users = nil
|
||||
}
|
||||
|
||||
return roles
|
||||
}
|
||||
|
||||
|
@ -230,16 +230,20 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
// base64 decode
|
||||
defated, err := base64.StdEncoding.DecodeString(samlRequest)
|
||||
if err != nil {
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, fmt.Errorf("err: Failed to decode SAML request , %s", err.Error())
|
||||
}
|
||||
|
||||
// decompress
|
||||
var buffer bytes.Buffer
|
||||
rdr := flate.NewReader(bytes.NewReader(defated))
|
||||
io.Copy(&buffer, rdr)
|
||||
_, err = io.Copy(&buffer, rdr)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
var authnRequest saml.AuthnRequest
|
||||
err = xml.Unmarshal(buffer.Bytes(), &authnRequest)
|
||||
if err != nil {
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, fmt.Errorf("err: Failed to unmarshal AuthnRequest, please check the SAML request. %s", err.Error())
|
||||
}
|
||||
|
||||
// verify samlRequest
|
||||
@ -252,14 +256,15 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
block, _ := pem.Decode([]byte(cert.Certificate))
|
||||
certificate := base64.StdEncoding.EncodeToString(block.Bytes)
|
||||
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
|
||||
// redirect Url (Assertion Consumer Url)
|
||||
if application.SamlReplyUrl != "" {
|
||||
method = "POST"
|
||||
authnRequest.AssertionConsumerServiceURL = application.SamlReplyUrl
|
||||
} else if authnRequest.AssertionConsumerServiceURL == "" {
|
||||
return "", "", "", fmt.Errorf("err: SAML request don't has attribute 'AssertionConsumerServiceURL' in <samlp:AuthnRequest>")
|
||||
}
|
||||
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
// build signedResponse
|
||||
samlResponse, _ := NewSamlResponse(user, originBackend, certificate, authnRequest.AssertionConsumerServiceURL, authnRequest.Issuer.Url, authnRequest.ID, application.RedirectUris)
|
||||
randomKeyStore := &X509Key{
|
||||
@ -279,7 +284,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
doc.SetRoot(samlResponse)
|
||||
xmlBytes, err := doc.WriteToBytes()
|
||||
if err != nil {
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, fmt.Errorf("err: Failed to serializes the SAML request into bytes, %s", err.Error())
|
||||
}
|
||||
|
||||
// compress
|
||||
@ -287,15 +292,21 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
flated := bytes.NewBuffer(nil)
|
||||
writer, err := flate.NewWriter(flated, flate.DefaultCompression)
|
||||
if err != nil {
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, err
|
||||
}
|
||||
_, err = writer.Write(xmlBytes)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
err = writer.Close()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
writer.Write(xmlBytes)
|
||||
writer.Close()
|
||||
xmlBytes = flated.Bytes()
|
||||
}
|
||||
// base64 encode
|
||||
res := base64.StdEncoding.EncodeToString(xmlBytes)
|
||||
return res, authnRequest.AssertionConsumerServiceURL, method, nil
|
||||
return res, authnRequest.AssertionConsumerServiceURL, method, err
|
||||
}
|
||||
|
||||
// NewSamlResponse11 return a saml1.1 response(not 2.0)
|
||||
@ -359,7 +370,10 @@ func NewSamlResponse11(user *User, requestID string, host string) *etree.Element
|
||||
|
||||
data, _ := json.Marshal(user)
|
||||
tmp := map[string]string{}
|
||||
json.Unmarshal(data, &tmp)
|
||||
err := json.Unmarshal(data, &tmp)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for k, v := range tmp {
|
||||
if v != "" {
|
||||
|
@ -17,26 +17,39 @@ package object
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/go-sms-sender"
|
||||
sender "github.com/casdoor/go-sms-sender"
|
||||
)
|
||||
|
||||
func SendSms(provider *Provider, content string, phoneNumbers ...string) error {
|
||||
client, err := go_sms_sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.AppId)
|
||||
if provider.Type == go_sms_sender.HuaweiCloud {
|
||||
client, err = go_sms_sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.ProviderUrl, provider.AppId)
|
||||
func getSmsClient(provider *Provider) (sender.SmsClient, error) {
|
||||
var client sender.SmsClient
|
||||
var err error
|
||||
|
||||
if provider.Type == sender.HuaweiCloud {
|
||||
client, err = sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.ProviderUrl, provider.AppId)
|
||||
} else {
|
||||
client, err = sender.NewSmsClient(provider.Type, provider.ClientId, provider.ClientSecret, provider.SignName, provider.TemplateCode, provider.AppId)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func SendSms(provider *Provider, content string, phoneNumbers ...string) error {
|
||||
client, err := getSmsClient(provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if provider.Type == go_sms_sender.Aliyun {
|
||||
if provider.Type == sender.Aliyun {
|
||||
for i, number := range phoneNumbers {
|
||||
phoneNumbers[i] = strings.TrimPrefix(number, "+")
|
||||
}
|
||||
}
|
||||
|
||||
params := map[string]string{}
|
||||
if provider.Type == go_sms_sender.TencentCloud {
|
||||
if provider.Type == sender.TencentCloud {
|
||||
params["0"] = content
|
||||
} else {
|
||||
params["code"] = content
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
"github.com/go-webauthn/webauthn/webauthn"
|
||||
"github.com/xorm-io/core"
|
||||
)
|
||||
|
||||
@ -172,8 +172,8 @@ type Userinfo struct {
|
||||
Sub string `json:"sub"`
|
||||
Iss string `json:"iss"`
|
||||
Aud string `json:"aud"`
|
||||
Name string `json:"name,omitempty"`
|
||||
DisplayName string `json:"preferred_username,omitempty"`
|
||||
Name string `json:"preferred_username,omitempty"`
|
||||
DisplayName string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Avatar string `json:"picture,omitempty"`
|
||||
Address string `json:"address,omitempty"`
|
||||
@ -449,7 +449,7 @@ func UpdateUser(id string, user *User, columns []string, isGlobalAdmin bool) boo
|
||||
if len(columns) == 0 {
|
||||
columns = []string{
|
||||
"owner", "display_name", "avatar",
|
||||
"location", "address", "region", "language", "affiliation", "title", "homepage", "bio", "score", "tag", "signup_application",
|
||||
"location", "address", "country_code", "region", "language", "affiliation", "title", "homepage", "bio", "score", "tag", "signup_application",
|
||||
"is_admin", "is_global_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts",
|
||||
"signin_wrong_times", "last_signin_wrong_time",
|
||||
}
|
||||
|
@ -53,10 +53,12 @@ func GetUserByFields(organization string, field string) *User {
|
||||
}
|
||||
|
||||
// check email
|
||||
if strings.Contains(field, "@") {
|
||||
user = GetUserByField(organization, "email", field)
|
||||
if user != nil {
|
||||
return user
|
||||
}
|
||||
}
|
||||
|
||||
// check phone
|
||||
user = GetUserByField(organization, "phone", field)
|
||||
|
@ -20,8 +20,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/duo-labs/webauthn/protocol"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
"github.com/go-webauthn/webauthn/webauthn"
|
||||
)
|
||||
|
||||
func GetWebAuthnObject(host string) *webauthn.WebAuthn {
|
||||
|
@ -112,7 +112,7 @@ func initAPI() {
|
||||
|
||||
beego.Router("/api/set-password", &controllers.ApiController{}, "POST:SetPassword")
|
||||
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
|
||||
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "POST:GetEmailAndPhone")
|
||||
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "GET:GetEmailAndPhone")
|
||||
beego.Router("/api/send-verification-code", &controllers.ApiController{}, "POST:SendVerificationCode")
|
||||
beego.Router("/api/verify-captcha", &controllers.ApiController{}, "POST:VerifyCaptcha")
|
||||
beego.Router("/api/reset-email-or-phone", &controllers.ApiController{}, "POST:ResetEmailOrPhone")
|
||||
@ -225,5 +225,5 @@ func initAPI() {
|
||||
beego.Router("/api/webauthn/signin/finish", &controllers.ApiController{}, "Post:WebAuthnSigninFinish")
|
||||
|
||||
beego.Router("/api/get-system-info", &controllers.ApiController{}, "GET:GetSystemInfo")
|
||||
beego.Router("/api/get-release", &controllers.ApiController{}, "GET:GitRepoVersion")
|
||||
beego.Router("/api/get-version-info", &controllers.ApiController{}, "GET:GetVersionInfo")
|
||||
}
|
||||
|
@ -339,6 +339,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-session": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Add session for one user in one application. If there are other existing sessions, join the session into the list.",
|
||||
"operationId": "ApiController.AddSession",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id(organization/application/user) of session",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "sessionId",
|
||||
"description": "sessionId to be added",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-syncer": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -889,13 +925,13 @@
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Delete session by userId",
|
||||
"description": "Delete session for one user in one application.",
|
||||
"operationId": "ApiController.DeleteSession",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id ( owner/name )(owner/name) of user.",
|
||||
"description": "The id(organization/application/user) of session",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
@ -1233,7 +1269,7 @@
|
||||
}
|
||||
},
|
||||
"/api/get-email-and-phone": {
|
||||
"post": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"User API"
|
||||
],
|
||||
@ -1306,7 +1342,7 @@
|
||||
}
|
||||
},
|
||||
"/api/get-ldap": {
|
||||
"post": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
@ -1322,7 +1358,7 @@
|
||||
}
|
||||
},
|
||||
"/api/get-ldaps": {
|
||||
"post": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
@ -1884,12 +1920,41 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-session": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Get session for one user in one application.",
|
||||
"operationId": "ApiController.GetSingleSession",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id(organization/application/user) of session",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-sessions": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Get organization user sessions",
|
||||
"description": "Get organization user sessions.",
|
||||
"operationId": "ApiController.GetSessions",
|
||||
"parameters": [
|
||||
{
|
||||
@ -2356,6 +2421,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/is-session-duplicated": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Check if there are other different sessions for one user in one application.",
|
||||
"operationId": "ApiController.IsSessionDuplicated",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id(organization/application/user) of session",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "sessionId",
|
||||
"description": "sessionId to be checked",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/login": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -3224,6 +3325,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/update-session": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Update session for one user in one application.",
|
||||
"operationId": "ApiController.UpdateSession",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id(organization/application/user) of session",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/update-syncer": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -3505,11 +3635,11 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"2346.0xc0001ce990.false": {
|
||||
"2346.0xc000278ab0.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
"2381.0xc0001ce9c0.false": {
|
||||
"2381.0xc000278ae0.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
@ -3566,6 +3696,9 @@
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"countryCode": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3599,9 +3732,6 @@
|
||||
"phoneCode": {
|
||||
"type": "string"
|
||||
},
|
||||
"phonePrefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"provider": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3636,10 +3766,10 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/2346.0xc0001ce990.false"
|
||||
"$ref": "#/definitions/2346.0xc000278ab0.false"
|
||||
},
|
||||
"data2": {
|
||||
"$ref": "#/definitions/2381.0xc0001ce9c0.false"
|
||||
"$ref": "#/definitions/2381.0xc000278ae0.false"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
@ -4091,6 +4221,12 @@
|
||||
"$ref": "#/definitions/object.AccountItem"
|
||||
}
|
||||
},
|
||||
"countryCodes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"createdTime": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4137,9 +4273,6 @@
|
||||
"passwordType": {
|
||||
"type": "string"
|
||||
},
|
||||
"phonePrefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -4906,6 +5039,9 @@
|
||||
"cloudfoundry": {
|
||||
"type": "string"
|
||||
},
|
||||
"countryCode": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdIp": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -218,6 +218,30 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/add-session:
|
||||
post:
|
||||
tags:
|
||||
- Session API
|
||||
description: Add session for one user in one application. If there are other existing sessions, join the session into the list.
|
||||
operationId: ApiController.AddSession
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id(organization/application/user) of session
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: sessionId
|
||||
description: sessionId to be added
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
/api/add-syncer:
|
||||
post:
|
||||
tags:
|
||||
@ -574,12 +598,12 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Session API
|
||||
description: Delete session by userId
|
||||
description: Delete session for one user in one application.
|
||||
operationId: ApiController.DeleteSession
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id ( owner/name )(owner/name) of user.
|
||||
description: The id(organization/application/user) of session
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
@ -799,7 +823,7 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/Response'
|
||||
/api/get-email-and-phone:
|
||||
post:
|
||||
get:
|
||||
tags:
|
||||
- User API
|
||||
description: get email and phone by username
|
||||
@ -847,7 +871,7 @@ paths:
|
||||
items:
|
||||
$ref: '#/definitions/object.User'
|
||||
/api/get-ldap:
|
||||
post:
|
||||
get:
|
||||
tags:
|
||||
- Account API
|
||||
operationId: ApiController.GetLdap
|
||||
@ -857,7 +881,7 @@ paths:
|
||||
- Account API
|
||||
operationId: ApiController.GetLdapser
|
||||
/api/get-ldaps:
|
||||
post:
|
||||
get:
|
||||
tags:
|
||||
- Account API
|
||||
operationId: ApiController.GetLdaps
|
||||
@ -1224,11 +1248,30 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Role'
|
||||
/api/get-session:
|
||||
get:
|
||||
tags:
|
||||
- Session API
|
||||
description: Get session for one user in one application.
|
||||
operationId: ApiController.GetSingleSession
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id(organization/application/user) of session
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
/api/get-sessions:
|
||||
get:
|
||||
tags:
|
||||
- Session API
|
||||
description: Get organization user sessions
|
||||
description: Get organization user sessions.
|
||||
operationId: ApiController.GetSessions
|
||||
parameters:
|
||||
- in: query
|
||||
@ -1535,6 +1578,30 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/is-session-duplicated:
|
||||
get:
|
||||
tags:
|
||||
- Session API
|
||||
description: Check if there are other different sessions for one user in one application.
|
||||
operationId: ApiController.IsSessionDuplicated
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id(organization/application/user) of session
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: sessionId
|
||||
description: sessionId to be checked
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
/api/login:
|
||||
post:
|
||||
tags:
|
||||
@ -2110,6 +2177,25 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/update-session:
|
||||
post:
|
||||
tags:
|
||||
- Session API
|
||||
description: Update session for one user in one application.
|
||||
operationId: ApiController.UpdateSession
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id(organization/application/user) of session
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
/api/update-syncer:
|
||||
post:
|
||||
tags:
|
||||
@ -2293,10 +2379,10 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/Response'
|
||||
definitions:
|
||||
2346.0xc0001ce990.false:
|
||||
2346.0xc000278ab0.false:
|
||||
title: "false"
|
||||
type: object
|
||||
2381.0xc0001ce9c0.false:
|
||||
2381.0xc000278ae0.false:
|
||||
title: "false"
|
||||
type: object
|
||||
Response:
|
||||
@ -2336,6 +2422,8 @@ definitions:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
countryCode:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
emailCode:
|
||||
@ -2358,8 +2446,6 @@ definitions:
|
||||
type: string
|
||||
phoneCode:
|
||||
type: string
|
||||
phonePrefix:
|
||||
type: string
|
||||
provider:
|
||||
type: string
|
||||
redirectUri:
|
||||
@ -2383,9 +2469,9 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/2346.0xc0001ce990.false'
|
||||
$ref: '#/definitions/2346.0xc000278ab0.false'
|
||||
data2:
|
||||
$ref: '#/definitions/2381.0xc0001ce9c0.false'
|
||||
$ref: '#/definitions/2381.0xc000278ae0.false'
|
||||
msg:
|
||||
type: string
|
||||
name:
|
||||
@ -2689,6 +2775,10 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.AccountItem'
|
||||
countryCodes:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
createdTime:
|
||||
type: string
|
||||
defaultApplication:
|
||||
@ -2720,8 +2810,6 @@ definitions:
|
||||
type: string
|
||||
passwordType:
|
||||
type: string
|
||||
phonePrefix:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
@ -3237,6 +3325,8 @@ definitions:
|
||||
type: string
|
||||
cloudfoundry:
|
||||
type: string
|
||||
countryCode:
|
||||
type: string
|
||||
createdIp:
|
||||
type: string
|
||||
createdTime:
|
||||
|
215
sync/bi_sync_mysql.go
Normal file
215
sync/bi_sync_mysql.go
Normal file
@ -0,0 +1,215 @@
|
||||
// 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 sync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/go-mysql-org/go-mysql/canal"
|
||||
"github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/replication"
|
||||
"github.com/siddontang/go-log/log"
|
||||
"github.com/xorm-io/xorm"
|
||||
)
|
||||
|
||||
type MyEventHandler struct {
|
||||
dataSourceName string
|
||||
engine *xorm.Engine
|
||||
serverId uint32
|
||||
serverUUID string
|
||||
GTID string
|
||||
canal.DummyEventHandler
|
||||
}
|
||||
|
||||
func StartCanal(cfg *canal.Config, username string, password string, host string, port int, database string) error {
|
||||
c, err := canal.NewCanal(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
GTIDSet, err := c.GetMasterGTIDSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
eventHandler := GetMyEventHandler(username, password, host, port, database)
|
||||
// Register a handler to handle RowsEvent
|
||||
c.SetEventHandler(&eventHandler)
|
||||
|
||||
// Start replication
|
||||
err = c.StartFromGTID(GTIDSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func StartBinlogSync() error {
|
||||
var wg sync.WaitGroup
|
||||
// init config
|
||||
cfg1 := GetCanalConfig(username1, password1, host1, port1, database1)
|
||||
cfg2 := GetCanalConfig(username2, password2, host2, port2, database2)
|
||||
|
||||
// start canal1 replication
|
||||
go StartCanal(cfg1, username2, password2, host2, port2, database2)
|
||||
wg.Add(1)
|
||||
|
||||
// start canal2 replication
|
||||
go StartCanal(cfg2, username1, password1, host1, port1, database1)
|
||||
wg.Add(1)
|
||||
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *MyEventHandler) OnGTID(header *replication.EventHeader, gtid mysql.GTIDSet) error {
|
||||
log.Info("OnGTID: ", gtid.String())
|
||||
h.GTID = gtid.String()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *MyEventHandler) onDDL(header *replication.EventHeader, nextPos mysql.Position, queryEvent *replication.QueryEvent) error {
|
||||
log.Info("into DDL event")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *MyEventHandler) OnRow(e *canal.RowsEvent) error {
|
||||
log.Info("serverId: ", e.Header.ServerID)
|
||||
if strings.Contains(h.GTID, h.serverUUID) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set the next gtid of the target library to the gtid of the current target library to avoid loopbacks
|
||||
h.engine.Exec(fmt.Sprintf("SET GTID_NEXT= '%s'", h.GTID))
|
||||
length := len(e.Table.Columns)
|
||||
columnNames := make([]string, length)
|
||||
oldColumnValue := make([]interface{}, length)
|
||||
newColumnValue := make([]interface{}, length)
|
||||
isChar := make([]bool, len(e.Table.Columns))
|
||||
|
||||
for i, col := range e.Table.Columns {
|
||||
columnNames[i] = col.Name
|
||||
if col.Type <= 2 {
|
||||
isChar[i] = false
|
||||
} else {
|
||||
isChar[i] = true
|
||||
}
|
||||
}
|
||||
// get pk column name
|
||||
pkColumnNames := GetPKColumnNames(columnNames, e.Table.PKColumns)
|
||||
|
||||
switch e.Action {
|
||||
case canal.UpdateAction:
|
||||
h.engine.Exec("BEGIN")
|
||||
for i, row := range e.Rows {
|
||||
for j, item := range row {
|
||||
if i%2 == 0 {
|
||||
if isChar[j] == true {
|
||||
oldColumnValue[j] = fmt.Sprintf("%s", item)
|
||||
} else {
|
||||
oldColumnValue[j] = fmt.Sprintf("%d", item)
|
||||
}
|
||||
} else {
|
||||
if isChar[j] == true {
|
||||
if item == nil {
|
||||
newColumnValue[j] = nil
|
||||
} else {
|
||||
newColumnValue[j] = fmt.Sprintf("%s", item)
|
||||
}
|
||||
} else {
|
||||
newColumnValue[j] = fmt.Sprintf("%d", item)
|
||||
}
|
||||
}
|
||||
}
|
||||
if i%2 == 1 {
|
||||
pkColumnValue := GetPKColumnValues(oldColumnValue, e.Table.PKColumns)
|
||||
updateSql, args, err := GetUpdateSql(e.Table.Schema, e.Table.Name, columnNames, newColumnValue, pkColumnNames, pkColumnValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := h.engine.DB().Exec(updateSql, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(updateSql, args, res)
|
||||
}
|
||||
}
|
||||
h.engine.Exec("COMMIT")
|
||||
h.engine.Exec("SET GTID_NEXT='automatic'")
|
||||
case canal.DeleteAction:
|
||||
h.engine.Exec("BEGIN")
|
||||
for _, row := range e.Rows {
|
||||
for j, item := range row {
|
||||
if isChar[j] == true {
|
||||
oldColumnValue[j] = fmt.Sprintf("%s", item)
|
||||
} else {
|
||||
oldColumnValue[j] = fmt.Sprintf("%d", item)
|
||||
}
|
||||
}
|
||||
|
||||
pkColumnValue := GetPKColumnValues(oldColumnValue, e.Table.PKColumns)
|
||||
deleteSql, args, err := GetDeleteSql(e.Table.Schema, e.Table.Name, pkColumnNames, pkColumnValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := h.engine.DB().Exec(deleteSql, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(deleteSql, args, res)
|
||||
}
|
||||
h.engine.Exec("COMMIT")
|
||||
h.engine.Exec("SET GTID_NEXT='automatic'")
|
||||
case canal.InsertAction:
|
||||
h.engine.Exec("BEGIN")
|
||||
for _, row := range e.Rows {
|
||||
for j, item := range row {
|
||||
if isChar[j] == true {
|
||||
if item == nil {
|
||||
newColumnValue[j] = nil
|
||||
} else {
|
||||
newColumnValue[j] = fmt.Sprintf("%s", item)
|
||||
}
|
||||
} else {
|
||||
newColumnValue[j] = fmt.Sprintf("%d", item)
|
||||
}
|
||||
}
|
||||
|
||||
insertSql, args, err := GetInsertSql(e.Table.Schema, e.Table.Name, columnNames, newColumnValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res, err := h.engine.DB().Exec(insertSql, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info(insertSql, args, res)
|
||||
}
|
||||
h.engine.Exec("COMMIT")
|
||||
h.engine.Exec("SET GTID_NEXT='automatic'")
|
||||
default:
|
||||
log.Infof("%v", e.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *MyEventHandler) String() string {
|
||||
return "MyEventHandler"
|
||||
}
|
17
sync/conf.go
Normal file
17
sync/conf.go
Normal file
@ -0,0 +1,17 @@
|
||||
package sync
|
||||
|
||||
var (
|
||||
host1 = "127.0.0.1"
|
||||
port1 = 3306
|
||||
username1 = "root"
|
||||
password1 = "123456"
|
||||
database1 = "db"
|
||||
)
|
||||
|
||||
var (
|
||||
host2 = "127.0.0.1"
|
||||
port2 = 3306
|
||||
username2 = "root"
|
||||
password2 = "123456"
|
||||
database2 = "db"
|
||||
)
|
130
sync/utils.go
Normal file
130
sync/utils.go
Normal file
@ -0,0 +1,130 @@
|
||||
// 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 sync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-mysql-org/go-mysql/canal"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/xorm-io/xorm"
|
||||
)
|
||||
|
||||
func GetUpdateSql(schemaName string, tableName string, columnNames []string, newColumnVal []interface{}, pkColumnNames []string, pkColumnValue []interface{}) (string, []interface{}, error) {
|
||||
updateSql := squirrel.Update(schemaName + "." + tableName)
|
||||
for i, columnName := range columnNames {
|
||||
updateSql = updateSql.Set(columnName, newColumnVal[i])
|
||||
}
|
||||
|
||||
for i, pkColumnName := range pkColumnNames {
|
||||
updateSql = updateSql.Where(squirrel.Eq{pkColumnName: pkColumnValue[i]})
|
||||
}
|
||||
|
||||
sql, args, err := updateSql.ToSql()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return sql, args, nil
|
||||
}
|
||||
|
||||
func GetInsertSql(schemaName string, tableName string, columnNames []string, columnValue []interface{}) (string, []interface{}, error) {
|
||||
insertSql := squirrel.Insert(schemaName + "." + tableName).Columns(columnNames...).Values(columnValue...)
|
||||
|
||||
return insertSql.ToSql()
|
||||
}
|
||||
|
||||
func GetDeleteSql(schemaName string, tableName string, pkColumnNames []string, pkColumnValue []interface{}) (string, []interface{}, error) {
|
||||
deleteSql := squirrel.Delete(schemaName + "." + tableName)
|
||||
|
||||
for i, columnName := range pkColumnNames {
|
||||
deleteSql = deleteSql.Where(squirrel.Eq{columnName: pkColumnValue[i]})
|
||||
}
|
||||
|
||||
return deleteSql.ToSql()
|
||||
}
|
||||
|
||||
func CreateEngine(dataSourceName string) (*xorm.Engine, error) {
|
||||
engine, err := xorm.NewEngine("mysql", dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ping mysql
|
||||
err = engine.Ping()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Println("mysql connection success……")
|
||||
return engine, nil
|
||||
}
|
||||
|
||||
func GetServerId(engin *xorm.Engine) (uint32, error) {
|
||||
res, err := engin.QueryInterface("SELECT @@server_id")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
serverId, _ := strconv.ParseUint(fmt.Sprintf("%s", res[0]["@@server_id"]), 10, 32)
|
||||
return uint32(serverId), nil
|
||||
}
|
||||
|
||||
func GetServerUUID(engin *xorm.Engine) (string, error) {
|
||||
res, err := engin.QueryString("show variables like 'server_uuid'")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
serverUUID := fmt.Sprintf("%s", res[0]["Value"])
|
||||
return serverUUID, err
|
||||
}
|
||||
|
||||
func GetPKColumnNames(columnNames []string, PKColumns []int) []string {
|
||||
pkColumnNames := make([]string, len(PKColumns))
|
||||
for i, index := range PKColumns {
|
||||
pkColumnNames[i] = columnNames[index]
|
||||
}
|
||||
return pkColumnNames
|
||||
}
|
||||
|
||||
func GetPKColumnValues(columnValues []interface{}, PKColumns []int) []interface{} {
|
||||
pkColumnNames := make([]interface{}, len(PKColumns))
|
||||
for i, index := range PKColumns {
|
||||
pkColumnNames[i] = columnValues[index]
|
||||
}
|
||||
return pkColumnNames
|
||||
}
|
||||
|
||||
func GetCanalConfig(username string, password string, host string, port int, database string) *canal.Config {
|
||||
// config canal
|
||||
cfg := canal.NewDefaultConfig()
|
||||
cfg.Addr = fmt.Sprintf("%s:%d", host, port)
|
||||
cfg.Password = password
|
||||
cfg.User = username
|
||||
// We only care table in database1
|
||||
cfg.Dump.TableDB = database
|
||||
return cfg
|
||||
}
|
||||
|
||||
func GetMyEventHandler(username string, password string, host string, port int, database string) MyEventHandler {
|
||||
var eventHandler MyEventHandler
|
||||
eventHandler.dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", username, password, host, port, database)
|
||||
eventHandler.engine, _ = CreateEngine(eventHandler.dataSourceName)
|
||||
eventHandler.serverId, _ = GetServerId(eventHandler.engine)
|
||||
eventHandler.serverUUID, _ = GetServerUUID(eventHandler.engine)
|
||||
return eventHandler
|
||||
}
|
128
util/system.go
128
util/system.go
@ -15,26 +15,37 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
)
|
||||
|
||||
// get cpu usage
|
||||
func GetCpuUsage() ([]float64, error) {
|
||||
type SystemInfo struct {
|
||||
CpuUsage []float64 `json:"cpuUsage"`
|
||||
MemoryUsed uint64 `json:"memoryUsed"`
|
||||
MemoryTotal uint64 `json:"memoryTotal"`
|
||||
}
|
||||
|
||||
type VersionInfo struct {
|
||||
Version string `json:"version"`
|
||||
CommitId string `json:"commitId"`
|
||||
CommitOffset int `json:"commitOffset"`
|
||||
}
|
||||
|
||||
// getCpuUsage get cpu usage
|
||||
func getCpuUsage() ([]float64, error) {
|
||||
usage, err := cpu.Percent(time.Second, true)
|
||||
return usage, err
|
||||
}
|
||||
|
||||
var fileDate, version string
|
||||
|
||||
// get memory usage
|
||||
func GetMemoryUsage() (uint64, uint64, error) {
|
||||
// getMemoryUsage get memory usage
|
||||
func getMemoryUsage() (uint64, uint64, error) {
|
||||
virtualMem, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
@ -46,33 +57,86 @@ func GetMemoryUsage() (uint64, uint64, error) {
|
||||
return m.TotalAlloc, virtualMem.Total, nil
|
||||
}
|
||||
|
||||
// get github repo release version
|
||||
func GetGitRepoVersion() (string, error) {
|
||||
pwd, err := os.Getwd()
|
||||
func GetSystemInfo() (*SystemInfo, error) {
|
||||
cpuUsage, err := getCpuUsage()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileInfos, err := ioutil.ReadDir(pwd + "/.git/refs/heads")
|
||||
for _, v := range fileInfos {
|
||||
if v.Name() == "master" {
|
||||
if v.ModTime().String() == fileDate {
|
||||
return version, nil
|
||||
} else {
|
||||
fileDate = v.ModTime().String()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(pwd + "/.git/refs/heads/master")
|
||||
memoryUsed, memoryTotal, err := getMemoryUsage()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert to full length
|
||||
temp := string(content)
|
||||
version = strings.ReplaceAll(temp, "\n", "")
|
||||
|
||||
return version, nil
|
||||
res := &SystemInfo{
|
||||
CpuUsage: cpuUsage,
|
||||
MemoryUsed: memoryUsed,
|
||||
MemoryTotal: memoryTotal,
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// GetVersionInfo get git current commit and repo release version
|
||||
func GetVersionInfo() (*VersionInfo, error) {
|
||||
res := &VersionInfo{
|
||||
Version: "",
|
||||
CommitId: "",
|
||||
CommitOffset: -1,
|
||||
}
|
||||
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
rootPath := path.Dir(path.Dir(filename))
|
||||
r, err := git.PlainOpen(rootPath)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ref, err := r.Head()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
tags, err := r.Tags()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
tagMap := make(map[plumbing.Hash]string)
|
||||
err = tags.ForEach(func(t *plumbing.Reference) error {
|
||||
// This technique should work for both lightweight and annotated tags.
|
||||
revHash, err := r.ResolveRevision(plumbing.Revision(t.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tagMap[*revHash] = t.Name().Short()
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
|
||||
|
||||
commitOffset := 0
|
||||
version := ""
|
||||
// iterates over the commits
|
||||
err = cIter.ForEach(func(c *object.Commit) error {
|
||||
tag, ok := tagMap[c.Hash]
|
||||
if ok {
|
||||
if version == "" {
|
||||
version = tag
|
||||
}
|
||||
}
|
||||
if version == "" {
|
||||
commitOffset++
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res = &VersionInfo{
|
||||
Version: version,
|
||||
CommitId: ref.Hash().String(),
|
||||
CommitOffset: commitOffset,
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
92
util/system_test.go
Normal file
92
util/system_test.go
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !skipCi
|
||||
// +build !skipCi
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"path"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetCpuUsage(t *testing.T) {
|
||||
usage, err := getCpuUsage()
|
||||
assert.Nil(t, err)
|
||||
t.Log(usage)
|
||||
}
|
||||
|
||||
func TestGetMemoryUsage(t *testing.T) {
|
||||
used, total, err := getMemoryUsage()
|
||||
assert.Nil(t, err)
|
||||
t.Log(used, total)
|
||||
}
|
||||
|
||||
func TestGetGitRepoVersion(t *testing.T) {
|
||||
versionInfo, err := GetVersionInfo()
|
||||
assert.Nil(t, err)
|
||||
t.Log(versionInfo)
|
||||
}
|
||||
|
||||
func TestGetVersion(t *testing.T) {
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
root := path.Dir(path.Dir(filename))
|
||||
r, err := git.PlainOpen(root)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
tags, err := r.Tags()
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
tagMap := make(map[plumbing.Hash]string)
|
||||
err = tags.ForEach(func(t *plumbing.Reference) error {
|
||||
// This technique should work for both lightweight and annotated tags.
|
||||
revHash, err := r.ResolveRevision(plumbing.Revision(t.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tagMap[*revHash] = t.Name().Short()
|
||||
return nil
|
||||
})
|
||||
|
||||
testHash := plumbing.NewHash("f8bc87eb4e5ba3256424cf14aafe0549f812f1cf")
|
||||
cIter, err := r.Log(&git.LogOptions{From: testHash})
|
||||
|
||||
aheadCnt := 0
|
||||
releaseVersion := ""
|
||||
// iterates over the commits
|
||||
err = cIter.ForEach(func(c *object.Commit) error {
|
||||
tag, ok := tagMap[c.Hash]
|
||||
if ok {
|
||||
if releaseVersion == "" {
|
||||
releaseVersion = tag
|
||||
}
|
||||
}
|
||||
if releaseVersion == "" {
|
||||
aheadCnt++
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
assert.Equal(t, 3, aheadCnt)
|
||||
assert.Equal(t, "v1.257.0", releaseVersion)
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetCpuUsage(t *testing.T) {
|
||||
usage, err := GetCpuUsage()
|
||||
assert.Nil(t, err)
|
||||
t.Log(usage)
|
||||
}
|
||||
|
||||
func TestGetMemoryUsage(t *testing.T) {
|
||||
used, total, err := GetMemoryUsage()
|
||||
assert.Nil(t, err)
|
||||
t.Log(used, total)
|
||||
}
|
@ -41,7 +41,7 @@ func IsPhoneValid(phone string, countryCode string) bool {
|
||||
}
|
||||
|
||||
func IsPhoneAllowInRegin(countryCode string, allowRegions []string) bool {
|
||||
return !ContainsString(allowRegions, countryCode)
|
||||
return ContainsString(allowRegions, countryCode)
|
||||
}
|
||||
|
||||
func GetE164Number(phone string, countryCode string) (string, bool) {
|
||||
|
@ -205,7 +205,7 @@ class AdapterListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/adapters/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete adapter: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteAdapter(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -16,7 +16,7 @@ import React, {Component} from "react";
|
||||
import "./App.less";
|
||||
import {Helmet} from "react-helmet";
|
||||
import * as Setting from "./Setting";
|
||||
import {StyleProvider} from "@ant-design/cssinjs";
|
||||
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
|
||||
import {BarsOutlined, DownOutlined, InfoCircleFilled, LogoutOutlined, SettingOutlined} from "@ant-design/icons";
|
||||
import {Alert, Avatar, Button, Card, ConfigProvider, Drawer, Dropdown, FloatButton, Layout, Menu, Result} from "antd";
|
||||
import {Link, Redirect, Route, Switch, withRouter} from "react-router-dom";
|
||||
@ -516,8 +516,8 @@ class App extends Component {
|
||||
<Route exact path="/applications/:organizationName/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/resources" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceListPage account={this.state.account} {...props} />)} />
|
||||
{/* <Route exact path="/resources/:resourceName" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceEditPage account={this.state.account} {...props} />)}/>*/}
|
||||
<Route exact path="/ldap/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/ldap/sync/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapSyncPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/ldap/:organizationName/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/ldap/sync/:organizationName/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapSyncPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/tokens" render={(props) => this.renderLoginIfNotLoggedIn(<TokenListPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/sessions" render={(props) => this.renderLoginIfNotLoggedIn(<SessionListPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/tokens/:tokenName" render={(props) => this.renderLoginIfNotLoggedIn(<TokenEditPage account={this.state.account} {...props} />)} />
|
||||
@ -730,7 +730,7 @@ class App extends Component {
|
||||
},
|
||||
algorithm: Setting.getAlgorithm(this.state.themeAlgorithm),
|
||||
}}>
|
||||
<StyleProvider hashPriority="high">
|
||||
<StyleProvider hashPriority="high" transformers={[legacyLogicalPropertiesTransformer]}>
|
||||
{
|
||||
this.renderPage()
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ class ApplicationListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/applications/${record.organization}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete application: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteApplication(index)}
|
||||
disabled={record.name === "app-built-in"}
|
||||
>
|
||||
|
@ -169,7 +169,7 @@ class CertListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/certs/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete cert: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteCert(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -27,6 +27,7 @@ class LdapEditPage extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
ldapId: props.match.params.ldapId,
|
||||
organizationName: props.match.params.organizationName,
|
||||
ldap: null,
|
||||
organizations: [],
|
||||
};
|
||||
@ -38,7 +39,7 @@ class LdapEditPage extends React.Component {
|
||||
}
|
||||
|
||||
getLdap() {
|
||||
LddpBackend.getLdap(this.state.ldapId)
|
||||
LddpBackend.getLdap(this.state.organizationName, this.state.ldapId)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
|
@ -140,7 +140,7 @@ class LdapListPage extends React.Component {
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}}
|
||||
onClick={() => Setting.goToLink(`/ldap/${record.id}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete LDAP Config: ${record.serverName} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.serverName} ?`}
|
||||
onConfirm={() => this.deleteLdap(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}}
|
||||
|
@ -23,6 +23,7 @@ class LdapSyncPage extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
ldapId: props.match.params.ldapId,
|
||||
organizationName: props.match.params.organizationName,
|
||||
ldap: null,
|
||||
users: [],
|
||||
existUuids: [],
|
||||
@ -73,7 +74,7 @@ class LdapSyncPage extends React.Component {
|
||||
}
|
||||
|
||||
getLdap() {
|
||||
LdapBackend.getLdap(this.state.ldapId)
|
||||
LdapBackend.getLdap(this.state.organizationName, this.state.ldapId)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState((prevState) => {
|
||||
|
@ -154,11 +154,11 @@ class LdapTable extends React.Component {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}}
|
||||
type="primary"
|
||||
onClick={() => Setting.goToLink(`/ldap/sync/${record.id}`)}>{i18next.t("ldap:Sync")}</Button>
|
||||
onClick={() => Setting.goToLink(`/ldap/sync/${record.owner}/${record.id}`)}>{i18next.t("ldap:Sync")}</Button>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}}
|
||||
onClick={() => Setting.goToLink(`/ldap/${record.id}`)}>{i18next.t("general:Edit")}</Button>
|
||||
onClick={() => Setting.goToLink(`/ldap/${record.owner}/${record.id}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete LDAP Config: ${record.serverName} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.serverName} ?`}
|
||||
onConfirm={() => this.deleteRow(table, index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}}
|
||||
|
@ -143,7 +143,7 @@ class ModelListPage extends BaseListPage {
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary"
|
||||
onClick={() => this.props.history.push(`/models/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete model: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteModel(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -184,20 +184,19 @@ class OrganizationEditPage extends React.Component {
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Supported country code"), i18next.t("general:Supported country code - Tooltip"))} :
|
||||
{Setting.getLabel(i18next.t("general:Supported country codes"), i18next.t("general:Supported country codes - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} mode={"multiple"} style={{width: "100%"}} value={this.state.organization.countryCodes ?? []}
|
||||
options={Setting.getCountriesData().map(country => {
|
||||
return Setting.getOption(
|
||||
<>
|
||||
{Setting.countryFlag(country)}
|
||||
{`${country.name} +${country.phone}`}
|
||||
</>,
|
||||
country.code);
|
||||
})} onChange={value => {
|
||||
onChange={value => {
|
||||
this.updateOrganizationField("countryCodes", value);
|
||||
}} />
|
||||
}}
|
||||
filterOption={(input, option) => (option?.text ?? "").toLowerCase().includes(input.toLowerCase())}
|
||||
>
|
||||
{
|
||||
Setting.getCountryCodeData().map((country) => Setting.getCountryCodeOption(country))
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
|
@ -37,7 +37,7 @@ class OrganizationListPage extends BaseListPage {
|
||||
defaultAvatar: `${Setting.StaticBaseUrl}/img/casbin.svg`,
|
||||
defaultApplication: "",
|
||||
tags: [],
|
||||
languages: ["en", "zh", "es", "fr", "de", "ja", "ko", "ru", "vi"],
|
||||
languages: Setting.Countries.map(item => item.key),
|
||||
masterPassword: "",
|
||||
enableSoftDeletion: false,
|
||||
isProfilePublic: true,
|
||||
@ -227,7 +227,7 @@ class OrganizationListPage extends BaseListPage {
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/organizations/${record.name}/users`)}>{i18next.t("general:Users")}</Button>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} onClick={() => this.props.history.push(`/organizations/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete organization: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteOrganization(index)}
|
||||
disabled={record.name === "built-in"}
|
||||
>
|
||||
|
@ -223,7 +223,7 @@ class PaymentListPage extends BaseListPage {
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} onClick={() => this.props.history.push(`/payments/${record.name}/result`)}>{i18next.t("payment:Result")}</Button>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/payments/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete payment: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deletePayment(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -301,7 +301,7 @@ class PermissionListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/permissions/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete permission: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deletePermission(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -240,7 +240,7 @@ class ProductListPage extends BaseListPage {
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} onClick={() => this.props.history.push(`/products/${record.name}/buy`)}>{i18next.t("product:Buy")}</Button>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/products/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete product: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteProduct(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -20,9 +20,11 @@ import * as Setting from "./Setting";
|
||||
import i18next from "i18next";
|
||||
import {authConfig} from "./auth/Auth";
|
||||
import * as ProviderEditTestEmail from "./TestEmailWidget";
|
||||
import * as ProviderEditTestSms from "./TestSmsWidget";
|
||||
import copy from "copy-to-clipboard";
|
||||
import {CaptchaPreview} from "./common/CaptchaPreview";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import {CountryCodeSelect} from "./common/CountryCodeSelect";
|
||||
|
||||
const {Option} = Select;
|
||||
const {TextArea} = Input;
|
||||
@ -596,7 +598,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Email Title"), i18next.t("provider:Email Title - Tooltip"))} :
|
||||
{Setting.getLabel(i18next.t("provider:Email title"), i18next.t("provider:Email title - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.title} onChange={e => {
|
||||
@ -606,7 +608,7 @@ class ProviderEditPage extends React.Component {
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Email Content"), i18next.t("provider:Email Content - Tooltip"))} :
|
||||
{Setting.getLabel(i18next.t("provider:Email content"), i18next.t("provider:Email content - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<TextArea autoSize={{minRows: 3, maxRows: 100}} value={this.state.provider.content} onChange={e => {
|
||||
@ -629,7 +631,7 @@ class ProviderEditPage extends React.Component {
|
||||
<Button style={{marginLeft: "10px", marginBottom: "5px"}} type="primary"
|
||||
disabled={!Setting.isValidEmail(this.state.provider.receiver)}
|
||||
onClick={() => ProviderEditTestEmail.sendTestEmail(this.state.provider, this.state.provider.receiver)} >
|
||||
{i18next.t("provider:Send Test Email")}
|
||||
{i18next.t("provider:Send Testing Email")}
|
||||
</Button>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
@ -659,6 +661,36 @@ class ProviderEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:SMS Test"), i18next.t("provider:SMS Test - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={4} >
|
||||
<Input.Group compact>
|
||||
<CountryCodeSelect
|
||||
style={{width: "30%"}}
|
||||
value={this.state.provider.content}
|
||||
onChange={(value) => {
|
||||
this.updateProviderField("content", value);
|
||||
}}
|
||||
countryCodes={this.props.account.organization.countryCodes}
|
||||
/>
|
||||
<Input value={this.state.provider.receiver}
|
||||
style={{width: "70%"}}
|
||||
placeholder = {i18next.t("user:Input your phone number")}
|
||||
onChange={e => {
|
||||
this.updateProviderField("receiver", e.target.value);
|
||||
}} />
|
||||
</Input.Group>
|
||||
</Col>
|
||||
<Col span={2} >
|
||||
<Button style={{marginLeft: "10px", marginBottom: "5px"}} type="primary"
|
||||
disabled={!Setting.isValidPhone(this.state.provider.receiver)}
|
||||
onClick={() => ProviderEditTestSms.sendTestSms(this.state.provider, "+" + Setting.getCountryCode(this.state.provider.content) + this.state.provider.receiver)} >
|
||||
{i18next.t("provider:Send Testing SMS")}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</React.Fragment>
|
||||
) : this.state.provider.category === "SAML" ? (
|
||||
<React.Fragment>
|
||||
@ -781,17 +813,17 @@ class ProviderEditPage extends React.Component {
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<CaptchaPreview
|
||||
owner={this.state.provider.owner}
|
||||
name={this.state.provider.name}
|
||||
provider={this.state.provider}
|
||||
providerName={this.state.providerName}
|
||||
clientSecret={this.state.provider.clientSecret}
|
||||
captchaType={this.state.provider.type}
|
||||
subType={this.state.provider.subType}
|
||||
owner={this.state.provider.owner}
|
||||
clientId={this.state.provider.clientId}
|
||||
name={this.state.provider.name}
|
||||
providerUrl={this.state.provider.providerUrl}
|
||||
clientSecret={this.state.provider.clientSecret}
|
||||
clientId2={this.state.provider.clientId2}
|
||||
clientSecret2={this.state.provider.clientSecret2}
|
||||
providerUrl={this.state.provider.providerUrl}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -207,7 +207,7 @@ class ProviderListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button disabled={!Setting.isAdminUser(this.props.account) && (record.owner !== this.props.account.owner)} style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/providers/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete provider: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteProvider(index)}
|
||||
>
|
||||
<Button disabled={!Setting.isAdminUser(this.props.account) && (record.owner !== this.props.account.owner)} style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -25,7 +25,7 @@ export const ResetModal = (props) => {
|
||||
const [confirmLoading, setConfirmLoading] = React.useState(false);
|
||||
const [dest, setDest] = React.useState("");
|
||||
const [code, setCode] = React.useState("");
|
||||
const {buttonText, destType, application} = props;
|
||||
const {buttonText, destType, application, countryCode} = props;
|
||||
|
||||
const showModal = () => {
|
||||
setVisible(true);
|
||||
@ -87,7 +87,7 @@ export const ResetModal = (props) => {
|
||||
<Row style={{width: "100%", marginBottom: "20px"}}>
|
||||
<Input
|
||||
addonBefore={destType === "email" ? i18next.t("user:New Email") : i18next.t("user:New phone")}
|
||||
prefix={destType === "email" ? <MailOutlined /> : <PhoneOutlined />}
|
||||
prefix={destType === "email" ? <React.Fragment><MailOutlined /> </React.Fragment> : (<React.Fragment><PhoneOutlined /> {countryCode !== "" ? "+" : null}{Setting.getCountryCode(countryCode)} </React.Fragment>)}
|
||||
placeholder={placeholder}
|
||||
onChange={e => setDest(e.target.value)}
|
||||
/>
|
||||
|
@ -246,7 +246,7 @@ class ResourceListPage extends BaseListPage {
|
||||
<div>
|
||||
{/* <Button style={{marginTop: '10px', marginBottom: '10px', marginRight: '10px'}} type="primary" onClick={() => this.props.history.push(`/resources/${record.name}`)}>{i18next.t("general:Edit")}</Button>*/}
|
||||
<Popconfirm
|
||||
title={`Sure to delete resource: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteResource(index)}
|
||||
okText={i18next.t("user:OK")}
|
||||
cancelText={i18next.t("user:Cancel")}
|
||||
|
@ -82,7 +82,7 @@ class RoleListPage extends BaseListPage {
|
||||
...this.getColumnSearchProps("name"),
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Link to={`/roles/${text}`}>
|
||||
<Link to={`/roles/${record.owner}/${record.name}`}>
|
||||
{text}
|
||||
</Link>
|
||||
);
|
||||
@ -176,7 +176,7 @@ class RoleListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/roles/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete role: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteRole(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -41,17 +41,15 @@ class SelectRegionBox extends React.Component {
|
||||
defaultValue={this.props.defaultValue || undefined}
|
||||
placeholder="Please select country/region"
|
||||
onChange={(value => {this.onChange(value);})}
|
||||
filterOption={(input, option) =>
|
||||
(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
|
||||
}
|
||||
filterOption={(input, option) => (option?.label ?? "").toLowerCase().includes(input.toLowerCase())}
|
||||
filterSort={(optionA, optionB) =>
|
||||
(optionA?.label ?? "").toLowerCase().localeCompare((optionB?.label ?? "").toLowerCase())
|
||||
}
|
||||
>
|
||||
{
|
||||
Setting.getCountriesData().map((item) => (
|
||||
Setting.getCountryCodeData().map((item) => (
|
||||
<Option key={item.code} value={item.code} label={`${item.name} (${item.code})`} >
|
||||
{Setting.countryFlag(item)}
|
||||
{Setting.getCountryImage(item)}
|
||||
{`${item.name} (${item.code})`}
|
||||
</Option>
|
||||
))
|
||||
|
@ -98,7 +98,7 @@ class SessionListPage extends BaseListPage {
|
||||
return (
|
||||
<div>
|
||||
<Popconfirm
|
||||
title={`Sure to delete session: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteSession(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
import React from "react";
|
||||
import {Link} from "react-router-dom";
|
||||
import {Checkbox, Form, Modal, Tag, Tooltip, message, theme} from "antd";
|
||||
import {Checkbox, Form, Modal, Select, Tag, Tooltip, message, theme} from "antd";
|
||||
import {QuestionCircleTwoTone} from "@ant-design/icons";
|
||||
import {isMobile as isMobileDevice} from "react-device-detect";
|
||||
import "./i18n";
|
||||
@ -26,6 +26,8 @@ import * as Conf from "./Conf";
|
||||
import * as phoneNumber from "libphonenumber-js";
|
||||
import * as path from "path-browserify";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
export const ServerUrl = "";
|
||||
|
||||
// export const StaticBaseUrl = "https://cdn.jsdelivr.net/gh/casbin/static";
|
||||
@ -92,13 +94,17 @@ export const OtherProviderInfo = {
|
||||
url: "https://www.huaweicloud.com/product/msgsms.html",
|
||||
},
|
||||
"Twilio SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_twilio.png`,
|
||||
logo: `${StaticBaseUrl}/img/social_twilio.svg`,
|
||||
url: "https://www.twilio.com/messaging",
|
||||
},
|
||||
"SmsBao SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_smsbao.png`,
|
||||
url: "https://www.smsbao.com/",
|
||||
},
|
||||
"SUBMAIL SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_submail.svg`,
|
||||
url: "https://www.mysubmail.com",
|
||||
},
|
||||
"Mock SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_default.png`,
|
||||
url: "",
|
||||
@ -206,7 +212,14 @@ export function initCountries() {
|
||||
return countries;
|
||||
}
|
||||
|
||||
export function getCountriesData(countryCodes = phoneNumber.getCountries()) {
|
||||
export function getCountryCode(country) {
|
||||
if (phoneNumber.isSupportedCountry(country)) {
|
||||
return phoneNumber.getCountryCallingCode(country);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export function getCountryCodeData(countryCodes = phoneNumber.getCountries()) {
|
||||
return countryCodes?.map((countryCode) => {
|
||||
if (phoneNumber.isSupportedCountry(countryCode)) {
|
||||
const name = initCountries().getName(countryCode, getLanguage());
|
||||
@ -216,17 +229,28 @@ export function getCountriesData(countryCodes = phoneNumber.getCountries()) {
|
||||
phone: phoneNumber.getCountryCallingCode(countryCode),
|
||||
};
|
||||
}
|
||||
});
|
||||
}).filter(item => item.name !== "")
|
||||
.sort((a, b) => a.phone - b.phone);
|
||||
}
|
||||
|
||||
export function countryFlag(country) {
|
||||
export function getCountryCodeOption(country) {
|
||||
return (
|
||||
<Option key={country.code} value={country.code} label={`+${country.phone}`} text={`${country.name}, ${country.code}, ${country.phone}`} >
|
||||
<div style={{display: "flex", justifyContent: "space-between", marginRight: "10px"}}>
|
||||
<div>
|
||||
{getCountryImage(country)}
|
||||
{`${country.name}`}
|
||||
</div>
|
||||
{`+${country.phone}`}
|
||||
</div>
|
||||
</Option>
|
||||
);
|
||||
}
|
||||
|
||||
export function getCountryImage(country) {
|
||||
return <img src={`${StaticBaseUrl}/flag-icons/${country.code}.svg`} alt={country.name} height={20} style={{marginRight: 10}} />;
|
||||
}
|
||||
|
||||
export function getPhoneCodeFromCountryCode(countryCode) {
|
||||
return phoneNumber.isSupportedCountry(countryCode) ? phoneNumber.getCountryCallingCode(countryCode) : "";
|
||||
}
|
||||
|
||||
export function initServerUrl() {
|
||||
// const hostname = window.location.hostname;
|
||||
// if (hostname === "localhost") {
|
||||
@ -332,13 +356,15 @@ export function isValidEmail(email) {
|
||||
}
|
||||
|
||||
export function isValidPhone(phone, countryCode = "") {
|
||||
if (countryCode !== "") {
|
||||
if (countryCode !== "" && countryCode !== "CN") {
|
||||
return phoneNumber.isValidPhoneNumber(phone, countryCode);
|
||||
}
|
||||
|
||||
// // https://learnku.com/articles/31543, `^s*$` filter empty email individually.
|
||||
// https://learnku.com/articles/31543, `^s*$` filter empty email individually.
|
||||
const phoneCnRegex = /^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
|
||||
const phoneRegex = /[0-9]{4,15}$/;
|
||||
return phoneRegex.test(phone);
|
||||
|
||||
return countryCode === "CN" ? phoneCnRegex.test(phone) : phoneRegex.test(phone);
|
||||
}
|
||||
|
||||
export function isValidInvoiceTitle(invoiceTitle) {
|
||||
@ -865,6 +891,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: "Huawei Cloud SMS", name: "Huawei Cloud SMS"},
|
||||
{id: "Twilio SMS", name: "Twilio SMS"},
|
||||
{id: "SmsBao SMS", name: "SmsBao SMS"},
|
||||
{id: "SUBMAIL SMS", name: "SUBMAIL SMS"},
|
||||
]
|
||||
);
|
||||
} else if (category === "Storage") {
|
||||
|
@ -233,7 +233,7 @@ class SyncerListPage extends BaseListPage {
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.runSyncer(index)}>{i18next.t("general:Sync")}</Button>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} onClick={() => this.props.history.push(`/syncers/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete syncer: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteSyncer(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -23,31 +23,24 @@ class SystemInfo extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
cpuUsage: [],
|
||||
memUsed: 0,
|
||||
memTotal: 0,
|
||||
latestVersion: undefined,
|
||||
systemInfo: {cpuUsage: [], memoryUsed: 0, memoryTotal: 0},
|
||||
versionInfo: {},
|
||||
intervalId: null,
|
||||
href: "",
|
||||
loading: true,
|
||||
};
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
SystemBackend.getSystemInfo(this.props.account?.owner, this.props.account?.name).then(res => {
|
||||
SystemBackend.getSystemInfo().then(res => {
|
||||
this.setState({
|
||||
cpuUsage: res.cpu_usage,
|
||||
memUsed: res.memory_used,
|
||||
memTotal: res.memory_total,
|
||||
systemInfo: res.data,
|
||||
loading: false,
|
||||
});
|
||||
|
||||
const id = setInterval(() => {
|
||||
SystemBackend.getSystemInfo(this.props.account?.owner, this.props.account?.name).then(res => {
|
||||
SystemBackend.getSystemInfo().then(res => {
|
||||
this.setState({
|
||||
cpuUsage: res.cpu_usage,
|
||||
memUsed: res.memory_used,
|
||||
memTotal: res.memory_total,
|
||||
systemInfo: res.data,
|
||||
});
|
||||
}).catch(error => {
|
||||
Setting.showMessage("error", `System info failed to get: ${error}`);
|
||||
@ -58,12 +51,12 @@ class SystemInfo extends React.Component {
|
||||
Setting.showMessage("error", `System info failed to get: ${error}`);
|
||||
});
|
||||
|
||||
SystemBackend.getGitHubLatestReleaseVersion().then(res => {
|
||||
const href = res && res.length >= 8 ? `https://github.com/casdoor/casdoor/commit/${res}` : "";
|
||||
const versionText = res && res.length >= 8 ? res.substring(0, 8) : i18next.t("system:Unknown Version");
|
||||
this.setState({latestVersion: versionText, href: href});
|
||||
SystemBackend.getVersionInfo().then(res => {
|
||||
this.setState({
|
||||
versionInfo: res.data,
|
||||
});
|
||||
}).catch(err => {
|
||||
Setting.showMessage("error", `get latest commit version failed: ${err}`);
|
||||
Setting.showMessage("error", `Version info failed to get: ${err}`);
|
||||
});
|
||||
}
|
||||
|
||||
@ -74,21 +67,25 @@ class SystemInfo extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const CPUInfo = this.state.cpuUsage?.length > 0 ?
|
||||
this.state.cpuUsage.map((usage, i) => {
|
||||
const cpuUi = this.state.systemInfo.cpuUsage?.length <= 0 ? i18next.t("system:Get CPU Usage Failed") :
|
||||
this.state.systemInfo.cpuUsage.map((usage, i) => {
|
||||
return (
|
||||
<Progress key={i} percent={Number(usage.toFixed(1))} />
|
||||
);
|
||||
}) : i18next.t("system:Get CPU Usage Failed");
|
||||
});
|
||||
|
||||
const MemInfo = (
|
||||
this.state.memUsed && this.state.memTotal && this.state.memTotal !== 0 ?
|
||||
const memUi = this.state.systemInfo.memoryUsed && this.state.systemInfo.memoryTotal && this.state.systemInfo.memoryTotal <= 0 ? i18next.t("system:Get Memory Usage Failed") :
|
||||
<div>
|
||||
{Setting.getFriendlyFileSize(this.state.memUsed)} / {Setting.getFriendlyFileSize(this.state.memTotal)}
|
||||
{Setting.getFriendlyFileSize(this.state.systemInfo.memoryUsed)} / {Setting.getFriendlyFileSize(this.state.systemInfo.memoryTotal)}
|
||||
<br /> <br />
|
||||
<Progress type="circle" percent={Number((Number(this.state.memUsed) / Number(this.state.memTotal) * 100).toFixed(2))} />
|
||||
</div> : i18next.t("system:Get Memory Usage Failed")
|
||||
);
|
||||
<Progress type="circle" percent={Number((Number(this.state.systemInfo.memoryUsed) / Number(this.state.systemInfo.memoryTotal) * 100).toFixed(2))} />
|
||||
</div>;
|
||||
|
||||
const link = this.state.versionInfo?.version !== "" ? `https://github.com/casdoor/casdoor/releases/tag/${this.state.versionInfo?.version}` : "";
|
||||
let versionText = this.state.versionInfo?.version !== "" ? this.state.versionInfo?.version : i18next.t("system:Unknown Version");
|
||||
if (this.state.versionInfo?.commitOffset > 0) {
|
||||
versionText += ` (ahead+${this.state.versionInfo?.commitOffset})`;
|
||||
}
|
||||
|
||||
if (!Setting.isMobile()) {
|
||||
return (
|
||||
@ -98,25 +95,25 @@ class SystemInfo extends React.Component {
|
||||
<Row gutter={[10, 10]}>
|
||||
<Col span={12}>
|
||||
<Card title={i18next.t("system:CPU Usage")} bordered={true} style={{textAlign: "center", height: "100%"}}>
|
||||
{this.state.loading ? <Spin size="large" /> : CPUInfo}
|
||||
{this.state.loading ? <Spin size="large" /> : cpuUi}
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Card title={i18next.t("system:Memory Usage")} bordered={true} style={{textAlign: "center", height: "100%"}}>
|
||||
{this.state.loading ? <Spin size="large" /> : MemInfo}
|
||||
{this.state.loading ? <Spin size="large" /> : memUi}
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
<Divider />
|
||||
<Card title={i18next.t("system:About Casdoor")} bordered={true} style={{textAlign: "center"}}>
|
||||
<div>{i18next.t("system:An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS")}</div>
|
||||
GitHub: <a href="https://github.com/casdoor/casdoor">casdoor</a>
|
||||
GitHub: <a target="_blank" rel="noreferrer" href="https://github.com/casdoor/casdoor">Casdoor</a>
|
||||
<br />
|
||||
{i18next.t("system:Version")}: <a href={this.state.href}>{this.state.latestVersion}</a>
|
||||
{i18next.t("system:Version")}: <a target="_blank" rel="noreferrer" href={link}>{versionText}</a>
|
||||
<br />
|
||||
{i18next.t("system:Official Website")}: <a href="https://casdoor.org/">casdoor.org</a>
|
||||
{i18next.t("system:Official Website")}: <a target="_blank" rel="noreferrer" href="https://casdoor.org">https://casdoor.org</a>
|
||||
<br />
|
||||
{i18next.t("system:Community")}: <a href="https://casdoor.org/#:~:text=Casdoor%20API-,Community,-GitHub">contact us</a>
|
||||
{i18next.t("system:Community")}: <a target="_blank" rel="noreferrer" href="https://casdoor.org/#:~:text=Casdoor%20API-,Community,-GitHub">Get in Touch!</a>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}></Col>
|
||||
@ -127,24 +124,24 @@ class SystemInfo extends React.Component {
|
||||
<Row gutter={[16, 0]}>
|
||||
<Col span={24}>
|
||||
<Card title={i18next.t("system:CPU Usage")} bordered={true} style={{textAlign: "center", width: "100%"}}>
|
||||
{this.state.loading ? <Spin size="large" /> : CPUInfo}
|
||||
{this.state.loading ? <Spin size="large" /> : cpuUi}
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Card title={i18next.t("system:Memory Usage")} bordered={true} style={{textAlign: "center", width: "100%"}}>
|
||||
{this.state.loading ? <Spin size="large" /> : MemInfo}
|
||||
{this.state.loading ? <Spin size="large" /> : memUi}
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Card title={i18next.t("system:About Casdoor")} bordered={true} style={{textAlign: "center"}}>
|
||||
<div>{i18next.t("system:An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS")}</div>
|
||||
GitHub: <a href="https://github.com/casdoor/casdoor">casdoor</a>
|
||||
GitHub: <a target="_blank" rel="noreferrer" href="https://github.com/casdoor/casdoor">Casdoor</a>
|
||||
<br />
|
||||
{i18next.t("system:Version")}: <a href={this.state.href}>{this.state.latestVersion}</a>
|
||||
{i18next.t("system:Version")}: <a target="_blank" rel="noreferrer" href={link}>{versionText}</a>
|
||||
<br />
|
||||
{i18next.t("system:Official Website")}: <a href="https://casdoor.org/">casdoor.org</a>
|
||||
{i18next.t("system:Official Website")}: <a target="_blank" rel="noreferrer" href="https://casdoor.org">https://casdoor.org</a>
|
||||
<br />
|
||||
{i18next.t("system:Community")}: <a href="https://casdoor.org/#:~:text=Casdoor%20API-,Community,-GitHub">contact us</a>
|
||||
{i18next.t("system:Community")}: <a target="_blank" rel="noreferrer" href="https://casdoor.org/#:~:text=Casdoor%20API-,Community,-GitHub">Get in Touch!</a>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -19,7 +19,7 @@ export function sendTestEmail(provider, email) {
|
||||
testEmailProvider(provider, email)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", "Successfully send email");
|
||||
Setting.showMessage("success", `${i18next.t("provider:Email sent successfully")}`);
|
||||
} else {
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
@ -33,7 +33,7 @@ export function connectSmtpServer(provider) {
|
||||
testEmailProvider(provider)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", "Successfully connecting smtp server");
|
||||
Setting.showMessage("success", "provider:SMTP connected successfully");
|
||||
} else {
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
|
43
web/src/TestSmsWidget.js
Normal file
43
web/src/TestSmsWidget.js
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import * as Setting from "./Setting";
|
||||
import i18next from "i18next";
|
||||
|
||||
export function sendTestSms(provider, phone) {
|
||||
testSmsProvider(provider, phone)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", `${i18next.t("provider:SMS sent successfully")}`);
|
||||
} else {
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
function testSmsProvider(provider, phone = "") {
|
||||
const SmsForm = {
|
||||
content: "123456",
|
||||
receivers: [phone],
|
||||
};
|
||||
|
||||
return fetch(`${Setting.ServerUrl}/api/send-sms?provider=` + provider.name, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
body: JSON.stringify(SmsForm),
|
||||
}).then(res => res.json());
|
||||
}
|
@ -202,7 +202,7 @@ class TokenListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/tokens/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete token: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteToken(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -29,7 +29,7 @@ import SelectRegionBox from "./SelectRegionBox";
|
||||
import WebAuthnCredentialTable from "./WebauthnCredentialTable";
|
||||
import ManagedAccountTable from "./ManagedAccountTable";
|
||||
import PropertyTable from "./propertyTable";
|
||||
import PhoneNumberInput from "./common/PhoneNumberInput";
|
||||
import {CountryCodeSelect} from "./common/CountryCodeSelect";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
@ -138,6 +138,10 @@ class UserEditPage extends React.Component {
|
||||
return this.isSelf() || Setting.isAdminUser(this.props.account);
|
||||
}
|
||||
|
||||
getCountryCode() {
|
||||
return this.props.account.countryCode;
|
||||
}
|
||||
|
||||
renderAccountItem(accountItem) {
|
||||
if (!accountItem.visible) {
|
||||
return null;
|
||||
@ -285,21 +289,14 @@ class UserEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:Email"), i18next.t("general:Email - Tooltip"))} :
|
||||
</Col>
|
||||
<Col style={{paddingRight: "20px"}} span={11} >
|
||||
{Setting.isLocalAdminUser(this.props.account) ?
|
||||
(<Input value={this.state.user.email}
|
||||
<Input
|
||||
value={this.state.user.email}
|
||||
style={{width: "280Px"}}
|
||||
disabled={disabled}
|
||||
disabled={!Setting.isLocalAdminUser(this.props.account) ? true : disabled}
|
||||
onChange={e => {
|
||||
this.updateUserField("email", e.target.value);
|
||||
}} />) :
|
||||
(<Select virtual={false} value={this.state.user.email}
|
||||
style={{width: "280Px"}}
|
||||
options={[Setting.getItem(this.state.user.email, this.state.user.email)]}
|
||||
disabled={disabled}
|
||||
onChange={e => {
|
||||
this.updateUserField("email", e.target.value);
|
||||
}} />)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={Setting.isMobile() ? 22 : 11} >
|
||||
{/* backend auto get the current user, so admin can not edit. Just self can reset*/}
|
||||
@ -314,10 +311,10 @@ class UserEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:Phone"), i18next.t("general:Phone - Tooltip"))} :
|
||||
</Col>
|
||||
<Col style={{paddingRight: "20px"}} span={11} >
|
||||
{Setting.isLocalAdminUser(this.props.account) ?
|
||||
<Input.Group compact style={{width: "280Px"}}>
|
||||
<PhoneNumberInput
|
||||
<CountryCodeSelect
|
||||
style={{width: "30%"}}
|
||||
// disabled={!Setting.isLocalAdminUser(this.props.account) ? true : disabled}
|
||||
value={this.state.user.countryCode}
|
||||
onChange={(value) => {
|
||||
this.updateUserField("countryCode", value);
|
||||
@ -326,22 +323,14 @@ class UserEditPage extends React.Component {
|
||||
/>
|
||||
<Input value={this.state.user.phone}
|
||||
style={{width: "70%"}}
|
||||
disabled={disabled}
|
||||
disabled={!Setting.isLocalAdminUser(this.props.account) ? true : disabled}
|
||||
onChange={e => {
|
||||
this.updateUserField("phone", e.target.value);
|
||||
}} />
|
||||
</Input.Group>
|
||||
:
|
||||
(<Select virtual={false} value={this.state.user.phone === "" ? null : `+${Setting.getPhoneCodeFromCountryCode(this.state.user.countryCode)} ${this.state.user.phone}`}
|
||||
options={this.state.user.phone === "" ? null : [Setting.getItem(`+${Setting.getPhoneCodeFromCountryCode(this.state.user.countryCode)} ${this.state.user.phone}`, this.state.user.phone)]}
|
||||
disabled={disabled}
|
||||
style={{width: "280px"}}
|
||||
onChange={e => {
|
||||
this.updateUserField("phone", e.target.value);
|
||||
}} />)}
|
||||
</Col>
|
||||
<Col span={Setting.isMobile() ? 24 : 11} >
|
||||
{this.isSelf() ? (<ResetModal application={this.state.application} disabled={disabled} buttonText={i18next.t("user:Reset Phone...")} destType={"phone"} />) : null}
|
||||
{this.isSelf() ? (<ResetModal application={this.state.application} countryCode={this.getCountryCode()} disabled={disabled} buttonText={i18next.t("user:Reset Phone...")} destType={"phone"} />) : null}
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
@ -342,7 +342,7 @@ class UserListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/users/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete user: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteUser(index)}
|
||||
disabled={disabled}
|
||||
>
|
||||
|
@ -198,7 +198,7 @@ class WebhookListPage extends BaseListPage {
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/webhooks/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Popconfirm
|
||||
title={`Sure to delete webhook: ${record.name} ?`}
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteWebhook(index)}
|
||||
>
|
||||
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||
|
@ -36,11 +36,10 @@ export function signup(values) {
|
||||
}).then(res => res.json());
|
||||
}
|
||||
|
||||
export function getEmailAndPhone(values) {
|
||||
return fetch(`${authConfig.serverUrl}/api/get-email-and-phone`, {
|
||||
method: "POST",
|
||||
export function getEmailAndPhone(organization, username) {
|
||||
return fetch(`${authConfig.serverUrl}/api/get-email-and-phone?organization=${organization}&username=${username}`, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
"Accept-Language": Setting.getAcceptLanguage(),
|
||||
},
|
||||
|
@ -24,8 +24,6 @@ import * as UserBackend from "../backend/UserBackend";
|
||||
import {CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import CustomGithubCorner from "../CustomGithubCorner";
|
||||
import {withRouter} from "react-router-dom";
|
||||
|
||||
const {Step} = Steps;
|
||||
const {Option} = Select;
|
||||
|
||||
class ForgetPage extends React.Component {
|
||||
@ -33,23 +31,21 @@ class ForgetPage extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
classes: props,
|
||||
account: props.account,
|
||||
applicationName: props.applicationName ?? props.match.params?.applicationName,
|
||||
application: null,
|
||||
msg: null,
|
||||
userId: "",
|
||||
username: "",
|
||||
name: "",
|
||||
email: "",
|
||||
isFixed: false,
|
||||
fixedContent: "",
|
||||
token: "",
|
||||
phone: "",
|
||||
emailCode: "",
|
||||
phoneCode: "",
|
||||
verifyType: null, // "email" or "phone"
|
||||
email: "",
|
||||
dest: "",
|
||||
isVerifyTypeFixed: false,
|
||||
verifyType: "", // "email", "phone"
|
||||
current: 0,
|
||||
};
|
||||
|
||||
this.form = React.createRef();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -88,72 +84,67 @@ class ForgetPage extends React.Component {
|
||||
switch (name) {
|
||||
case "step1":
|
||||
const username = forms.step1.getFieldValue("username");
|
||||
AuthBackend.getEmailAndPhone({
|
||||
application: forms.step1.getFieldValue("application"),
|
||||
organization: forms.step1.getFieldValue("organization"),
|
||||
username: username,
|
||||
}).then((res) => {
|
||||
AuthBackend.getEmailAndPhone(forms.step1.getFieldValue("organization"), username)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
const phone = res.data.phone;
|
||||
const email = res.data.email;
|
||||
const saveFields = () => {
|
||||
if (this.state.isFixed) {
|
||||
forms.step2.setFieldsValue({email: this.state.fixedContent});
|
||||
this.setState({username: this.state.fixedContent});
|
||||
}
|
||||
this.setState({current: 1});
|
||||
};
|
||||
this.setState({phone: phone, email: email, username: res.data.name, name: res.data.name});
|
||||
|
||||
if (phone !== "" && email === "") {
|
||||
if (phone === "" && email === "") {
|
||||
Setting.showMessage("error", "no verification method!");
|
||||
} else {
|
||||
this.setState({
|
||||
verifyType: "phone",
|
||||
name: res.data.name,
|
||||
phone: phone,
|
||||
email: email,
|
||||
});
|
||||
} else if (phone === "" && email !== "") {
|
||||
|
||||
const saveFields = (type, dest, fixed) => {
|
||||
this.setState({
|
||||
verifyType: "email",
|
||||
verifyType: type,
|
||||
isVerifyTypeFixed: fixed,
|
||||
dest: dest,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
switch (res.data2) {
|
||||
case "email":
|
||||
this.setState({isFixed: true, fixedContent: email, verifyType: "email"}, () => {saveFields();});
|
||||
saveFields("email", email, true);
|
||||
break;
|
||||
case "phone":
|
||||
this.setState({isFixed: true, fixedContent: phone, verifyType: "phone"}, () => {saveFields();});
|
||||
break;
|
||||
default:
|
||||
saveFields();
|
||||
saveFields("phone", phone, true);
|
||||
break;
|
||||
case "username":
|
||||
phone !== "" ? saveFields("phone", phone, false) : saveFields("email", email, false);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
current: 1,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "step2":
|
||||
const oAuthParams = Util.getOAuthGetParameters();
|
||||
const login = () => {
|
||||
|
||||
AuthBackend.login({
|
||||
application: forms.step2.getFieldValue("application"),
|
||||
organization: forms.step2.getFieldValue("organization"),
|
||||
username: this.state.username,
|
||||
username: forms.step2.getFieldValue("dest"),
|
||||
name: this.state.name,
|
||||
code: forms.step2.getFieldValue("emailCode"),
|
||||
code: forms.step2.getFieldValue("code"),
|
||||
type: "login",
|
||||
}, oAuthParams).then(res => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({current: 2, userId: res.data, username: res.data.split("/")[1]});
|
||||
this.setState({current: 2, userId: res.data});
|
||||
} else {
|
||||
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (this.state.verifyType === "email") {
|
||||
this.setState({username: this.state.email}, () => {login();});
|
||||
} else if (this.state.verifyType === "phone") {
|
||||
this.setState({username: this.state.phone}, () => {login();});
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -161,13 +152,13 @@ class ForgetPage extends React.Component {
|
||||
}
|
||||
|
||||
onFinish(values) {
|
||||
values.username = this.state.username;
|
||||
values.username = this.state.name;
|
||||
values.userOwner = this.getApplicationObj()?.organizationObj.name;
|
||||
UserBackend.setPassword(values.userOwner, values.username, "", values?.newPassword).then(res => {
|
||||
if (res.status === "ok") {
|
||||
Setting.redirectToLoginPage(this.getApplicationObj(), this.props.history);
|
||||
} else {
|
||||
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -179,7 +170,7 @@ class ForgetPage extends React.Component {
|
||||
|
||||
if (this.state.phone !== "") {
|
||||
options.push(
|
||||
<Option key={"phone"} value={"phone"}>
|
||||
<Option key={"phone"} value={this.state.phone} >
|
||||
{this.state.phone}
|
||||
</Option>
|
||||
);
|
||||
@ -187,7 +178,7 @@ class ForgetPage extends React.Component {
|
||||
|
||||
if (this.state.email !== "") {
|
||||
options.push(
|
||||
<Option key={"email"} value={"email"}>
|
||||
<Option key={"email"} value={this.state.email} >
|
||||
{this.state.email}
|
||||
</Option>
|
||||
);
|
||||
@ -202,8 +193,8 @@ class ForgetPage extends React.Component {
|
||||
this.onFormFinish(name, info, forms);
|
||||
}}>
|
||||
{/* STEP 1: input username -> get email & phone */}
|
||||
{this.state.current === 0 ?
|
||||
<Form
|
||||
hidden={this.state.current !== 0}
|
||||
ref={this.form}
|
||||
name="step1"
|
||||
// eslint-disable-next-line no-console
|
||||
@ -216,26 +207,22 @@ class ForgetPage extends React.Component {
|
||||
size="large"
|
||||
>
|
||||
<Form.Item
|
||||
style={{height: 0, visibility: "hidden"}}
|
||||
hidden
|
||||
name="application"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your application!"
|
||||
),
|
||||
message: i18next.t("application:Please input your application!"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Form.Item
|
||||
style={{height: 0, visibility: "hidden"}}
|
||||
hidden
|
||||
name="organization"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your organization!"
|
||||
),
|
||||
message: i18next.t("application:Please input your organization!"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
@ -244,19 +231,12 @@ class ForgetPage extends React.Component {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your username!"
|
||||
),
|
||||
message: i18next.t("forget:Please input your username!"),
|
||||
whitespace: true,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
onChange={(e) => {
|
||||
this.setState({
|
||||
username: e.target.value,
|
||||
});
|
||||
}}
|
||||
prefix={<UserOutlined />}
|
||||
placeholder={i18next.t("login:username, Email or phone")}
|
||||
/>
|
||||
@ -267,11 +247,10 @@ class ForgetPage extends React.Component {
|
||||
{i18next.t("forget:Next Step")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Form> : null}
|
||||
|
||||
{/* STEP 2: verify email or phone */}
|
||||
<Form
|
||||
hidden={this.state.current !== 1}
|
||||
{this.state.current === 1 ? <Form
|
||||
ref={this.form}
|
||||
name="step2"
|
||||
onFinishFailed={(errorInfo) =>
|
||||
@ -281,9 +260,17 @@ class ForgetPage extends React.Component {
|
||||
errorInfo.outOfDate
|
||||
)
|
||||
}
|
||||
onValuesChange={(changedValues, allValues) => {
|
||||
const verifyType = changedValues.dest?.indexOf("@") === -1 ? "phone" : "email";
|
||||
this.setState({
|
||||
dest: changedValues.dest,
|
||||
verifyType: verifyType,
|
||||
});
|
||||
}}
|
||||
initialValues={{
|
||||
application: application.name,
|
||||
organization: application.organization,
|
||||
dest: this.state.dest,
|
||||
}}
|
||||
style={{width: "300px"}}
|
||||
size="large"
|
||||
@ -294,42 +281,30 @@ class ForgetPage extends React.Component {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your application!"
|
||||
),
|
||||
message: i18next.t("application:Please input your application!"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Form.Item
|
||||
style={{height: 0, visibility: "hidden"}}
|
||||
hidden
|
||||
name="organization"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your organization!"
|
||||
),
|
||||
message: i18next.t("application:Please input your organization!"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Form.Item
|
||||
name="email" // use email instead of email/phone to adapt to RequestForm in account.go
|
||||
name="dest"
|
||||
validateFirst
|
||||
hasFeedback
|
||||
>
|
||||
{
|
||||
this.state.isFixed ? <Input disabled /> :
|
||||
<Select virtual={false}
|
||||
key={this.state.verifyType}
|
||||
disabled={this.state.isVerifyTypeFixed}
|
||||
style={{textAlign: "left"}}
|
||||
defaultValue={this.state.verifyType}
|
||||
disabled={this.state.username === ""}
|
||||
placeholder={i18next.t("forget:Choose email or phone")}
|
||||
onChange={(value) => {
|
||||
this.setState({
|
||||
verifyType: value,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{
|
||||
this.renderOptions()
|
||||
@ -338,31 +313,19 @@ class ForgetPage extends React.Component {
|
||||
}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="emailCode" // use emailCode instead of email/phoneCode to adapt to RequestForm in account.go
|
||||
name="code"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"code:Please input your verification code!"
|
||||
),
|
||||
message: i18next.t("code:Please input your verification code!"),
|
||||
},
|
||||
]}
|
||||
>
|
||||
{this.state.verifyType === "email" ? (
|
||||
<SendCodeInput
|
||||
disabled={this.state.username === "" || this.state.verifyType === ""}
|
||||
<SendCodeInput disabled={this.state.dest === ""}
|
||||
method={"forget"}
|
||||
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationName(this.getApplicationObj()), this.state.name]}
|
||||
onButtonClickArgs={[this.state.dest, this.state.verifyType, Setting.getApplicationName(this.getApplicationObj()), this.state.name]}
|
||||
application={application}
|
||||
/>
|
||||
) : (
|
||||
<SendCodeInput
|
||||
disabled={this.state.username === "" || this.state.verifyType === ""}
|
||||
method={"forget"}
|
||||
onButtonClickArgs={[this.state.phone, "phone", Setting.getApplicationName(this.getApplicationObj()), this.state.name]}
|
||||
application={application}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<br />
|
||||
<Form.Item>
|
||||
@ -374,11 +337,11 @@ class ForgetPage extends React.Component {
|
||||
{i18next.t("forget:Next Step")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Form> : null}
|
||||
|
||||
{/* STEP 3 */}
|
||||
{this.state.current === 2 ?
|
||||
<Form
|
||||
hidden={this.state.current !== 2}
|
||||
ref={this.form}
|
||||
name="step3"
|
||||
onFinish={(values) => this.onFinish(values)}
|
||||
@ -397,26 +360,22 @@ class ForgetPage extends React.Component {
|
||||
size="large"
|
||||
>
|
||||
<Form.Item
|
||||
style={{height: 0, visibility: "hidden"}}
|
||||
hidden
|
||||
name="application"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your application!"
|
||||
),
|
||||
message: i18next.t("application:Please input your application!"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Form.Item
|
||||
style={{height: 0, visibility: "hidden"}}
|
||||
hidden
|
||||
name="organization"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your organization!"
|
||||
),
|
||||
message: i18next.t("application:Please input your organization!"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
@ -426,9 +385,7 @@ class ForgetPage extends React.Component {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please input your password!"
|
||||
),
|
||||
message: i18next.t("login:Please input your password!"),
|
||||
},
|
||||
]}
|
||||
hasFeedback
|
||||
@ -446,9 +403,7 @@ class ForgetPage extends React.Component {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: i18next.t(
|
||||
"forget:Please confirm your password!"
|
||||
),
|
||||
message: i18next.t("signup:Please confirm your password!"),
|
||||
},
|
||||
({getFieldValue}) => ({
|
||||
validator(rule, value) {
|
||||
@ -456,9 +411,7 @@ class ForgetPage extends React.Component {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(
|
||||
i18next.t(
|
||||
"forget:Your confirmed password is inconsistent with the password!"
|
||||
)
|
||||
i18next.t("signup:Your confirmed password is inconsistent with the password!")
|
||||
);
|
||||
},
|
||||
}),
|
||||
@ -476,7 +429,7 @@ class ForgetPage extends React.Component {
|
||||
{i18next.t("forget:Change Password")}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Form> : null}
|
||||
</Form.Provider>
|
||||
);
|
||||
}
|
||||
@ -516,6 +469,20 @@ class ForgetPage extends React.Component {
|
||||
<Col span={24}>
|
||||
<Steps
|
||||
current={this.state.current}
|
||||
items={[
|
||||
{
|
||||
title: i18next.t("forget:Account"),
|
||||
icon: <UserOutlined />,
|
||||
},
|
||||
{
|
||||
title: i18next.t("forget:Verify"),
|
||||
icon: <SolutionOutlined />,
|
||||
},
|
||||
{
|
||||
title: i18next.t("forget:Reset"),
|
||||
icon: <KeyOutlined />,
|
||||
},
|
||||
]}
|
||||
style={{
|
||||
width: "90%",
|
||||
maxWidth: "500px",
|
||||
@ -523,24 +490,12 @@ class ForgetPage extends React.Component {
|
||||
marginTop: "80px",
|
||||
}}
|
||||
>
|
||||
<Step
|
||||
title={i18next.t("forget:Account")}
|
||||
icon={<UserOutlined />}
|
||||
/>
|
||||
<Step
|
||||
title={i18next.t("forget:Verify")}
|
||||
icon={<SolutionOutlined />}
|
||||
/>
|
||||
<Step
|
||||
title={i18next.t("forget:Reset")}
|
||||
icon={<KeyOutlined />}
|
||||
/>
|
||||
</Steps>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={24} style={{display: "flex", justifyContent: "center"}}>
|
||||
<div style={{marginTop: "10px", textAlign: "center"}}>
|
||||
<div style={{marginTop: "40px", textAlign: "center"}}>
|
||||
{this.renderForm(application)}
|
||||
</div>
|
||||
</Col>
|
||||
|
@ -82,13 +82,13 @@ class LoginPage extends React.Component {
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
if (this.state.application && !prevState.application) {
|
||||
const defaultCaptchaProviderItems = this.getDefaultCaptchaProviderItems(this.state.application);
|
||||
const captchaProviderItems = this.getCaptchaProviderItems(this.state.application);
|
||||
|
||||
if (!defaultCaptchaProviderItems) {
|
||||
if (!captchaProviderItems) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({enableCaptchaModal: defaultCaptchaProviderItems.some(providerItem => providerItem.rule === "Always")});
|
||||
this.setState({enableCaptchaModal: captchaProviderItems.some(providerItem => providerItem.rule === "Always")});
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@ class LoginPage extends React.Component {
|
||||
Setting.goToLinkSoft(ths, `/prompt/${application.name}?redirectUri=${oAuthParams.redirectUri}&code=${code}&state=${oAuthParams.state}`);
|
||||
}
|
||||
} else {
|
||||
Setting.showMessage("error", `Failed to sign in: ${res.msg}`);
|
||||
Setting.showMessage("error", `${i18next.t("application:Failed to log in")}: ${res.msg}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -262,13 +262,7 @@ class LoginPage extends React.Component {
|
||||
if (this.state.loginMethod === "password" && this.state.enableCaptchaModal) {
|
||||
this.setState({
|
||||
openCaptchaModal: true,
|
||||
verifyCaptcha: (captchaType, captchaToken, secret) => {
|
||||
values["captchaType"] = captchaType;
|
||||
values["captchaToken"] = captchaToken;
|
||||
values["clientSecret"] = secret;
|
||||
|
||||
this.login(values);
|
||||
},
|
||||
values: values,
|
||||
});
|
||||
} else {
|
||||
this.login(values);
|
||||
@ -290,8 +284,6 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
Setting.showMessage("success", msg);
|
||||
|
||||
this.setState({openCaptchaModal: false});
|
||||
|
||||
if (casParams.service !== "") {
|
||||
const st = res.data;
|
||||
const newUrl = new URL(casParams.service);
|
||||
@ -299,8 +291,7 @@ class LoginPage extends React.Component {
|
||||
window.location.href = newUrl.toString();
|
||||
}
|
||||
} else {
|
||||
this.setState({openCaptchaModal: false});
|
||||
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
|
||||
Setting.showMessage("error", `${i18next.t("application:Failed to log in")}: ${res.msg}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -338,8 +329,7 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.setState({openCaptchaModal: false});
|
||||
Setting.showMessage("error", `Failed to log in: ${res.msg}`);
|
||||
Setting.showMessage("error", `${i18next.t("application:Failed to log in")}: ${res.msg}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -378,6 +368,13 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
|
||||
if (application.enablePassword) {
|
||||
let loginWidth = 320;
|
||||
if (Setting.getLanguage() === "fr") {
|
||||
loginWidth += 10;
|
||||
} else if (Setting.getLanguage() === "es") {
|
||||
loginWidth += 40;
|
||||
}
|
||||
|
||||
return (
|
||||
<Form
|
||||
name="normal_login"
|
||||
@ -391,7 +388,7 @@ class LoginPage extends React.Component {
|
||||
onFinish={(values) => {
|
||||
this.onFinish(values);
|
||||
}}
|
||||
style={{width: "300px"}}
|
||||
style={{width: `${loginWidth}px`}}
|
||||
size="large"
|
||||
ref={this.form}
|
||||
>
|
||||
@ -542,7 +539,7 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
getDefaultCaptchaProviderItems(application) {
|
||||
getCaptchaProviderItems(application) {
|
||||
const providers = application?.providers;
|
||||
|
||||
if (providers === undefined || providers === null) {
|
||||
@ -554,7 +551,7 @@ class LoginPage extends React.Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
return providerItem.provider.category === "Captcha" && providerItem.provider.type === "Default";
|
||||
return providerItem.provider.category === "Captcha";
|
||||
});
|
||||
}
|
||||
|
||||
@ -563,22 +560,25 @@ class LoginPage extends React.Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
const provider = this.getDefaultCaptchaProviderItems(application)
|
||||
const provider = this.getCaptchaProviderItems(application)
|
||||
.filter(providerItem => providerItem.rule === "Always")
|
||||
.map(providerItem => providerItem.provider)[0];
|
||||
|
||||
return <CaptchaModal
|
||||
owner={provider.owner}
|
||||
name={provider.name}
|
||||
captchaType={provider.type}
|
||||
subType={provider.subType}
|
||||
clientId={provider.clientId}
|
||||
clientId2={provider.clientId2}
|
||||
clientSecret={provider.clientSecret}
|
||||
clientSecret2={provider.clientSecret2}
|
||||
open={this.state.openCaptchaModal}
|
||||
onOk={(captchaType, captchaToken, secret) => this.state.verifyCaptcha?.(captchaType, captchaToken, secret)}
|
||||
canCancel={false}
|
||||
visible={this.state.openCaptchaModal}
|
||||
onOk={(captchaType, captchaToken, clientSecret) => {
|
||||
const values = this.state.values;
|
||||
values["captchaType"] = captchaType;
|
||||
values["captchaToken"] = captchaToken;
|
||||
values["clientSecret"] = clientSecret;
|
||||
|
||||
this.login(values);
|
||||
this.setState({openCaptchaModal: false});
|
||||
}}
|
||||
onCancel={() => this.setState({openCaptchaModal: false})}
|
||||
isCurrentProvider={true}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,7 @@ export function getAuthUrl(application, provider, method) {
|
||||
const state = Util.getStateFromQueryParams(application.name, provider.name, method, isShortState);
|
||||
const codeChallenge = "P3S-a7dr8bgM4bF6vOyiKkKETDl16rcAzao9F8UIL1Y"; // SHA256(Base64-URL-encode("casdoor-verifier"))
|
||||
|
||||
if (provider.type === "Google" || provider.type === "GitHub" || provider.type === "QQ" || provider.type === "Facebook" || provider.type === "DingTalk"
|
||||
if (provider.type === "Google" || provider.type === "GitHub" || provider.type === "QQ" || provider.type === "Facebook"
|
||||
|| provider.type === "Weibo" || provider.type === "Gitee" || provider.type === "LinkedIn" || provider.type === "GitLab" || provider.type === "AzureAD"
|
||||
|| provider.type === "Slack" || provider.type === "Line" || provider.type === "Amazon" || provider.type === "Auth0" || provider.type === "BattleNet"
|
||||
|| provider.type === "Bitbucket" || provider.type === "Box" || provider.type === "CloudFoundry" || provider.type === "Dailymotion"
|
||||
@ -390,6 +390,8 @@ export function getAuthUrl(application, provider, method) {
|
||||
|| provider.type === "Twitch" || provider.type === "Typetalk" || provider.type === "Uber" || provider.type === "VK" || provider.type === "Wepay"
|
||||
|| provider.type === "Xero" || provider.type === "Yahoo" || provider.type === "Yammer" || provider.type === "Yandex" || provider.type === "Zoom") {
|
||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&state=${state}`;
|
||||
} else if (provider.type === "DingTalk") {
|
||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${scope}&response_type=code&prompt=consent&state=${state}`;
|
||||
} else if (provider.type === "WeChat") {
|
||||
if (navigator.userAgent.includes("MicroMessenger")) {
|
||||
return `${authInfo[provider.type].mpEndpoint}?appid=${provider.clientId2}&redirect_uri=${redirectUri}&state=${state}&scope=${authInfo[provider.type].mpScope}&response_type=code#wechat_redirect`;
|
||||
|
@ -26,7 +26,7 @@ import SelectRegionBox from "../SelectRegionBox";
|
||||
import CustomGithubCorner from "../CustomGithubCorner";
|
||||
import SelectLanguageBox from "../SelectLanguageBox";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import PhoneNumberInput from "../common/PhoneNumberInput";
|
||||
import {CountryCodeSelect} from "../common/CountryCodeSelect";
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
@ -82,7 +82,7 @@ class SignupPage extends React.Component {
|
||||
this.form = React.createRef();
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
componentDidMount() {
|
||||
let applicationName = this.state.applicationName;
|
||||
const oAuthParams = Util.getOAuthGetParameters();
|
||||
if (oAuthParams !== null) {
|
||||
@ -208,7 +208,6 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="username"
|
||||
key="username"
|
||||
label={i18next.t("signup:Username")}
|
||||
rules={[
|
||||
{
|
||||
@ -227,7 +226,6 @@ class SignupPage extends React.Component {
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
name="firstName"
|
||||
key="firstName"
|
||||
label={i18next.t("general:First name")}
|
||||
rules={[
|
||||
{
|
||||
@ -241,7 +239,6 @@ class SignupPage extends React.Component {
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="lastName"
|
||||
key="lastName"
|
||||
label={i18next.t("general:Last name")}
|
||||
rules={[
|
||||
{
|
||||
@ -260,7 +257,6 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="name"
|
||||
key="name"
|
||||
label={(signupItem.rule === "Real name" || signupItem.rule === "First, last") ? i18next.t("general:Real name") : i18next.t("general:Display name")}
|
||||
rules={[
|
||||
{
|
||||
@ -277,7 +273,6 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="affiliation"
|
||||
key="affiliation"
|
||||
label={i18next.t("user:Affiliation")}
|
||||
rules={[
|
||||
{
|
||||
@ -294,7 +289,6 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="idCard"
|
||||
key="idCard"
|
||||
label={i18next.t("user:ID card")}
|
||||
rules={[
|
||||
{
|
||||
@ -316,7 +310,6 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="country_region"
|
||||
key="region"
|
||||
label={i18next.t("user:Country/Region")}
|
||||
rules={[
|
||||
{
|
||||
@ -333,7 +326,6 @@ class SignupPage extends React.Component {
|
||||
<React.Fragment>
|
||||
<Form.Item
|
||||
name="email"
|
||||
key="email"
|
||||
label={i18next.t("general:Email")}
|
||||
rules={[
|
||||
{
|
||||
@ -359,7 +351,6 @@ class SignupPage extends React.Component {
|
||||
signupItem.rule !== "No verification" &&
|
||||
<Form.Item
|
||||
name="emailCode"
|
||||
key="emailCode"
|
||||
label={i18next.t("code:Email code")}
|
||||
rules={[{
|
||||
required: required,
|
||||
@ -383,46 +374,31 @@ class SignupPage extends React.Component {
|
||||
<Input.Group compact>
|
||||
<Form.Item
|
||||
name="countryCode"
|
||||
key="countryCode"
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please select your country code!"),
|
||||
},
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (this.state.phone !== "" && !Setting.isValidPhone(this.state.phone, this.state.countryCode)) {
|
||||
this.setState({validPhone: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Phone!"));
|
||||
}
|
||||
|
||||
this.setState({validPhone: true});
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
]}
|
||||
>
|
||||
<PhoneNumberInput
|
||||
showSearsh={true}
|
||||
<CountryCodeSelect
|
||||
style={{width: "35%"}}
|
||||
value={this.state.countryCode}
|
||||
onChange={(value) => {this.setState({countryCode: value});}}
|
||||
countryCodes={this.getApplicationObj().organizationObj.countryCodes}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="phone"
|
||||
key="phone"
|
||||
dependencies={["countryCode"]}
|
||||
noStyle
|
||||
rules={[
|
||||
{
|
||||
required: required,
|
||||
message: i18next.t("signup:Please input your phone number!"),
|
||||
},
|
||||
{
|
||||
({getFieldValue}) => ({
|
||||
validator: (_, value) => {
|
||||
if (this.state.phone !== "" && !Setting.isValidPhone(this.state.phone, this.state.countryCode)) {
|
||||
if (value !== "" && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
|
||||
this.setState({validPhone: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Phone!"));
|
||||
}
|
||||
@ -430,7 +406,7 @@ class SignupPage extends React.Component {
|
||||
this.setState({validPhone: true});
|
||||
return Promise.resolve();
|
||||
},
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
@ -442,7 +418,6 @@ class SignupPage extends React.Component {
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="phoneCode"
|
||||
key="phoneCode"
|
||||
label={i18next.t("code:Phone code")}
|
||||
rules={[
|
||||
{
|
||||
@ -456,6 +431,7 @@ class SignupPage extends React.Component {
|
||||
method={"signup"}
|
||||
onButtonClickArgs={[this.state.phone, "phone", Setting.getApplicationName(application)]}
|
||||
application={application}
|
||||
countryCode={this.form.current?.getFieldValue("countryCode")}
|
||||
/>
|
||||
</Form.Item>
|
||||
</React.Fragment>
|
||||
@ -464,7 +440,6 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="password"
|
||||
key="password"
|
||||
label={i18next.t("general:Password")}
|
||||
rules={[
|
||||
{
|
||||
@ -482,7 +457,6 @@ class SignupPage extends React.Component {
|
||||
return (
|
||||
<Form.Item
|
||||
name="confirm"
|
||||
key="confirm"
|
||||
label={i18next.t("signup:Confirm")}
|
||||
dependencies={["password"]}
|
||||
hasFeedback
|
||||
@ -560,6 +534,7 @@ class SignupPage extends React.Component {
|
||||
initialValues={{
|
||||
application: application.name,
|
||||
organization: application.organization,
|
||||
countryCode: application.organizationObj.countryCodes?.[0],
|
||||
}}
|
||||
size="large"
|
||||
layout={Setting.isMobile() ? "vertical" : "horizontal"}
|
||||
|
@ -51,7 +51,9 @@ window.fetch = async(url, option = {}) => {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
originalFetch(url, option).then(res => {
|
||||
if (!url.startsWith("/api/get-organizations")) {
|
||||
responseFilters.forEach(filter => filter(res.clone()));
|
||||
}
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
|
@ -24,8 +24,8 @@ export function getLdaps(owner) {
|
||||
}).then(res => res.json());
|
||||
}
|
||||
|
||||
export function getLdap(id) {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-ldap?id=${id}`, {
|
||||
export function getLdap(owner, name) {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-ldap?id=${owner}/${encodeURIComponent(name)}`, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
import * as Setting from "../Setting";
|
||||
|
||||
export function getSystemInfo(owner, name) {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-system-info?id=${owner}/${encodeURIComponent(name)}`, {
|
||||
export function getSystemInfo() {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-system-info`, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
@ -24,8 +24,8 @@ export function getSystemInfo(owner, name) {
|
||||
}).then(res => res.json());
|
||||
}
|
||||
|
||||
export function getGitHubLatestReleaseVersion() {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-release`, {
|
||||
export function getVersionInfo() {
|
||||
return fetch(`${Setting.ServerUrl}/api/get-version-info`, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
|
@ -109,12 +109,13 @@ export function setPassword(userOwner, userName, oldPassword, newPassword) {
|
||||
}).then(res => res.json());
|
||||
}
|
||||
|
||||
export function sendCode(checkType, checkId, checkKey, method, dest, type, applicationId, checkUser = "") {
|
||||
export function sendCode(checkType, captchaToken, clientSecret, method, countryCode = "", dest, type, applicationId, checkUser = "") {
|
||||
const formData = new FormData();
|
||||
formData.append("checkType", checkType);
|
||||
formData.append("checkId", checkId);
|
||||
formData.append("checkKey", checkKey);
|
||||
formData.append("captchaToken", captchaToken);
|
||||
formData.append("clientSecret", clientSecret);
|
||||
formData.append("method", method);
|
||||
formData.append("countryCode", countryCode);
|
||||
formData.append("dest", dest);
|
||||
formData.append("type", type);
|
||||
formData.append("applicationId", applicationId);
|
||||
|
@ -61,8 +61,13 @@ class HomePage extends React.Component {
|
||||
}
|
||||
} else {
|
||||
this.state.applications.forEach(application => {
|
||||
let homepageUrl = application.homepageUrl;
|
||||
if (homepageUrl === "<custom-url>") {
|
||||
homepageUrl = this.props.account.homepage;
|
||||
}
|
||||
|
||||
items.push({
|
||||
link: application.homepageUrl, name: application.displayName, organizer: application.description, logo: application.logo, createdTime: "",
|
||||
link: homepageUrl, name: application.displayName, organizer: application.description, logo: application.logo, createdTime: "",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -19,64 +19,65 @@ import * as UserBackend from "../backend/UserBackend";
|
||||
import {CaptchaWidget} from "./CaptchaWidget";
|
||||
import {SafetyOutlined} from "@ant-design/icons";
|
||||
|
||||
export const CaptchaModal = ({
|
||||
owner,
|
||||
name,
|
||||
captchaType,
|
||||
subType,
|
||||
clientId,
|
||||
clientId2,
|
||||
clientSecret,
|
||||
clientSecret2,
|
||||
open,
|
||||
onOk,
|
||||
onCancel,
|
||||
canCancel,
|
||||
}) => {
|
||||
const [visible, setVisible] = React.useState(false);
|
||||
export const CaptchaModal = (props) => {
|
||||
const {owner, name, visible, onOk, onCancel, isCurrentProvider} = props;
|
||||
|
||||
const [captchaType, setCaptchaType] = React.useState("none");
|
||||
const [clientId, setClientId] = React.useState("");
|
||||
const [clientSecret, setClientSecret] = React.useState("");
|
||||
const [subType, setSubType] = React.useState("");
|
||||
const [clientId2, setClientId2] = React.useState("");
|
||||
const [clientSecret2, setClientSecret2] = React.useState("");
|
||||
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [captchaImg, setCaptchaImg] = React.useState("");
|
||||
const [captchaToken, setCaptchaToken] = React.useState("");
|
||||
const [secret, setSecret] = React.useState(clientSecret);
|
||||
const [secret2, setSecret2] = React.useState(clientSecret2);
|
||||
|
||||
const defaultInputRef = React.useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
setVisible(() => {
|
||||
if (open) {
|
||||
getCaptchaFromBackend();
|
||||
if (visible) {
|
||||
loadCaptcha();
|
||||
} else {
|
||||
cleanUp();
|
||||
handleCancel();
|
||||
setOpen(false);
|
||||
}
|
||||
return open;
|
||||
});
|
||||
}, [open]);
|
||||
}, [visible]);
|
||||
|
||||
const handleOk = () => {
|
||||
onOk?.(captchaType, captchaToken, secret);
|
||||
onOk?.(captchaType, captchaToken, clientSecret);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setCaptchaToken("");
|
||||
onCancel?.();
|
||||
};
|
||||
|
||||
const cleanUp = () => {
|
||||
setCaptchaToken("");
|
||||
};
|
||||
|
||||
const getCaptchaFromBackend = () => {
|
||||
UserBackend.getCaptcha(owner, name, true).then((res) => {
|
||||
if (captchaType === "Default") {
|
||||
setSecret(res.captchaId);
|
||||
const loadCaptcha = () => {
|
||||
UserBackend.getCaptcha(owner, name, isCurrentProvider).then((res) => {
|
||||
if (res.type === "none") {
|
||||
handleOk();
|
||||
} else if (res.type === "Default") {
|
||||
setOpen(true);
|
||||
setClientSecret(res.captchaId);
|
||||
setCaptchaImg(res.captchaImage);
|
||||
setCaptchaType("Default");
|
||||
} else {
|
||||
setSecret(res.clientSecret);
|
||||
setSecret2(res.clientSecret2);
|
||||
setOpen(true);
|
||||
setCaptchaType(res.type);
|
||||
setClientId(res.clientId);
|
||||
setClientSecret(res.clientSecret);
|
||||
setSubType(res.subType);
|
||||
setClientId2(res.clientId2);
|
||||
setClientSecret2(res.clientSecret2);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const renderDefaultCaptcha = () => {
|
||||
return (
|
||||
<Col>
|
||||
<Col style={{textAlign: "center"}}>
|
||||
<div style={{display: "inline-block"}}>
|
||||
<Row
|
||||
style={{
|
||||
backgroundImage: `url('data:image/png;base64,${captchaImg}')`,
|
||||
@ -85,12 +86,13 @@ export const CaptchaModal = ({
|
||||
width: "200px",
|
||||
borderRadius: "5px",
|
||||
border: "1px solid #ccc",
|
||||
marginBottom: 10,
|
||||
marginBottom: "20px",
|
||||
}}
|
||||
/>
|
||||
<Row>
|
||||
<Input
|
||||
autoFocus
|
||||
ref={defaultInputRef}
|
||||
style={{width: "200px"}}
|
||||
value={captchaToken}
|
||||
prefix={<SafetyOutlined />}
|
||||
placeholder={i18next.t("general:Captcha")}
|
||||
@ -98,15 +100,16 @@ export const CaptchaModal = ({
|
||||
onChange={(e) => setCaptchaToken(e.target.value)}
|
||||
/>
|
||||
</Row>
|
||||
</div>
|
||||
</Col>
|
||||
);
|
||||
};
|
||||
|
||||
const onSubmit = (token) => {
|
||||
const onChange = (token) => {
|
||||
setCaptchaToken(token);
|
||||
};
|
||||
|
||||
const renderCheck = () => {
|
||||
const renderCaptcha = () => {
|
||||
if (captchaType === "Default") {
|
||||
return renderDefaultCaptcha();
|
||||
} else {
|
||||
@ -117,10 +120,10 @@ export const CaptchaModal = ({
|
||||
captchaType={captchaType}
|
||||
subType={subType}
|
||||
siteKey={clientId}
|
||||
clientSecret={secret}
|
||||
onChange={onSubmit}
|
||||
clientSecret={clientSecret}
|
||||
onChange={onChange}
|
||||
clientId2={clientId2}
|
||||
clientSecret2={secret2}
|
||||
clientSecret2={clientSecret2}
|
||||
/>
|
||||
</Row>
|
||||
</Col>
|
||||
@ -129,31 +132,41 @@ export const CaptchaModal = ({
|
||||
};
|
||||
|
||||
const renderFooter = () => {
|
||||
if (canCancel) {
|
||||
let isOkDisabled = false;
|
||||
if (captchaType === "Default") {
|
||||
const regex = /^\d{5}$/;
|
||||
if (!regex.test(captchaToken)) {
|
||||
isOkDisabled = true;
|
||||
}
|
||||
} else if (captchaToken === "") {
|
||||
isOkDisabled = true;
|
||||
}
|
||||
|
||||
return [
|
||||
<Button key="cancel" onClick={handleCancel}>{i18next.t("user:Cancel")}</Button>,
|
||||
<Button key="ok" type="primary" onClick={handleOk}>{i18next.t("user:OK")}</Button>,
|
||||
<Button key="ok" disabled={isOkDisabled} type="primary" onClick={handleOk}>{i18next.t("user:OK")}</Button>,
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
<Button key="ok" type="primary" onClick={handleOk}>{i18next.t("user:OK")}</Button>,
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Modal
|
||||
closable={false}
|
||||
maskClosable={false}
|
||||
destroyOnClose={true}
|
||||
title={i18next.t("general:Captcha")}
|
||||
open={visible}
|
||||
width={348}
|
||||
open={open}
|
||||
okText={i18next.t("user:OK")}
|
||||
cancelText={i18next.t("user:Cancel")}
|
||||
width={350}
|
||||
footer={renderFooter()}
|
||||
onCancel={handleCancel}
|
||||
onOk={handleOk}
|
||||
>
|
||||
{renderCheck()}
|
||||
<div style={{marginTop: "20px", marginBottom: "50px"}}>
|
||||
{
|
||||
renderCaptcha()
|
||||
}
|
||||
</div>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
@ -16,23 +16,11 @@ import {Button} from "antd";
|
||||
import React from "react";
|
||||
import i18next from "i18next";
|
||||
import {CaptchaModal} from "./CaptchaModal";
|
||||
import * as ProviderBackend from "../backend/ProviderBackend";
|
||||
import * as UserBackend from "../backend/UserBackend";
|
||||
|
||||
export const CaptchaPreview = ({
|
||||
provider,
|
||||
providerName,
|
||||
clientSecret,
|
||||
captchaType,
|
||||
subType,
|
||||
owner,
|
||||
clientId,
|
||||
name,
|
||||
providerUrl,
|
||||
clientId2,
|
||||
clientSecret2,
|
||||
}) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
export const CaptchaPreview = (props) => {
|
||||
const {owner, name, provider, captchaType, subType, clientId, clientSecret, clientId2, clientSecret2, providerUrl} = props;
|
||||
const [visible, setVisible] = React.useState(false);
|
||||
|
||||
const clickPreview = () => {
|
||||
provider.name = name;
|
||||
@ -41,15 +29,16 @@ export const CaptchaPreview = ({
|
||||
provider.providerUrl = providerUrl;
|
||||
if (clientSecret !== "***") {
|
||||
provider.clientSecret = clientSecret;
|
||||
ProviderBackend.updateProvider(owner, providerName, provider).then(() => {
|
||||
setOpen(true);
|
||||
});
|
||||
// ProviderBackend.updateProvider(owner, providerName, provider).then(() => {
|
||||
// setOpen(true);
|
||||
// });
|
||||
setVisible(true);
|
||||
} else {
|
||||
setOpen(true);
|
||||
setVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
const getButtonDisabled = () => {
|
||||
const isButtonDisabled = () => {
|
||||
if (captchaType !== "Default") {
|
||||
if (!clientId || !clientSecret) {
|
||||
return true;
|
||||
@ -63,14 +52,14 @@ export const CaptchaPreview = ({
|
||||
return false;
|
||||
};
|
||||
|
||||
const onOk = (captchaType, captchaToken, secret) => {
|
||||
UserBackend.verifyCaptcha(captchaType, captchaToken, secret).then(() => {
|
||||
setOpen(false);
|
||||
const onOk = (captchaType, captchaToken, clientSecret) => {
|
||||
UserBackend.verifyCaptcha(captchaType, captchaToken, clientSecret).then(() => {
|
||||
setVisible(false);
|
||||
});
|
||||
};
|
||||
|
||||
const onCancel = () => {
|
||||
setOpen(false);
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -79,23 +68,17 @@ export const CaptchaPreview = ({
|
||||
style={{fontSize: 14}}
|
||||
type={"primary"}
|
||||
onClick={clickPreview}
|
||||
disabled={getButtonDisabled()}
|
||||
disabled={isButtonDisabled()}
|
||||
>
|
||||
{i18next.t("general:Preview")}
|
||||
</Button>
|
||||
<CaptchaModal
|
||||
owner={owner}
|
||||
name={name}
|
||||
captchaType={captchaType}
|
||||
subType={subType}
|
||||
clientId={clientId}
|
||||
clientId2={clientId2}
|
||||
clientSecret={clientSecret}
|
||||
clientSecret2={clientSecret2}
|
||||
open={open}
|
||||
visible={visible}
|
||||
onOk={onOk}
|
||||
onCancel={onCancel}
|
||||
canCancel={true}
|
||||
isCurrentProvider={true}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
@ -14,7 +14,9 @@
|
||||
|
||||
import React, {useEffect} from "react";
|
||||
|
||||
export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onChange, clientId2, clientSecret2}) => {
|
||||
export const CaptchaWidget = (props) => {
|
||||
const {captchaType, subType, siteKey, clientSecret, clientId2, clientSecret2, onChange} = props;
|
||||
|
||||
const loadScript = (src) => {
|
||||
const tag = document.createElement("script");
|
||||
tag.async = false;
|
||||
|
@ -16,43 +16,29 @@ import {Select} from "antd";
|
||||
import * as Setting from "../Setting";
|
||||
import React from "react";
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
export default function PhoneNumberInput(props) {
|
||||
const {onChange, style, showSearch} = props;
|
||||
const value = props.value ?? "CN";
|
||||
export const CountryCodeSelect = (props) => {
|
||||
const {onChange, style, disabled, value} = props;
|
||||
const countryCodes = props.countryCodes ?? [];
|
||||
|
||||
const handleOnChange = (e) => {
|
||||
onChange?.(e);
|
||||
const handleOnChange = (value) => {
|
||||
onChange?.(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<Select
|
||||
virtual={false}
|
||||
showSearch
|
||||
style={style}
|
||||
disabled={disabled}
|
||||
value={value}
|
||||
dropdownMatchSelectWidth={false}
|
||||
optionLabelProp={"label"}
|
||||
showSearch={showSearch}
|
||||
onChange={handleOnChange}
|
||||
filterOption={(input, option) =>
|
||||
(option?.label ?? "").toLowerCase().includes(input.toLowerCase())
|
||||
}
|
||||
filterOption={(input, option) => (option?.text ?? "").toLowerCase().includes(input.toLowerCase())}
|
||||
>
|
||||
{
|
||||
Setting.getCountriesData(countryCodes).map((country) => (
|
||||
<Option key={country.code} value={country.code} label={`+${country.phone}`} >
|
||||
<div style={{display: "flex", justifyContent: "space-between"}}>
|
||||
<div>
|
||||
{Setting.countryFlag(country)}
|
||||
{`${country.name}`}
|
||||
</div>
|
||||
{`+${country.phone}`}
|
||||
</div>
|
||||
</Option>
|
||||
))
|
||||
Setting.getCountryCodeData(countryCodes).map((country) => Setting.getCountryCodeOption(country))
|
||||
}
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
};
|
@ -12,29 +12,21 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import {Button, Col, Input, Modal, Row} from "antd";
|
||||
import {Button, Input} from "antd";
|
||||
import React from "react";
|
||||
import i18next from "i18next";
|
||||
import * as UserBackend from "../backend/UserBackend";
|
||||
import {SafetyOutlined} from "@ant-design/icons";
|
||||
import {CaptchaWidget} from "./CaptchaWidget";
|
||||
import {CaptchaModal} from "./CaptchaModal";
|
||||
|
||||
const {Search} = Input;
|
||||
|
||||
export const SendCodeInput = (props) => {
|
||||
const {disabled, textBefore, onChange, onButtonClickArgs, application, method} = props;
|
||||
const {disabled, textBefore, onChange, onButtonClickArgs, application, method, countryCode} = props;
|
||||
const [visible, setVisible] = React.useState(false);
|
||||
const [key, setKey] = React.useState("");
|
||||
const [captchaImg, setCaptchaImg] = React.useState("");
|
||||
const [checkType, setCheckType] = React.useState("");
|
||||
const [checkId, setCheckId] = React.useState("");
|
||||
|
||||
const [buttonLeftTime, setButtonLeftTime] = React.useState(0);
|
||||
const [buttonLoading, setButtonLoading] = React.useState(false);
|
||||
const [buttonDisabled, setButtonDisabled] = React.useState(true);
|
||||
const [clientId, setClientId] = React.useState("");
|
||||
const [subType, setSubType] = React.useState("");
|
||||
const [clientId2, setClientId2] = React.useState("");
|
||||
const [clientSecret2, setClientSecret2] = React.useState("");
|
||||
|
||||
const handleCountDown = (leftTime = 60) => {
|
||||
let leftTimeSecond = leftTime;
|
||||
@ -50,11 +42,10 @@ export const SendCodeInput = (props) => {
|
||||
setTimeout(countDown, 1000);
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
const handleOk = (captchaType, captchaToken, clintSecret) => {
|
||||
setVisible(false);
|
||||
setButtonLoading(true);
|
||||
UserBackend.sendCode(checkType, checkId, key, method, ...onButtonClickArgs).then(res => {
|
||||
setKey("");
|
||||
UserBackend.sendCode(captchaType, captchaToken, clintSecret, method, countryCode, ...onButtonClickArgs).then(res => {
|
||||
setButtonLoading(false);
|
||||
if (res) {
|
||||
handleCountDown(60);
|
||||
@ -64,76 +55,6 @@ export const SendCodeInput = (props) => {
|
||||
|
||||
const handleCancel = () => {
|
||||
setVisible(false);
|
||||
setKey("");
|
||||
};
|
||||
|
||||
const loadCaptcha = () => {
|
||||
UserBackend.getCaptcha(application.owner, application.name, false).then(res => {
|
||||
if (res.type === "none") {
|
||||
UserBackend.sendCode("none", "", "", method, ...onButtonClickArgs).then(res => {
|
||||
if (res) {
|
||||
handleCountDown(60);
|
||||
}
|
||||
});
|
||||
} else if (res.type === "Default") {
|
||||
setCheckId(res.captchaId);
|
||||
setCaptchaImg(res.captchaImage);
|
||||
setCheckType("Default");
|
||||
setVisible(true);
|
||||
} else {
|
||||
setCheckType(res.type);
|
||||
setClientId(res.clientId);
|
||||
setCheckId(res.clientSecret);
|
||||
setVisible(true);
|
||||
setSubType(res.subType);
|
||||
setClientId2(res.clientId2);
|
||||
setClientSecret2(res.clientSecret2);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const renderCaptcha = () => {
|
||||
return (
|
||||
<Col>
|
||||
<Row
|
||||
style={{
|
||||
backgroundImage: `url('data:image/png;base64,${captchaImg}')`,
|
||||
backgroundRepeat: "no-repeat",
|
||||
height: "80px",
|
||||
width: "200px",
|
||||
borderRadius: "5px",
|
||||
border: "1px solid #ccc",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
/>
|
||||
<Row>
|
||||
<Input autoFocus value={key} prefix={<SafetyOutlined />} placeholder={i18next.t("general:Captcha")} onPressEnter={handleOk} onChange={e => setKey(e.target.value)} />
|
||||
</Row>
|
||||
</Col>
|
||||
);
|
||||
};
|
||||
|
||||
const onSubmit = (token) => {
|
||||
setButtonDisabled(false);
|
||||
setKey(token);
|
||||
};
|
||||
|
||||
const renderCheck = () => {
|
||||
if (checkType === "Default") {
|
||||
return renderCaptcha();
|
||||
} else {
|
||||
return (
|
||||
<CaptchaWidget
|
||||
captchaType={checkType}
|
||||
subType={subType}
|
||||
siteKey={clientId}
|
||||
clientSecret={checkId}
|
||||
onChange={onSubmit}
|
||||
clientId2={clientId2}
|
||||
clientSecret2={clientSecret2}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@ -149,25 +70,16 @@ export const SendCodeInput = (props) => {
|
||||
{buttonLeftTime > 0 ? `${buttonLeftTime} s` : buttonLoading ? i18next.t("code:Sending Code") : i18next.t("code:Send Code")}
|
||||
</Button>
|
||||
}
|
||||
onSearch={loadCaptcha}
|
||||
onSearch={() => setVisible(true)}
|
||||
/>
|
||||
<Modal
|
||||
closable={false}
|
||||
maskClosable={false}
|
||||
destroyOnClose={true}
|
||||
title={i18next.t("general:Captcha")}
|
||||
open={visible}
|
||||
okText={i18next.t("user:OK")}
|
||||
cancelText={i18next.t("user:Cancel")}
|
||||
<CaptchaModal
|
||||
owner={application.owner}
|
||||
name={application.name}
|
||||
visible={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
okButtonProps={{disabled: key.length !== 5 && buttonDisabled}}
|
||||
width={348}
|
||||
>
|
||||
{
|
||||
renderCheck()
|
||||
}
|
||||
</Modal>
|
||||
isCurrentProvider={false}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
|
||||
"Enable signup": "Anmeldung aktivieren",
|
||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Anmeldung fehlgeschlagen",
|
||||
"File uploaded successfully": "Datei erfolgreich hochgeladen",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Syncers",
|
||||
@ -311,7 +313,7 @@
|
||||
"No account?": "Kein Konto?",
|
||||
"Or sign in with another account": "Oder melden Sie sich mit einem anderen Konto an",
|
||||
"Password": "Passwort",
|
||||
"Password - Tooltip": "Passwort - Tooltip",
|
||||
"Password - Tooltip": "Password - Tooltip",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your code!": "Bitte gib deinen Code ein!",
|
||||
"Please input your password!": "Bitte geben Sie Ihr Passwort ein!",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "Domäne",
|
||||
"Domain - Tooltip": "Storage endpoint custom domain",
|
||||
"Edit Provider": "Anbieter bearbeiten",
|
||||
"Email Content": "Email content",
|
||||
"Email Content - Tooltip": "Unique string-style identifier",
|
||||
"Email Title": "E-Mail-Titel",
|
||||
"Email Title - Tooltip": "Unique string-style identifier",
|
||||
"Email content": "Email content",
|
||||
"Email content - Tooltip": "Unique string-style identifier",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "E-Mail-Titel",
|
||||
"Email title - Tooltip": "Unique string-style identifier",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "Region Endpunkt für Intranet",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "SMS sent successfully",
|
||||
"SP ACS URL": "SP-ACS-URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||
"SP Entity ID": "SP Entity ID",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "Schild Name",
|
||||
"Sign Name - Tooltip": "Unique string-style identifier",
|
||||
"Sign request": "Signaturanfrage",
|
||||
@ -649,7 +656,7 @@
|
||||
"The input is not valid Email!": "Die Eingabe ist ungültig!",
|
||||
"The input is not valid Phone!": "Die Eingabe ist nicht gültig!",
|
||||
"Username": "Benutzername",
|
||||
"Username - Tooltip": "Benutzername - Tooltip",
|
||||
"Username - Tooltip": "Username - Tooltip",
|
||||
"Your account has been created!": "Ihr Konto wurde erstellt!",
|
||||
"Your confirmed password is inconsistent with the password!": "Ihr bestätigtes Passwort stimmt nicht mit dem Passwort überein!",
|
||||
"sign in now": "jetzt anmelden"
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||
"Enable signup": "Enable signup",
|
||||
"Enable signup - Tooltip": "Enable signup - Tooltip",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Failed to sign in",
|
||||
"File uploaded successfully": "File uploaded successfully",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Syncers",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "Domain",
|
||||
"Domain - Tooltip": "Domain - Tooltip",
|
||||
"Edit Provider": "Edit Provider",
|
||||
"Email Content": "Email Content",
|
||||
"Email Content - Tooltip": "Email Content - Tooltip",
|
||||
"Email Title": "Email Title",
|
||||
"Email Title - Tooltip": "Email Title - Tooltip",
|
||||
"Email content": "Email content",
|
||||
"Email content - Tooltip": "Email content - Tooltip",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "Email title",
|
||||
"Email title - Tooltip": "Email title - Tooltip",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "Region endpoint for Intranet",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "SMS sent successfully",
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||
"SP Entity ID": "SP Entity ID",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "Sign Name",
|
||||
"Sign Name - Tooltip": "Sign Name - Tooltip",
|
||||
"Sign request": "Sign request",
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||
"Enable signup": "Habilitar nuevos registros",
|
||||
"Enable signup - Tooltip": "Habilitar nuevos registros - Tooltip",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Failed to sign in",
|
||||
"File uploaded successfully": "El archivo ha sido subido con éxito",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sincronizador",
|
||||
"Syncers": "Sincronizadores",
|
||||
@ -311,7 +313,7 @@
|
||||
"No account?": "¿No estás registrado?",
|
||||
"Or sign in with another account": "O inicia sesión con otra cuenta",
|
||||
"Password": "Contraseña",
|
||||
"Password - Tooltip": "Contraseña - Tooltip",
|
||||
"Password - Tooltip": "Password - Tooltip",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your code!": "¡Por favor ingrese su código!",
|
||||
"Please input your password!": "¡Por favor ingrese su contraseña!",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "Dominio",
|
||||
"Domain - Tooltip": "Dominio - Tooltip",
|
||||
"Edit Provider": "Editar Proveedor",
|
||||
"Email Content": "Contenido del Email",
|
||||
"Email Content - Tooltip": "Contenido del Email - Tooltip",
|
||||
"Email Title": "Titulo del Email",
|
||||
"Email Title - Tooltip": "Titulo del Email - Tooltip",
|
||||
"Email content": "Contenido del Email",
|
||||
"Email content - Tooltip": "Contenido del Email - Tooltip",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "Titulo del Email",
|
||||
"Email title - Tooltip": "Titulo del Email - Tooltip",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "Region endpoint for Intranet",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "SMS sent successfully",
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||
"SP Entity ID": "SP Entity ID",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
|
||||
"Send Test Email": "Enviar email de prueba",
|
||||
"Send Testing Email": "Enviar email de prueba",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "Sign Name",
|
||||
"Sign Name - Tooltip": "Sign Name - Tooltip",
|
||||
"Sign request": "Sign request",
|
||||
@ -649,7 +656,7 @@
|
||||
"The input is not valid Email!": "El valor ingresado no es un Email válido!",
|
||||
"The input is not valid Phone!": "El valor ingresado no es un Teléfono válido!",
|
||||
"Username": "Nombre de usuario",
|
||||
"Username - Tooltip": "Nombre de usuario - Tooltip",
|
||||
"Username - Tooltip": "Username - Tooltip",
|
||||
"Your account has been created!": "¡Tu cuenta ha sido creada!",
|
||||
"Your confirmed password is inconsistent with the password!": "¡La confirmación de su contraseña es inconsistente!",
|
||||
"sign in now": "iniciar sesión ahora"
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
|
||||
"Enable signup": "Activer l'inscription",
|
||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Failed to sign in",
|
||||
"File uploaded successfully": "Fichier téléchargé avec succès",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Synchronisateurs",
|
||||
@ -311,7 +313,7 @@
|
||||
"No account?": "Pas de compte ?",
|
||||
"Or sign in with another account": "Ou connectez-vous avec un autre compte",
|
||||
"Password": "Mot de passe",
|
||||
"Password - Tooltip": "Mot de passe - Info-bulle",
|
||||
"Password - Tooltip": "Password - Tooltip",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your code!": "Veuillez saisir votre code !",
|
||||
"Please input your password!": "Veuillez saisir votre mot de passe !",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "Domaine",
|
||||
"Domain - Tooltip": "Storage endpoint custom domain",
|
||||
"Edit Provider": "Modifier le fournisseur",
|
||||
"Email Content": "Email content",
|
||||
"Email Content - Tooltip": "Unique string-style identifier",
|
||||
"Email Title": "Titre de l'e-mail",
|
||||
"Email Title - Tooltip": "Unique string-style identifier",
|
||||
"Email content": "Email content",
|
||||
"Email content - Tooltip": "Unique string-style identifier",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "Titre de l'e-mail",
|
||||
"Email title - Tooltip": "Unique string-style identifier",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "Point de terminaison de la région pour Intranet",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "SMS sent successfully",
|
||||
"SP ACS URL": "URL du SP ACS",
|
||||
"SP ACS URL - Tooltip": "URL SP ACS - infobulle",
|
||||
"SP Entity ID": "ID de l'entité SP",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "SecretAccessKey - Infobulle",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "Nom du panneau",
|
||||
"Sign Name - Tooltip": "Unique string-style identifier",
|
||||
"Sign request": "Demande de signature",
|
||||
@ -649,7 +656,7 @@
|
||||
"The input is not valid Email!": "L'entrée n'est pas un email valide !",
|
||||
"The input is not valid Phone!": "L'entrée n'est pas un téléphone valide !",
|
||||
"Username": "Nom d'utilisateur",
|
||||
"Username - Tooltip": "Nom d'utilisateur - Info-bulle",
|
||||
"Username - Tooltip": "Username - Tooltip",
|
||||
"Your account has been created!": "Votre compte a été créé !",
|
||||
"Your confirmed password is inconsistent with the password!": "Votre mot de passe confirmé est incompatible avec le mot de passe !",
|
||||
"sign in now": "connectez-vous maintenant"
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||
"Enable signup": "サインアップを有効にする",
|
||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Failed to sign in",
|
||||
"File uploaded successfully": "ファイルが正常にアップロードされました",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Syncers",
|
||||
@ -311,7 +313,7 @@
|
||||
"No account?": "アカウントがありませんか?",
|
||||
"Or sign in with another account": "または別のアカウントでサインイン",
|
||||
"Password": "パスワード",
|
||||
"Password - Tooltip": "パスワード → ツールチップ",
|
||||
"Password - Tooltip": "Password - Tooltip",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your code!": "コードを入力してください!",
|
||||
"Please input your password!": "パスワードを入力してください!",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "ドメイン",
|
||||
"Domain - Tooltip": "Storage endpoint custom domain",
|
||||
"Edit Provider": "プロバイダーを編集",
|
||||
"Email Content": "Email content",
|
||||
"Email Content - Tooltip": "Unique string-style identifier",
|
||||
"Email Title": "メールタイトル",
|
||||
"Email Title - Tooltip": "Unique string-style identifier",
|
||||
"Email content": "Email content",
|
||||
"Email content - Tooltip": "Unique string-style identifier",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "メールタイトル",
|
||||
"Email title - Tooltip": "Unique string-style identifier",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "イントラネットのリージョンエンドポイント",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "短信发送成功",
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - ツールチップ",
|
||||
"SP Entity ID": "SP ID",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "シークレットアクセスキー - ツールチップ",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "署名名",
|
||||
"Sign Name - Tooltip": "Unique string-style identifier",
|
||||
"Sign request": "サインリクエスト",
|
||||
@ -649,7 +656,7 @@
|
||||
"The input is not valid Email!": "入力されたメールアドレスが無効です!",
|
||||
"The input is not valid Phone!": "入力された電話番号が正しくありません!",
|
||||
"Username": "ユーザー名",
|
||||
"Username - Tooltip": "ユーザー名 - ツールチップ",
|
||||
"Username - Tooltip": "Username - Tooltip",
|
||||
"Your account has been created!": "あなたのアカウントが作成されました!",
|
||||
"Your confirmed password is inconsistent with the password!": "確認されたパスワードがパスワードと一致していません!",
|
||||
"sign in now": "今すぐサインイン"
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||
"Enable signup": "Enable signup",
|
||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Failed to sign in",
|
||||
"File uploaded successfully": "File uploaded successfully",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Syncers",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "Domain",
|
||||
"Domain - Tooltip": "Storage endpoint custom domain",
|
||||
"Edit Provider": "Edit Provider",
|
||||
"Email Content": "Email content",
|
||||
"Email Content - Tooltip": "Unique string-style identifier",
|
||||
"Email Title": "Email title",
|
||||
"Email Title - Tooltip": "Unique string-style identifier",
|
||||
"Email content": "Email content",
|
||||
"Email content - Tooltip": "Unique string-style identifier",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "Email title",
|
||||
"Email title - Tooltip": "Unique string-style identifier",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "Region endpoint for Intranet",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "短信发送成功",
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||
"SP Entity ID": "SP Entity ID",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "Sign Name",
|
||||
"Sign Name - Tooltip": "Unique string-style identifier",
|
||||
"Sign request": "Sign request",
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
|
||||
"Enable signup": "Включить регистрацию",
|
||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Failed to sign in",
|
||||
"File uploaded successfully": "Файл успешно загружен",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Синхронизаторы",
|
||||
@ -311,7 +313,7 @@
|
||||
"No account?": "Нет учетной записи?",
|
||||
"Or sign in with another account": "Или войти с помощью другой учетной записи",
|
||||
"Password": "Пароль",
|
||||
"Password - Tooltip": "Пароль - Подсказка",
|
||||
"Password - Tooltip": "Password - Tooltip",
|
||||
"Please input your Email or Phone!": "Please input your Email or Phone!",
|
||||
"Please input your code!": "Пожалуйста, введите ваш код!",
|
||||
"Please input your password!": "Пожалуйста, введите ваш пароль!",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "Домен",
|
||||
"Domain - Tooltip": "Storage endpoint custom domain",
|
||||
"Edit Provider": "Изменить провайдера",
|
||||
"Email Content": "Email content",
|
||||
"Email Content - Tooltip": "Unique string-style identifier",
|
||||
"Email Title": "Заголовок письма",
|
||||
"Email Title - Tooltip": "Unique string-style identifier",
|
||||
"Email content": "Email content",
|
||||
"Email content - Tooltip": "Unique string-style identifier",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "Заголовок письма",
|
||||
"Email title - Tooltip": "Unique string-style identifier",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "Конечная точка региона Интранета",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "短信发送成功",
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - Подсказка",
|
||||
"SP Entity ID": "Идентификатор сущности SP",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "SecretAccessKey - Подсказка",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "Имя подписи",
|
||||
"Sign Name - Tooltip": "Unique string-style identifier",
|
||||
"Sign request": "Запрос на подпись",
|
||||
@ -649,7 +656,7 @@
|
||||
"The input is not valid Email!": "Ввод не является допустимым Email!",
|
||||
"The input is not valid Phone!": "Введен неверный телефон!",
|
||||
"Username": "Имя пользователя",
|
||||
"Username - Tooltip": "Имя пользователя - Подсказка",
|
||||
"Username - Tooltip": "Username - Tooltip",
|
||||
"Your account has been created!": "Ваша учетная запись была создана!",
|
||||
"Your confirmed password is inconsistent with the password!": "Подтвержденный пароль не соответствует паролю!",
|
||||
"sign in now": "войти сейчас"
|
||||
|
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||
"Enable signup": "Enable signup",
|
||||
"Enable signup - Tooltip": "Enable signup - Tooltip",
|
||||
"Failed to log in": "Failed to log in",
|
||||
"Failed to sign in": "Failed to sign in",
|
||||
"File uploaded successfully": "File uploaded successfully",
|
||||
"Follow organization theme": "Follow organization theme",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "Successfully added",
|
||||
"Successfully deleted": "Successfully deleted",
|
||||
"Successfully saved": "Successfully saved",
|
||||
"Supported country code": "Supported country code",
|
||||
"Supported country code - Tooltip": "Supported country code - Tooltip",
|
||||
"Supported country codes": "Supported country codes",
|
||||
"Supported country codes - Tooltip": "Supported country codes - Tooltip",
|
||||
"Sure to delete": "Sure to delete",
|
||||
"Swagger": "Swagger",
|
||||
"Sync": "Sync",
|
||||
"Syncers": "Syncers",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "Domain",
|
||||
"Domain - Tooltip": "Domain - Tooltip",
|
||||
"Edit Provider": "Edit Provider",
|
||||
"Email Content": "Email Content",
|
||||
"Email Content - Tooltip": "Email Content - Tooltip",
|
||||
"Email Title": "Email Title",
|
||||
"Email Title - Tooltip": "Email Title - Tooltip",
|
||||
"Email content": "Email content",
|
||||
"Email content - Tooltip": "Email content - Tooltip",
|
||||
"Email sent successfully": "Email sent successfully",
|
||||
"Email title": "Email title",
|
||||
"Email title - Tooltip": "Email title - Tooltip",
|
||||
"Enable QR code": "Enable QR code",
|
||||
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||
"Endpoint": "Endpoint",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "Region endpoint for Intranet",
|
||||
"Required": "Required",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "SMS Test",
|
||||
"SMS Test - Tooltip": "SMS Test - Tooltip",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "短信发送成功",
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||
"SP Entity ID": "SP Entity ID",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "Secret key - Tooltip",
|
||||
"SecretAccessKey - Tooltip": "SecretAccessKey - Tooltip",
|
||||
"Send Test Email": "Send Test Email",
|
||||
"Send Testing Email": "Send Testing Email",
|
||||
"Send Testing SMS": "Send Testing SMS",
|
||||
"Sign Name": "Sign Name",
|
||||
"Sign Name - Tooltip": "Sign Name - Tooltip",
|
||||
"Sign request": "Sign request",
|
||||
|
@ -27,7 +27,7 @@
|
||||
"Copy signup page URL": "复制注册页面URL",
|
||||
"Edit Application": "编辑应用",
|
||||
"Enable SAML compress": "压缩SAML响应",
|
||||
"Enable SAML compress - Tooltip": "Casdoor作为SAML idp时,是否压缩SAML响应信息",
|
||||
"Enable SAML compress - Tooltip": "Casdoor作为SAML IdP时,是否压缩SAML响应信息",
|
||||
"Enable WebAuthn signin": "启用WebAuthn登录",
|
||||
"Enable WebAuthn signin - Tooltip": "是否支持用户在登录页面通过WebAuthn方式登录",
|
||||
"Enable code signin": "启用验证码登录",
|
||||
@ -38,6 +38,7 @@
|
||||
"Enable signin session - Tooltip": "从应用登录Casdoor后,Casdoor是否保持会话",
|
||||
"Enable signup": "启用注册",
|
||||
"Enable signup - Tooltip": "是否允许用户注册",
|
||||
"Failed to log in": "登录失败",
|
||||
"Failed to sign in": "登录失败",
|
||||
"File uploaded successfully": "文件上传成功",
|
||||
"Follow organization theme": "使用组织主题",
|
||||
@ -125,7 +126,7 @@
|
||||
},
|
||||
"forget": {
|
||||
"Account": "账号",
|
||||
"Change Password": "编辑密码",
|
||||
"Change Password": "修改密码",
|
||||
"Choose email or phone": "请选择邮箱或手机号验证",
|
||||
"Confirm": "验证密码",
|
||||
"Next Step": "下一步",
|
||||
@ -251,8 +252,9 @@
|
||||
"Successfully added": "添加成功",
|
||||
"Successfully deleted": "删除成功",
|
||||
"Successfully saved": "保存成功",
|
||||
"Supported country code": "支持的国家代码",
|
||||
"Supported country code - Tooltip": "支持发送短信的国家 - Tooltip",
|
||||
"Supported country codes": "支持的国家代码",
|
||||
"Supported country codes - Tooltip": "支持发送短信的国家 - Tooltip",
|
||||
"Sure to delete": "确定删除",
|
||||
"Swagger": "API文档",
|
||||
"Sync": "同步",
|
||||
"Syncers": "同步器",
|
||||
@ -514,10 +516,11 @@
|
||||
"Domain": "域名",
|
||||
"Domain - Tooltip": "存储节点自定义域名",
|
||||
"Edit Provider": "编辑提供商",
|
||||
"Email Content": "邮件内容",
|
||||
"Email Content - Tooltip": "邮件内容",
|
||||
"Email Title": "邮件标题",
|
||||
"Email Title - Tooltip": "邮件标题",
|
||||
"Email content": "邮件内容",
|
||||
"Email content - Tooltip": "邮件内容",
|
||||
"Email sent successfully": "邮件发送成功",
|
||||
"Email title": "邮件标题",
|
||||
"Email title - Tooltip": "邮件标题",
|
||||
"Enable QR code": "扫码登陆",
|
||||
"Enable QR code - Tooltip": "扫码登陆 - 工具提示",
|
||||
"Endpoint": "地域节点 (外网)",
|
||||
@ -550,8 +553,11 @@
|
||||
"Region endpoint for Intranet": "地域节点 (内网)",
|
||||
"Required": "是否必填项",
|
||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||
"SMS Test": "测试短信配置",
|
||||
"SMS Test - Tooltip": "请输入测试手机号",
|
||||
"SMS account": "SMS account",
|
||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||
"SMS sent successfully": "短信发送成功",
|
||||
"SP ACS URL": "SP ACS URL",
|
||||
"SP ACS URL - Tooltip": "SP ACS URL - 工具提示",
|
||||
"SP Entity ID": "SP 实体 ID",
|
||||
@ -563,7 +569,8 @@
|
||||
"Secret key": "Secret key",
|
||||
"Secret key - Tooltip": "用于服务端调用验证码提供商API进行验证",
|
||||
"SecretAccessKey - Tooltip": "访问密钥-工具提示",
|
||||
"Send Test Email": "发送测试邮件",
|
||||
"Send Testing Email": "发送测试邮件",
|
||||
"Send Testing SMS": "发送测试短信",
|
||||
"Sign Name": "签名名称",
|
||||
"Sign Name - Tooltip": "签名名称",
|
||||
"Sign request": "签名请求",
|
||||
@ -649,7 +656,7 @@
|
||||
"The input is not valid Email!": "您输入的电子邮箱格式有误!",
|
||||
"The input is not valid Phone!": "您输入的手机号格式有误!",
|
||||
"Username": "用户名",
|
||||
"Username - Tooltip": "允许字符包括字母、数字、下划线,不得以数字开头",
|
||||
"Username - Tooltip": "唯一的用户名",
|
||||
"Your account has been created!": "您的账号已创建!",
|
||||
"Your confirmed password is inconsistent with the password!": "您两次输入的密码不一致!",
|
||||
"sign in now": "立即登录"
|
||||
|
Reference in New Issue
Block a user