mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-09 09:23:40 +08:00
Compare commits
45 Commits
Author | SHA1 | Date | |
---|---|---|---|
457e6208ad | |||
d10b1347a8 | |||
f5b7f8cb45 | |||
5d9b17542f | |||
0021226a60 | |||
79fc0516dd | |||
a73be11990 | |||
eddd8acbf4 | |||
d0741e3705 | |||
c66561dc9a | |||
fcdf1e8dd2 | |||
6d4f94986e | |||
9ca686b240 | |||
c93bc0dda2 | |||
7d25b9cdd8 | |||
ead844131e | |||
ce2a4bbf6e | |||
fcb80b800f | |||
6daadf8d3c | |||
090389b86a | |||
b566af8e11 | |||
57028c2059 | |||
a6e9084973 | |||
6fb3e2cd7f | |||
8b6bde6d82 | |||
fb2b03f00f | |||
1681138729 | |||
1d8b0a264e | |||
b525210835 | |||
4ab2ca7a25 | |||
dcf148fb7f | |||
c8846f1a2d | |||
0559298d6c | |||
ddb5e26fcd | |||
1f39027b78 | |||
eae3b0d367 | |||
186f0ac97b | |||
308f305c53 | |||
d498bc60ce | |||
7bbe1e38c1 | |||
f465fc6ce0 | |||
c952c2f2f4 | |||
86ae97d1e5 | |||
6ea73e3eca | |||
a71a190db5 |
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -1,2 +1,5 @@
|
|||||||
*.go linguist-detectable=true
|
*.go linguist-detectable=true
|
||||||
*.js linguist-detectable=false
|
*.js linguist-detectable=false
|
||||||
|
# Declare files that will always have LF line endings on checkout.
|
||||||
|
# Git will always convert line endings to LF on checkout. You should use this for files that must keep LF endings, even on Windows.
|
||||||
|
*.sh text eol=lf
|
50
.github/workflows/build.yml
vendored
50
.github/workflows/build.yml
vendored
@ -76,11 +76,59 @@ jobs:
|
|||||||
version: latest
|
version: latest
|
||||||
args: --disable-all -c dummy.yml -E=gofumpt --max-same-issues=0 --timeout 5m --modules-download-mode=mod
|
args: --disable-all -c dummy.yml -E=gofumpt --max-same-issues=0 --timeout 5m --modules-download-mode=mod
|
||||||
|
|
||||||
|
e2e:
|
||||||
|
name: e2e-test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [ frontend, backend, linter ]
|
||||||
|
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: front install
|
||||||
|
run: yarn install
|
||||||
|
working-directory: ./web
|
||||||
|
- name: front start
|
||||||
|
run: nohup yarn start &
|
||||||
|
working-directory: ./web
|
||||||
|
- name: back start
|
||||||
|
run: nohup go run ./main.go &
|
||||||
|
working-directory: ./
|
||||||
|
- name: Sleep for starting
|
||||||
|
run: sleep 90s
|
||||||
|
shell: bash
|
||||||
|
- name: e2e
|
||||||
|
run: npx cypress run --spec "**/e2e/**.cy.js"
|
||||||
|
working-directory: ./web
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: cypress-screenshots
|
||||||
|
path: ./web/cypress/screenshots
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: cypress-videos
|
||||||
|
path: ./web/cypress/videos
|
||||||
|
|
||||||
release-and-push:
|
release-and-push:
|
||||||
name: Release And Push
|
name: Release And Push
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push'
|
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push'
|
||||||
needs: [ frontend, backend, linter ]
|
needs: [ frontend, backend, linter, e2e ]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
@ -17,6 +17,7 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -238,20 +239,67 @@ func (c *ApiController) Signup() {
|
|||||||
// @Title Logout
|
// @Title Logout
|
||||||
// @Tag Login API
|
// @Tag Login API
|
||||||
// @Description logout the current user
|
// @Description logout the current user
|
||||||
|
// @Param id_token_hint query string false "id_token_hint"
|
||||||
|
// @Param post_logout_redirect_uri query string false "post_logout_redirect_uri"
|
||||||
|
// @Param state query string false "state"
|
||||||
// @Success 200 {object} controllers.Response The Response object
|
// @Success 200 {object} controllers.Response The Response object
|
||||||
// @router /logout [get,post]
|
// @router /logout [get,post]
|
||||||
func (c *ApiController) Logout() {
|
func (c *ApiController) Logout() {
|
||||||
user := c.GetSessionUsername()
|
user := c.GetSessionUsername()
|
||||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
|
||||||
|
|
||||||
application := c.GetSessionApplication()
|
// https://openid.net/specs/openid-connect-rpinitiated-1_0-final.html
|
||||||
c.ClearUserSession()
|
accessToken := c.Input().Get("id_token_hint")
|
||||||
|
redirectUri := c.Input().Get("post_logout_redirect_uri")
|
||||||
|
state := c.Input().Get("state")
|
||||||
|
|
||||||
if application == nil || application.Name == "app-built-in" || application.HomepageUrl == "" {
|
if accessToken == "" && redirectUri == "" {
|
||||||
c.ResponseOk(user)
|
c.ClearUserSession()
|
||||||
|
object.DeleteSessionId(user, c.Ctx.Input.CruSession.SessionID())
|
||||||
|
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||||
|
|
||||||
|
application := c.GetSessionApplication()
|
||||||
|
if application == nil || application.Name == "app-built-in" || application.HomepageUrl == "" {
|
||||||
|
c.ResponseOk(user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.ResponseOk(user, application.HomepageUrl)
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
if redirectUri == "" {
|
||||||
|
c.ResponseError(c.T("general:Missing parameter") + ": post_logout_redirect_uri")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if accessToken == "" {
|
||||||
|
c.ResponseError(c.T("general:Missing parameter") + ": id_token_hint")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
affected, application, token := object.ExpireTokenByAccessToken(accessToken)
|
||||||
|
if !affected {
|
||||||
|
c.ResponseError(c.T("token:Token not found, invalid accessToken"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if application == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist")), token.Application)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if application.IsRedirectUriValid(redirectUri) {
|
||||||
|
if user == "" {
|
||||||
|
user = util.GetId(token.Organization, token.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ClearUserSession()
|
||||||
|
object.DeleteSessionId(user, 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))
|
||||||
|
} else {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("token:Redirect URI: %s doesn't exist in the allowed Redirect URI list"), redirectUri))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.ResponseOk(user, application.HomepageUrl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccount
|
// GetAccount
|
||||||
@ -271,12 +319,17 @@ func (c *ApiController) GetAccount() {
|
|||||||
user = object.ExtendManagedAccountsWithUser(user)
|
user = object.ExtendManagedAccountsWithUser(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object.ExtendUserWithRolesAndPermissions(user)
|
||||||
|
|
||||||
|
user.Permissions = object.GetMaskedPermissions(user.Permissions)
|
||||||
|
user.Roles = object.GetMaskedRoles(user.Roles)
|
||||||
|
|
||||||
organization := object.GetMaskedOrganization(object.GetOrganizationByUser(user))
|
organization := object.GetMaskedOrganization(object.GetOrganizationByUser(user))
|
||||||
resp := Response{
|
resp := Response{
|
||||||
Status: "ok",
|
Status: "ok",
|
||||||
Sub: user.Id,
|
Sub: user.Id,
|
||||||
Name: user.Name,
|
Name: user.Name,
|
||||||
Data: user,
|
Data: object.GetMaskedUser(user),
|
||||||
Data2: organization,
|
Data2: organization,
|
||||||
}
|
}
|
||||||
c.Data["json"] = resp
|
c.Data["json"] = resp
|
||||||
|
@ -86,7 +86,7 @@ func (c *ApiController) GetUserApplication() {
|
|||||||
id := c.Input().Get("id")
|
id := c.Input().Get("id")
|
||||||
user := object.GetUser(id)
|
user := object.GetUser(id)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("application:The user: %s doesn't exist"), id))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ func (c *ApiController) GetOrganizationApplications() {
|
|||||||
sortOrder := c.Input().Get("sortOrder")
|
sortOrder := c.Input().Get("sortOrder")
|
||||||
|
|
||||||
if organization == "" {
|
if organization == "" {
|
||||||
c.ResponseError(c.T("application:Parameter organization is missing"))
|
c.ResponseError(c.T("general:Missing parameter") + ": organization")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func tokenToResponse(token *object.Token) *Response {
|
|||||||
if token.AccessToken == "" {
|
if token.AccessToken == "" {
|
||||||
return &Response{Status: "error", Msg: "fail to get accessToken", Data: token.AccessToken}
|
return &Response{Status: "error", Msg: "fail to get accessToken", Data: token.AccessToken}
|
||||||
}
|
}
|
||||||
return &Response{Status: "ok", Msg: "", Data: token.AccessToken}
|
return &Response{Status: "ok", Msg: "", Data: token.AccessToken, Data2: token.RefreshToken}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleLoggedIn ...
|
// HandleLoggedIn ...
|
||||||
@ -103,12 +103,12 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
resp = tokenToResponse(token)
|
resp = tokenToResponse(token)
|
||||||
}
|
}
|
||||||
} else if form.Type == ResponseTypeSaml { // saml flow
|
} else if form.Type == ResponseTypeSaml { // saml flow
|
||||||
res, redirectUrl, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host)
|
res, redirectUrl, method, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error(), nil)
|
c.ResponseError(err.Error(), nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: redirectUrl}
|
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: map[string]string{"redirectUrl": redirectUrl, "method": method}}
|
||||||
} else if form.Type == ResponseTypeCas {
|
} else if form.Type == ResponseTypeCas {
|
||||||
// not oauth but CAS SSO protocol
|
// not oauth but CAS SSO protocol
|
||||||
service := c.Input().Get("service")
|
service := c.Input().Get("service")
|
||||||
@ -139,6 +139,10 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resp.Status == "ok" {
|
||||||
|
object.SetSession(user.GetId(), c.Ctx.Input.CruSession.SessionID())
|
||||||
|
}
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +209,7 @@ func (c *ApiController) Login() {
|
|||||||
if form.Username != "" {
|
if form.Username != "" {
|
||||||
if form.Type == ResponseTypeLogin {
|
if form.Type == ResponseTypeLogin {
|
||||||
if c.GetSessionUsername() != "" {
|
if c.GetSessionUsername() != "" {
|
||||||
c.ResponseError(c.T("auth:Please sign out first before signing in"), c.GetSessionUsername())
|
c.ResponseError(c.T("account:Please sign out first before signing in"), c.GetSessionUsername())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,12 +226,13 @@ func (c *ApiController) Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check result through Email or Phone
|
// check result through Email or Phone
|
||||||
|
var checkDest string
|
||||||
if strings.Contains(form.Username, "@") {
|
if strings.Contains(form.Username, "@") {
|
||||||
verificationCodeType = "email"
|
verificationCodeType = "email"
|
||||||
if user != nil && util.GetMaskedEmail(user.Email) == form.Username {
|
if user != nil && util.GetMaskedEmail(user.Email) == form.Username {
|
||||||
form.Username = user.Email
|
form.Username = user.Email
|
||||||
}
|
}
|
||||||
checkResult = object.CheckVerificationCode(form.Username, form.Code, c.GetAcceptLanguage())
|
checkDest = form.Username
|
||||||
} else {
|
} else {
|
||||||
verificationCodeType = "phone"
|
verificationCodeType = "phone"
|
||||||
if len(form.PhonePrefix) == 0 {
|
if len(form.PhonePrefix) == 0 {
|
||||||
@ -238,11 +243,16 @@ func (c *ApiController) Login() {
|
|||||||
if user != nil && util.GetMaskedPhone(user.Phone) == form.Username {
|
if user != nil && util.GetMaskedPhone(user.Phone) == form.Username {
|
||||||
form.Username = user.Phone
|
form.Username = user.Phone
|
||||||
}
|
}
|
||||||
checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)
|
checkDest = fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)
|
||||||
checkResult = object.CheckVerificationCode(checkPhone, form.Code, c.GetAcceptLanguage())
|
|
||||||
}
|
}
|
||||||
|
user = object.GetUserByFields(form.Organization, form.Username)
|
||||||
|
if user == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
checkResult = object.CheckSigninCode(user, checkDest, form.Code, c.GetAcceptLanguage())
|
||||||
if len(checkResult) != 0 {
|
if len(checkResult) != 0 {
|
||||||
responseText := fmt.Sprintf("%s%s", verificationCodeType, checkResult)
|
responseText := fmt.Sprintf("%s - %s", verificationCodeType, checkResult)
|
||||||
c.ResponseError(responseText)
|
c.ResponseError(responseText)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -253,18 +263,16 @@ func (c *ApiController) Login() {
|
|||||||
} else {
|
} else {
|
||||||
object.DisableVerificationCode(fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username))
|
object.DisableVerificationCode(fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username))
|
||||||
}
|
}
|
||||||
|
|
||||||
user = object.GetUserByFields(form.Organization, form.Username)
|
|
||||||
if user == nil {
|
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:The user: %s/%s doesn't exist"), form.Organization, form.Username))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !application.EnablePassword {
|
||||||
|
c.ResponseError(c.T("auth:The login method: login with password is not enabled for the application"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if object.CheckToEnableCaptcha(application) {
|
if object.CheckToEnableCaptcha(application) {
|
||||||
isHuman, err := captcha.VerifyCaptchaByCaptchaType(form.CaptchaType, form.CaptchaToken, form.ClientSecret)
|
isHuman, err := captcha.VerifyCaptchaByCaptchaType(form.CaptchaType, form.CaptchaToken, form.ClientSecret)
|
||||||
@ -397,54 +405,61 @@ func (c *ApiController) Login() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle username conflicts
|
if application.EnableLinkWithEmail {
|
||||||
tmpUser := object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Username))
|
// find user that has the same email
|
||||||
if tmpUser != nil {
|
user = object.GetUserByField(application.Organization, "email", userInfo.Email)
|
||||||
uid, err := uuid.NewRandom()
|
}
|
||||||
|
|
||||||
|
if user == nil || user.IsDeleted {
|
||||||
|
// Handle username conflicts
|
||||||
|
tmpUser := object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Username))
|
||||||
|
if tmpUser != nil {
|
||||||
|
uid, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uidStr := strings.Split(uid.String(), "-")
|
||||||
|
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
properties := map[string]string{}
|
||||||
|
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
||||||
|
initScore, err := getInitScore(organization)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(fmt.Errorf(c.T("account:Get init score failed, error: %w"), err).Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
uidStr := strings.Split(uid.String(), "-")
|
user = &object.User{
|
||||||
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
|
Owner: application.Organization,
|
||||||
|
Name: userInfo.Username,
|
||||||
|
CreatedTime: util.GetCurrentTime(),
|
||||||
|
Id: util.GenerateId(),
|
||||||
|
Type: "normal-user",
|
||||||
|
DisplayName: userInfo.DisplayName,
|
||||||
|
Avatar: userInfo.AvatarUrl,
|
||||||
|
Address: []string{},
|
||||||
|
Email: userInfo.Email,
|
||||||
|
Score: initScore,
|
||||||
|
IsAdmin: false,
|
||||||
|
IsGlobalAdmin: false,
|
||||||
|
IsForbidden: false,
|
||||||
|
IsDeleted: false,
|
||||||
|
SignupApplication: application.Name,
|
||||||
|
Properties: properties,
|
||||||
|
}
|
||||||
|
|
||||||
|
affected := object.AddUser(user)
|
||||||
|
if !affected {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to create user, user information is invalid: %s"), util.StructToJson(user)))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
properties := map[string]string{}
|
|
||||||
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
|
||||||
initScore, err := getInitScore(organization)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(fmt.Errorf(c.T("auth:Get init score failed, error: %w"), err).Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
user = &object.User{
|
|
||||||
Owner: application.Organization,
|
|
||||||
Name: userInfo.Username,
|
|
||||||
CreatedTime: util.GetCurrentTime(),
|
|
||||||
Id: util.GenerateId(),
|
|
||||||
Type: "normal-user",
|
|
||||||
DisplayName: userInfo.DisplayName,
|
|
||||||
Avatar: userInfo.AvatarUrl,
|
|
||||||
Address: []string{},
|
|
||||||
Email: userInfo.Email,
|
|
||||||
Score: initScore,
|
|
||||||
IsAdmin: false,
|
|
||||||
IsGlobalAdmin: false,
|
|
||||||
IsForbidden: false,
|
|
||||||
IsDeleted: false,
|
|
||||||
SignupApplication: application.Name,
|
|
||||||
Properties: properties,
|
|
||||||
}
|
|
||||||
// sync info from 3rd-party if possible
|
// sync info from 3rd-party if possible
|
||||||
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
|
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
|
||||||
|
|
||||||
affected := object.AddUser(user)
|
|
||||||
if !affected {
|
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to create user, user information is invalid: %s"), util.StructToJson(user)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
object.LinkUserAccount(user, provider.Type, userInfo.Id)
|
object.LinkUserAccount(user, provider.Type, userInfo.Id)
|
||||||
|
|
||||||
resp = c.HandleLoggedIn(application, user, &form)
|
resp = c.HandleLoggedIn(application, user, &form)
|
||||||
@ -460,13 +475,13 @@ func (c *ApiController) Login() {
|
|||||||
record2.User = user.Name
|
record2.User = user.Name
|
||||||
util.SafeGoroutine(func() { object.AddRecord(record2) })
|
util.SafeGoroutine(func() { object.AddRecord(record2) })
|
||||||
} else if provider.Category == "SAML" {
|
} else if provider.Category == "SAML" {
|
||||||
resp = &Response{Status: "error", Msg: "The account does not exist"}
|
resp = &Response{Status: "error", Msg: fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id))}
|
||||||
}
|
}
|
||||||
// resp = &Response{Status: "ok", Msg: "", Data: res}
|
// resp = &Response{Status: "ok", Msg: "", Data: res}
|
||||||
} else { // form.Method != "signup"
|
} else { // form.Method != "signup"
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError(c.T("auth:The account does not exist"), userInfo)
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id)), userInfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ func (c *ApiController) BatchEnforce() {
|
|||||||
func (c *ApiController) GetAllObjects() {
|
func (c *ApiController) GetAllObjects() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError(c.T("enforcer:Please sign in first"))
|
c.ResponseError(c.T("general:Please login first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ func (c *ApiController) GetAllObjects() {
|
|||||||
func (c *ApiController) GetAllActions() {
|
func (c *ApiController) GetAllActions() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError(c.T("enforcer:Please sign in first"))
|
c.ResponseError(c.T("general:Please login first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ func (c *ApiController) GetAllActions() {
|
|||||||
func (c *ApiController) GetAllRoles() {
|
func (c *ApiController) GetAllRoles() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError(c.T("enforcer:Please sign in first"))
|
c.ResponseError(c.T("general:Please login first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func (c *ApiController) GetLdapUser() {
|
|||||||
ldapServer := LdapServer{}
|
ldapServer := LdapServer{}
|
||||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldapServer)
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldapServer)
|
||||||
if err != nil || util.IsStrsEmpty(ldapServer.Host, ldapServer.Admin, ldapServer.Passwd, ldapServer.BaseDn) {
|
if err != nil || util.IsStrsEmpty(ldapServer.Host, ldapServer.Admin, ldapServer.Passwd, ldapServer.BaseDn) {
|
||||||
c.ResponseError(c.T("ldap:Missing parameter"))
|
c.ResponseError(c.T("general:Missing parameter"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ func (c *ApiController) GetLdap() {
|
|||||||
id := c.Input().Get("id")
|
id := c.Input().Get("id")
|
||||||
|
|
||||||
if util.IsStrsEmpty(id) {
|
if util.IsStrsEmpty(id) {
|
||||||
c.ResponseError(c.T("ldap:Missing parameter"))
|
c.ResponseError(c.T("general:Missing parameter"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,12 +136,12 @@ func (c *ApiController) AddLdap() {
|
|||||||
var ldap object.Ldap
|
var ldap object.Ldap
|
||||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldap)
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(c.T("ldap:Missing parameter"))
|
c.ResponseError(c.T("general:Missing parameter"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if util.IsStrsEmpty(ldap.Owner, ldap.ServerName, ldap.Host, ldap.Admin, ldap.Passwd, ldap.BaseDn) {
|
if util.IsStrsEmpty(ldap.Owner, ldap.ServerName, ldap.Host, ldap.Admin, ldap.Passwd, ldap.BaseDn) {
|
||||||
c.ResponseError(c.T("ldap:Missing parameter"))
|
c.ResponseError(c.T("general:Missing parameter"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ func (c *ApiController) UpdateLdap() {
|
|||||||
var ldap object.Ldap
|
var ldap object.Ldap
|
||||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldap)
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldap)
|
||||||
if err != nil || util.IsStrsEmpty(ldap.Owner, ldap.ServerName, ldap.Host, ldap.Admin, ldap.Passwd, ldap.BaseDn) {
|
if err != nil || util.IsStrsEmpty(ldap.Owner, ldap.ServerName, ldap.Host, ldap.Admin, ldap.Passwd, ldap.BaseDn) {
|
||||||
c.ResponseError(c.T("ldap:Missing parameter"))
|
c.ResponseError(c.T("general:Missing parameter"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,13 +141,13 @@ func (c *ApiController) BuyProduct() {
|
|||||||
|
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError(c.T("product:Please login first"))
|
c.ResponseError(c.T("general:Please login first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user := object.GetUser(userId)
|
user := object.GetUser(userId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("product:The user: %s doesn't exist"), userId))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), userId))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
68
controllers/session.go
Normal file
68
controllers/session.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// 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 controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/beego/beego/utils/pagination"
|
||||||
|
"github.com/casdoor/casdoor/object"
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeleteSession
|
||||||
|
// @Title DeleteSession
|
||||||
|
// @Tag Session API
|
||||||
|
// @Description Delete session by userId
|
||||||
|
// @Param ID query string true "The ID(owner/name) of user."
|
||||||
|
// @Success 200 {array} string The Response object
|
||||||
|
// @router /delete-session [post]
|
||||||
|
func (c *ApiController) DeleteSession() {
|
||||||
|
var session object.Session
|
||||||
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &session)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["json"] = wrapActionResponse(object.DeleteSession(util.GetId(session.Owner, session.Name)))
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSessions
|
||||||
|
// @Title GetSessions
|
||||||
|
// @Tag Session API
|
||||||
|
// @Description Get organization user sessions
|
||||||
|
// @Param owner query string true "The organization name"
|
||||||
|
// @Success 200 {array} string The Response object
|
||||||
|
// @router /get-sessions [get]
|
||||||
|
func (c *ApiController) GetSessions() {
|
||||||
|
limit := c.Input().Get("pageSize")
|
||||||
|
page := c.Input().Get("p")
|
||||||
|
field := c.Input().Get("field")
|
||||||
|
value := c.Input().Get("value")
|
||||||
|
sortField := c.Input().Get("sortField")
|
||||||
|
sortOrder := c.Input().Get("sortOrder")
|
||||||
|
owner := c.Input().Get("owner")
|
||||||
|
if limit == "" || page == "" {
|
||||||
|
c.Data["json"] = object.GetSessions(owner)
|
||||||
|
c.ServeJSON()
|
||||||
|
} else {
|
||||||
|
limit := util.ParseInt(limit)
|
||||||
|
paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetSessionCount(owner, field, value)))
|
||||||
|
sessions := object.GetPaginationSessions(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||||
|
c.ResponseOk(sessions, paginator.Nums())
|
||||||
|
}
|
||||||
|
}
|
@ -40,7 +40,7 @@ func (c *ApiController) GetSystemInfo() {
|
|||||||
|
|
||||||
user := object.GetUser(id)
|
user := object.GetUser(id)
|
||||||
if user == nil || !user.IsGlobalAdmin {
|
if user == nil || !user.IsGlobalAdmin {
|
||||||
c.ResponseError(c.T("system_info:You are not authorized to access this resource"))
|
c.ResponseError(c.T("auth:Unauthorized operation"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ package controllers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/beego/beego/utils/pagination"
|
"github.com/beego/beego/utils/pagination"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
@ -150,7 +149,7 @@ func (c *ApiController) GetOAuthCode() {
|
|||||||
codeChallenge := c.Input().Get("code_challenge")
|
codeChallenge := c.Input().Get("code_challenge")
|
||||||
|
|
||||||
if challengeMethod != "S256" && challengeMethod != "null" && challengeMethod != "" {
|
if challengeMethod != "S256" && challengeMethod != "null" && challengeMethod != "" {
|
||||||
c.ResponseError(c.T("token:Challenge method should be S256"))
|
c.ResponseError(c.T("auth:Challenge method should be S256"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
host := c.Ctx.Request.Host
|
host := c.Ctx.Request.Host
|
||||||
@ -247,28 +246,6 @@ func (c *ApiController) RefreshToken() {
|
|||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenLogout
|
|
||||||
// @Title TokenLogout
|
|
||||||
// @Tag Token API
|
|
||||||
// @Description delete token by AccessToken
|
|
||||||
// @Param id_token_hint query string true "id_token_hint"
|
|
||||||
// @Param post_logout_redirect_uri query string false "post_logout_redirect_uri"
|
|
||||||
// @Param state query string true "state"
|
|
||||||
// @Success 200 {object} controllers.Response The Response object
|
|
||||||
// @router /login/oauth/logout [get]
|
|
||||||
func (c *ApiController) TokenLogout() {
|
|
||||||
token := c.Input().Get("id_token_hint")
|
|
||||||
flag, application := object.DeleteTokenByAccessToken(token)
|
|
||||||
redirectUri := c.Input().Get("post_logout_redirect_uri")
|
|
||||||
state := c.Input().Get("state")
|
|
||||||
if application != nil && application.IsRedirectUriValid(redirectUri) {
|
|
||||||
c.Ctx.Redirect(http.StatusFound, redirectUri+"?state="+state)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Data["json"] = wrapActionResponse(flag)
|
|
||||||
c.ServeJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntrospectToken
|
// IntrospectToken
|
||||||
// @Title IntrospectToken
|
// @Title IntrospectToken
|
||||||
// @Description The introspection endpoint is an OAuth 2.0 endpoint that takes a
|
// @Description The introspection endpoint is an OAuth 2.0 endpoint that takes a
|
||||||
|
@ -148,8 +148,8 @@ func (c *ApiController) UpdateUser() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.DisplayName == "" {
|
if msg := object.CheckUpdateUser(object.GetUser(id), &user, c.GetAcceptLanguage()); msg != "" {
|
||||||
c.ResponseError(c.T("user:Display name cannot be empty"))
|
c.ResponseError(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +159,12 @@ func (c *ApiController) UpdateUser() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isGlobalAdmin := c.IsGlobalAdmin()
|
isGlobalAdmin := c.IsGlobalAdmin()
|
||||||
|
|
||||||
|
if pass, err := checkPermissionForUpdateUser(id, user, c); !pass {
|
||||||
|
c.ResponseError(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
affected := object.UpdateUser(id, &user, columns, isGlobalAdmin)
|
affected := object.UpdateUser(id, &user, columns, isGlobalAdmin)
|
||||||
if affected {
|
if affected {
|
||||||
object.UpdateUserToOriginalDatabase(&user)
|
object.UpdateUserToOriginalDatabase(&user)
|
||||||
@ -236,7 +242,7 @@ func (c *ApiController) GetEmailAndPhone() {
|
|||||||
|
|
||||||
user := object.GetUserByFields(form.Organization, form.Username)
|
user := object.GetUserByFields(form.Organization, form.Username)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("user:The user: %s/%s doesn't exist"), form.Organization, form.Username))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
135
controllers/user_util.go
Normal file
135
controllers/user_util.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
// 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 controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/object"
|
||||||
|
)
|
||||||
|
|
||||||
|
func checkPermissionForUpdateUser(userId string, newUser object.User, c *ApiController) (bool, string) {
|
||||||
|
oldUser := object.GetUser(userId)
|
||||||
|
organization := object.GetOrganizationByUser(oldUser)
|
||||||
|
var itemsChanged []*object.AccountItem
|
||||||
|
|
||||||
|
if oldUser.Owner != newUser.Owner {
|
||||||
|
item := object.GetAccountItemByName("Organization", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Name != newUser.Name {
|
||||||
|
item := object.GetAccountItemByName("Name", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Id != newUser.Id {
|
||||||
|
item := object.GetAccountItemByName("ID", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.DisplayName != newUser.DisplayName {
|
||||||
|
item := object.GetAccountItemByName("Display name", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Avatar != newUser.Avatar {
|
||||||
|
item := object.GetAccountItemByName("Avatar", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Type != newUser.Type {
|
||||||
|
item := object.GetAccountItemByName("User type", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
// The password is *** when not modified
|
||||||
|
if oldUser.Password != newUser.Password && newUser.Password != "***" {
|
||||||
|
item := object.GetAccountItemByName("Password", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Email != newUser.Email {
|
||||||
|
item := object.GetAccountItemByName("Email", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Phone != newUser.Phone {
|
||||||
|
item := object.GetAccountItemByName("Phone", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Region != newUser.Region {
|
||||||
|
item := object.GetAccountItemByName("Country/Region", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Location != newUser.Location {
|
||||||
|
item := object.GetAccountItemByName("Location", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Affiliation != newUser.Affiliation {
|
||||||
|
item := object.GetAccountItemByName("Affiliation", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Title != newUser.Title {
|
||||||
|
item := object.GetAccountItemByName("Title", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Homepage != newUser.Homepage {
|
||||||
|
item := object.GetAccountItemByName("Homepage", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Bio != newUser.Bio {
|
||||||
|
item := object.GetAccountItemByName("Bio", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Tag != newUser.Tag {
|
||||||
|
item := object.GetAccountItemByName("Tag", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.SignupApplication != newUser.SignupApplication {
|
||||||
|
item := object.GetAccountItemByName("Signup application", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldUserPropertiesJson, _ := json.Marshal(oldUser.Properties)
|
||||||
|
newUserPropertiesJson, _ := json.Marshal(newUser.Properties)
|
||||||
|
if string(oldUserPropertiesJson) != string(newUserPropertiesJson) {
|
||||||
|
item := object.GetAccountItemByName("Properties", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.IsAdmin != newUser.IsAdmin {
|
||||||
|
item := object.GetAccountItemByName("Is admin", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.IsGlobalAdmin != newUser.IsGlobalAdmin {
|
||||||
|
item := object.GetAccountItemByName("Is global admin", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.IsForbidden != newUser.IsForbidden {
|
||||||
|
item := object.GetAccountItemByName("Is forbidden", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.IsDeleted != newUser.IsDeleted {
|
||||||
|
item := object.GetAccountItemByName("Is deleted", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentUser := c.getCurrentUser()
|
||||||
|
if currentUser == nil && c.IsGlobalAdmin() {
|
||||||
|
currentUser = &object.User{
|
||||||
|
IsGlobalAdmin: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range itemsChanged {
|
||||||
|
if pass, err := object.CheckAccountItemModifyRule(itemsChanged[i], currentUser, c.GetAcceptLanguage()); !pass {
|
||||||
|
return pass, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, ""
|
||||||
|
}
|
@ -84,7 +84,7 @@ func (c *ApiController) SetTokenErrorHttpStatus() {
|
|||||||
func (c *ApiController) RequireSignedIn() (string, bool) {
|
func (c *ApiController) RequireSignedIn() (string, bool) {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError(c.T("util:Please login first"), "Please login first")
|
c.ResponseError(c.T("general:Please login first"), "Please login first")
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
return userId, true
|
return userId, true
|
||||||
@ -100,7 +100,7 @@ func (c *ApiController) RequireSignedInUser() (*object.User, bool) {
|
|||||||
user := object.GetUser(userId)
|
user := object.GetUser(userId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ClearUserSession()
|
c.ClearUserSession()
|
||||||
c.ResponseError(fmt.Sprintf(c.T("util:The user: %s doesn't exist"), userId))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), userId))
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return user, true
|
return user, true
|
||||||
|
@ -51,15 +51,15 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
|
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
|
||||||
|
|
||||||
if destType == "" {
|
if destType == "" {
|
||||||
c.ResponseError(c.T("verification:Missing parameter") + ": type.")
|
c.ResponseError(c.T("general:Missing parameter") + ": type.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if dest == "" {
|
if dest == "" {
|
||||||
c.ResponseError(c.T("verification:Missing parameter") + ": dest.")
|
c.ResponseError(c.T("general:Missing parameter") + ": dest.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if applicationId == "" {
|
if applicationId == "" {
|
||||||
c.ResponseError(c.T("verification:Missing parameter") + ": applicationId.")
|
c.ResponseError(c.T("general:Missing parameter") + ": applicationId.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(applicationId, "/") {
|
if !strings.Contains(applicationId, "/") {
|
||||||
@ -67,7 +67,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if checkType == "" {
|
if checkType == "" {
|
||||||
c.ResponseError(c.T("verification:Missing parameter") + ": checkType.")
|
c.ResponseError(c.T("general:Missing parameter") + ": checkType.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
|
|
||||||
if captchaProvider != nil {
|
if captchaProvider != nil {
|
||||||
if checkKey == "" {
|
if checkKey == "" {
|
||||||
c.ResponseError(c.T("verification:Missing parameter") + ": checkKey.")
|
c.ResponseError(c.T("general:Missing parameter") + ": checkKey.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isHuman, err := captchaProvider.VerifyCaptcha(checkKey, checkId)
|
isHuman, err := captchaProvider.VerifyCaptcha(checkKey, checkId)
|
||||||
@ -99,7 +99,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if checkUser == "true" && user == nil && object.GetUserByFields(organization.Name, dest) == nil {
|
if checkUser == "true" && user == nil && object.GetUserByFields(organization.Name, dest) == nil {
|
||||||
c.ResponseError(c.T("verification:Please login first"))
|
c.ResponseError(c.T("general:Please login first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,14 +170,19 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
dest := c.Ctx.Request.Form.Get("dest")
|
dest := c.Ctx.Request.Form.Get("dest")
|
||||||
code := c.Ctx.Request.Form.Get("code")
|
code := c.Ctx.Request.Form.Get("code")
|
||||||
if len(dest) == 0 || len(code) == 0 || len(destType) == 0 {
|
if len(dest) == 0 || len(code) == 0 || len(destType) == 0 {
|
||||||
c.ResponseError(c.T("verification:Missing parameter"))
|
c.ResponseError(c.T("general:Missing parameter"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDest := dest
|
checkDest := dest
|
||||||
org := object.GetOrganizationByUser(user)
|
organization := object.GetOrganizationByUser(user)
|
||||||
if destType == "phone" {
|
if destType == "phone" {
|
||||||
phoneItem := object.GetAccountItemByName("Phone", org)
|
if object.HasUserByField(user.Owner, "phone", user.Phone) {
|
||||||
|
c.ResponseError(c.T("check:Phone already exists"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
phoneItem := object.GetAccountItemByName("Phone", organization)
|
||||||
if phoneItem == nil {
|
if phoneItem == nil {
|
||||||
c.ResponseError(c.T("verification:Unable to get the phone modify rule."))
|
c.ResponseError(c.T("verification:Unable to get the phone modify rule."))
|
||||||
return
|
return
|
||||||
@ -189,12 +194,17 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
phonePrefix := "86"
|
phonePrefix := "86"
|
||||||
if org != nil && org.PhonePrefix != "" {
|
if organization != nil && organization.PhonePrefix != "" {
|
||||||
phonePrefix = org.PhonePrefix
|
phonePrefix = organization.PhonePrefix
|
||||||
}
|
}
|
||||||
checkDest = fmt.Sprintf("+%s%s", phonePrefix, dest)
|
checkDest = fmt.Sprintf("+%s%s", phonePrefix, dest)
|
||||||
} else if destType == "email" {
|
} else if destType == "email" {
|
||||||
emailItem := object.GetAccountItemByName("Email", org)
|
if object.HasUserByField(user.Owner, "email", user.Email) {
|
||||||
|
c.ResponseError(c.T("check:Email already exists"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emailItem := object.GetAccountItemByName("Email", organization)
|
||||||
if emailItem == nil {
|
if emailItem == nil {
|
||||||
c.ResponseError(c.T("verification:Unable to get the email modify rule."))
|
c.ResponseError(c.T("verification:Unable to get the email modify rule."))
|
||||||
return
|
return
|
||||||
@ -237,11 +247,11 @@ func (c *ApiController) VerifyCaptcha() {
|
|||||||
captchaToken := c.Ctx.Request.Form.Get("captchaToken")
|
captchaToken := c.Ctx.Request.Form.Get("captchaToken")
|
||||||
clientSecret := c.Ctx.Request.Form.Get("clientSecret")
|
clientSecret := c.Ctx.Request.Form.Get("clientSecret")
|
||||||
if captchaToken == "" {
|
if captchaToken == "" {
|
||||||
c.ResponseError(c.T("verification:Missing parameter") + ": captchaToken.")
|
c.ResponseError(c.T("general:Missing parameter") + ": captchaToken.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if clientSecret == "" {
|
if clientSecret == "" {
|
||||||
c.ResponseError(c.T("verification:Missing parameter") + ": clientSecret.")
|
c.ResponseError(c.T("general:Missing parameter") + ": clientSecret.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ func (c *ApiController) WebAuthnSignupBegin() {
|
|||||||
webauthnObj := object.GetWebAuthnObject(c.Ctx.Request.Host)
|
webauthnObj := object.GetWebAuthnObject(c.Ctx.Request.Host)
|
||||||
user := c.getCurrentUser()
|
user := c.getCurrentUser()
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(c.T("webauthn:Please login first"))
|
c.ResponseError(c.T("general:Please login first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ func (c *ApiController) WebAuthnSignupFinish() {
|
|||||||
webauthnObj := object.GetWebAuthnObject(c.Ctx.Request.Host)
|
webauthnObj := object.GetWebAuthnObject(c.Ctx.Request.Host)
|
||||||
user := c.getCurrentUser()
|
user := c.getCurrentUser()
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(c.T("webauthn:Please login first"))
|
c.ResponseError(c.T("general:Please login first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sessionObj := c.GetSession("registration")
|
sessionObj := c.GetSession("registration")
|
||||||
@ -101,7 +101,7 @@ func (c *ApiController) WebAuthnSigninBegin() {
|
|||||||
userName := c.Input().Get("name")
|
userName := c.Input().Get("name")
|
||||||
user := object.GetUserByFields(userOwner, userName)
|
user := object.GetUserByFields(userOwner, userName)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("webauthn:The user: %s/%s doesn't exist"), userOwner, userName))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(userOwner, userName)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(user.WebauthnCredentials) == 0 {
|
if len(user.WebauthnCredentials) == 0 {
|
||||||
|
5
go.mod
5
go.mod
@ -13,7 +13,7 @@ require (
|
|||||||
github.com/casdoor/go-sms-sender v0.5.1
|
github.com/casdoor/go-sms-sender v0.5.1
|
||||||
github.com/casdoor/oss v1.2.0
|
github.com/casdoor/oss v1.2.0
|
||||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc
|
github.com/denisenkom/go-mssqldb v0.9.0
|
||||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
|
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
|
||||||
github.com/forestmgy/ldapserver v1.1.0
|
github.com/forestmgy/ldapserver v1.1.0
|
||||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
||||||
@ -51,7 +51,8 @@ require (
|
|||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0
|
gopkg.in/square/go-jose.v2 v2.6.0
|
||||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||||
|
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84
|
||||||
xorm.io/builder v0.3.12 // indirect
|
xorm.io/builder v0.3.12 // indirect
|
||||||
xorm.io/core v0.7.2
|
xorm.io/core v0.7.2
|
||||||
xorm.io/xorm v1.0.5
|
xorm.io/xorm v1.1.2
|
||||||
)
|
)
|
||||||
|
58
go.sum
58
go.sum
@ -126,10 +126,13 @@ github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWW
|
|||||||
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
|
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.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
|
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
|
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 h1:L63RATZFZuFMXy6ixnKmv3eNAXwYQF6HW1vd4IYsQqQ=
|
||||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
|
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
|
||||||
|
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/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/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 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||||
@ -231,6 +234,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
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.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 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
@ -279,14 +283,17 @@ github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9q
|
|||||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||||
|
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
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/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=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
@ -327,8 +334,11 @@ github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911
|
|||||||
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
|
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=
|
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
|
||||||
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
|
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
|
||||||
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
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 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
@ -384,6 +394,8 @@ github.com/qiangmzsx/string-adapter/v2 v2.1.0/go.mod h1:PElPB7b7HnGKTsuADAffFpOQ
|
|||||||
github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
|
github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
|
||||||
github.com/qiniu/go-sdk/v7 v7.12.1/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w=
|
github.com/qiniu/go-sdk/v7 v7.12.1/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w=
|
||||||
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
|
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||||
|
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 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
@ -506,6 +518,7 @@ 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.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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.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.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -539,6 +552,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
|||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
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-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
@ -561,6 +575,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
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-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-20210220032951-036812b2e83c/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -585,6 +600,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -599,7 +615,10 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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-20210330210617-4fbd30eecc44/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-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-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@ -669,10 +688,13 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
|||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
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-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.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
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-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-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=
|
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.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||||
@ -795,14 +817,42 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
|
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009 h1:u0oCo5b9wyLr++HF3AN9JicGhkUxJhMz51+8TIZH9N0=
|
||||||
|
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/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||||
|
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||||
|
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.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/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/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.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/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/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||||
|
xorm.io/builder v0.3.8/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||||
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
|
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
|
||||||
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||||
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
|
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
|
||||||
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||||
xorm.io/xorm v1.0.3/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
xorm.io/xorm v1.0.3/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
||||||
xorm.io/xorm v1.0.5 h1:LRr5PfOUb4ODPR63YwbowkNDwcolT2LnkwP/TUaMaB0=
|
xorm.io/xorm v1.1.2 h1:bje+1KZvK3m5AHtZNfUDlKEEyuw/IRHT+an0CLIG5TU=
|
||||||
xorm.io/xorm v1.0.5/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
xorm.io/xorm v1.1.2/go.mod h1:Cb0DKYTHbyECMaSfgRnIZp5aiUgQozxcJJ0vzcLGJSg=
|
||||||
|
@ -26,16 +26,22 @@ import (
|
|||||||
|
|
||||||
type I18nData map[string]map[string]string
|
type I18nData map[string]map[string]string
|
||||||
|
|
||||||
var reI18n *regexp.Regexp
|
var (
|
||||||
|
reI18nFrontend *regexp.Regexp
|
||||||
|
reI18nBackendObject *regexp.Regexp
|
||||||
|
reI18nBackendController *regexp.Regexp
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
reI18n, _ = regexp.Compile("i18next.t\\(\"(.*?)\"\\)")
|
reI18nFrontend, _ = regexp.Compile("i18next.t\\(\"(.*?)\"\\)")
|
||||||
|
reI18nBackendObject, _ = regexp.Compile("i18n.Translate\\((.*?)\"\\)")
|
||||||
|
reI18nBackendController, _ = regexp.Compile("c.T\\((.*?)\"\\)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAllI18nStrings(fileContent string) []string {
|
func getAllI18nStringsFrontend(fileContent string) []string {
|
||||||
res := []string{}
|
res := []string{}
|
||||||
|
|
||||||
matches := reI18n.FindAllStringSubmatch(fileContent, -1)
|
matches := reI18nFrontend.FindAllStringSubmatch(fileContent, -1)
|
||||||
if matches == nil {
|
if matches == nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@ -46,17 +52,39 @@ func getAllI18nStrings(fileContent string) []string {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAllJsFilePaths() []string {
|
func getAllI18nStringsBackend(fileContent string, isObjectPackage bool) []string {
|
||||||
path := "../web/src"
|
|
||||||
|
|
||||||
res := []string{}
|
res := []string{}
|
||||||
err := filepath.Walk(path,
|
if isObjectPackage {
|
||||||
|
matches := reI18nBackendObject.FindAllStringSubmatch(fileContent, -1)
|
||||||
|
if matches == nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
for _, match := range matches {
|
||||||
|
match := strings.SplitN(match[1], ",", 2)
|
||||||
|
res = append(res, match[1][2:])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matches := reI18nBackendController.FindAllStringSubmatch(fileContent, -1)
|
||||||
|
if matches == nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
for _, match := range matches {
|
||||||
|
res = append(res, match[1][1:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAllFilePathsInFolder(folder string, fileSuffix string) []string {
|
||||||
|
res := []string{}
|
||||||
|
err := filepath.Walk(folder,
|
||||||
func(path string, info os.FileInfo, err error) error {
|
func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasSuffix(info.Name(), ".js") {
|
if !strings.HasSuffix(info.Name(), fileSuffix) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,12 +99,25 @@ func getAllJsFilePaths() []string {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseToData() *I18nData {
|
func parseEnData(category string) *I18nData {
|
||||||
|
var paths []string
|
||||||
|
if category == "backend" {
|
||||||
|
paths = getAllFilePathsInFolder("../", ".go")
|
||||||
|
} else {
|
||||||
|
paths = getAllFilePathsInFolder("../web/src", ".js")
|
||||||
|
}
|
||||||
|
|
||||||
allWords := []string{}
|
allWords := []string{}
|
||||||
paths := getAllJsFilePaths()
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
fileContent := util.ReadStringFromPath(path)
|
fileContent := util.ReadStringFromPath(path)
|
||||||
words := getAllI18nStrings(fileContent)
|
|
||||||
|
var words []string
|
||||||
|
if category == "backend" {
|
||||||
|
isObjectPackage := strings.Contains(path, "object")
|
||||||
|
words = getAllI18nStringsBackend(fileContent, isObjectPackage)
|
||||||
|
} else {
|
||||||
|
words = getAllI18nStringsFrontend(fileContent)
|
||||||
|
}
|
||||||
allWords = append(allWords, words...)
|
allWords = append(allWords, words...)
|
||||||
}
|
}
|
||||||
fmt.Printf("%v\n", allWords)
|
fmt.Printf("%v\n", allWords)
|
||||||
|
@ -1,115 +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 i18n
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
reI18nBackendObject *regexp.Regexp
|
|
||||||
re18nBackendController *regexp.Regexp
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
reI18nBackendObject, _ = regexp.Compile("i18n.Translate\\((.*?)\"\\)")
|
|
||||||
re18nBackendController, _ = regexp.Compile("c.T\\((.*?)\"\\)")
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetAllI18nStrings(fileContent string, path string) []string {
|
|
||||||
res := []string{}
|
|
||||||
if strings.Contains(path, "object") {
|
|
||||||
matches := reI18nBackendObject.FindAllStringSubmatch(fileContent, -1)
|
|
||||||
if matches == nil {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
for _, match := range matches {
|
|
||||||
match := strings.SplitN(match[1], ",", 2)
|
|
||||||
res = append(res, match[1][2:])
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
matches := re18nBackendController.FindAllStringSubmatch(fileContent, -1)
|
|
||||||
if matches == nil {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
for _, match := range matches {
|
|
||||||
res = append(res, match[1][1:])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAllGoFilePaths() []string {
|
|
||||||
path := "../"
|
|
||||||
|
|
||||||
res := []string{}
|
|
||||||
err := filepath.Walk(path,
|
|
||||||
func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasSuffix(info.Name(), ".go") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res = append(res, path)
|
|
||||||
// fmt.Println(path, info.Name())
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func getErrName(paths []string) map[string]string {
|
|
||||||
ErrName := make(map[string]string)
|
|
||||||
for i := 0; i < len(paths); i++ {
|
|
||||||
content := util.ReadStringFromPath(paths[i])
|
|
||||||
words := GetAllI18nStrings(content, paths[i])
|
|
||||||
for j := 0; j < len(words); j++ {
|
|
||||||
ErrName[words[j]] = paths[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ErrName
|
|
||||||
}
|
|
||||||
|
|
||||||
func getI18nJSONData(errName map[string]string) *I18nData {
|
|
||||||
data := I18nData{}
|
|
||||||
for k, v := range errName {
|
|
||||||
var index int
|
|
||||||
if strings.Contains(v, "/") {
|
|
||||||
index = strings.LastIndex(v, "/")
|
|
||||||
} else {
|
|
||||||
index = strings.LastIndex(v, "\\")
|
|
||||||
}
|
|
||||||
namespace := v[index+1 : len(v)-3]
|
|
||||||
key := k[len(namespace)+1:]
|
|
||||||
// fmt.Printf("k=%s,v=%s,namespace=%s,key=%s\n", k, v, namespace, key)
|
|
||||||
if _, ok := data[namespace]; !ok {
|
|
||||||
data[namespace] = map[string]string{}
|
|
||||||
}
|
|
||||||
data[namespace][key] = key
|
|
||||||
}
|
|
||||||
return &data
|
|
||||||
}
|
|
@ -15,50 +15,39 @@
|
|||||||
package i18n
|
package i18n
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func applyToOtherLanguage(dataEn *I18nData, lang string) {
|
func applyToOtherLanguage(category string, language string, i18nData *I18nData) {
|
||||||
dataOther := readI18nFile(lang)
|
newData := readI18nFile(category, language)
|
||||||
println(dataOther)
|
println(newData)
|
||||||
|
|
||||||
applyData(dataEn, dataOther)
|
applyData(i18nData, newData)
|
||||||
writeI18nFile(lang, dataEn)
|
writeI18nFile(category, language, i18nData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateI18nStringsForFrontend(t *testing.T) {
|
func TestGenerateI18nFrontend(t *testing.T) {
|
||||||
dataEn := parseToData()
|
enData := parseEnData("frontend")
|
||||||
writeI18nFile("en", dataEn)
|
writeI18nFile("frontend", "en", enData)
|
||||||
|
|
||||||
applyToOtherLanguage(dataEn, "de")
|
applyToOtherLanguage("frontend", "de", enData)
|
||||||
applyToOtherLanguage(dataEn, "fr")
|
applyToOtherLanguage("frontend", "es", enData)
|
||||||
applyToOtherLanguage(dataEn, "ja")
|
applyToOtherLanguage("frontend", "fr", enData)
|
||||||
applyToOtherLanguage(dataEn, "ko")
|
applyToOtherLanguage("frontend", "ja", enData)
|
||||||
applyToOtherLanguage(dataEn, "ru")
|
applyToOtherLanguage("frontend", "ko", enData)
|
||||||
applyToOtherLanguage(dataEn, "zh")
|
applyToOtherLanguage("frontend", "ru", enData)
|
||||||
|
applyToOtherLanguage("frontend", "zh", enData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateI18nStringsForBackend(t *testing.T) {
|
func TestGenerateI18nBackend(t *testing.T) {
|
||||||
paths := getAllGoFilePaths()
|
enData := parseEnData("backend")
|
||||||
|
writeI18nFile("backend", "en", enData)
|
||||||
|
|
||||||
errName := getErrName(paths)
|
applyToOtherLanguage("backend", "de", enData)
|
||||||
|
applyToOtherLanguage("backend", "es", enData)
|
||||||
dataEn := getI18nJSONData(errName)
|
applyToOtherLanguage("backend", "fr", enData)
|
||||||
|
applyToOtherLanguage("backend", "ja", enData)
|
||||||
writeI18nFile("backend_en", dataEn)
|
applyToOtherLanguage("backend", "ko", enData)
|
||||||
|
applyToOtherLanguage("backend", "ru", enData)
|
||||||
applyToOtherLanguage(dataEn, "backend_de")
|
applyToOtherLanguage("backend", "zh", enData)
|
||||||
applyToOtherLanguage(dataEn, "backend_es")
|
|
||||||
applyToOtherLanguage(dataEn, "backend_fr")
|
|
||||||
applyToOtherLanguage(dataEn, "backend_ja")
|
|
||||||
applyToOtherLanguage(dataEn, "backend_ko")
|
|
||||||
applyToOtherLanguage(dataEn, "backend_ru")
|
|
||||||
applyToOtherLanguage(dataEn, "backend_zh")
|
|
||||||
|
|
||||||
fmt.Println("Total Err Words:", len(errName))
|
|
||||||
|
|
||||||
for i := range errName {
|
|
||||||
fmt.Println(i)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,25 @@
|
|||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||||
"Invalid information": "Invalid information",
|
"Invalid information": "Invalid information",
|
||||||
"Phone: %s": "Phone: %s",
|
"Phone: %s": "Phone: %s",
|
||||||
|
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||||
},
|
},
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Parameter organization is missing",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s No phone prefix",
|
"%s No phone prefix": "%s No phone prefix",
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
"Challenge method should be S256": "Challenge method should be S256",
|
||||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||||
"Failed to login in: %s": "Failed to login in: %s",
|
"Failed to login in: %s": "Failed to login in: %s",
|
||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
|
||||||
"Invalid token": "Invalid token",
|
"Invalid token": "Invalid token",
|
||||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
|
||||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||||
"The account does not exist": "The account does not exist",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||||
"The application: %s does not exist": "The application: %s does not exist",
|
"The application: %s does not exist": "The application: %s does not exist",
|
||||||
|
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
||||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unauthorized operation": "Unauthorized operation",
|
"Unauthorized operation": "Unauthorized operation",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||||
@ -53,11 +47,8 @@
|
|||||||
"Phone already exists": "Phone already exists",
|
"Phone already exists": "Phone already exists",
|
||||||
"Phone cannot be empty": "Phone cannot be empty",
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Session outdated, please login again": "Session outdated, please login again",
|
"Session outdated, please login again": "Session outdated, please login again",
|
||||||
"The user doesn't exist": "The user doesn't exist",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||||
"Username already exists": "Username already exists",
|
"Username already exists": "Username already exists",
|
||||||
"Username cannot be an email address": "Username cannot be an email address",
|
"Username cannot be an email address": "Username cannot be an email address",
|
||||||
@ -65,20 +56,17 @@
|
|||||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||||
"You don't have the permission to do this": "You don't have the permission to do this",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again",
|
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||||
"unsupported password type: %s": "unsupported password type: %s"
|
"unsupported password type: %s": "unsupported password type: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again",
|
"Missing parameter": "Missing parameter",
|
||||||
"password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances"
|
"Please login first": "Please login first",
|
||||||
},
|
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "Please sign in first"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap server exist",
|
"Ldap server exist": "Ldap server exist"
|
||||||
"Missing parameter": "Missing parameter"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "Please link first",
|
"Please link first": "Please link first",
|
||||||
@ -93,10 +81,6 @@
|
|||||||
"The %s is immutable.": "The %s is immutable.",
|
"The %s is immutable.": "The %s is immutable.",
|
||||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||||
},
|
},
|
||||||
"product": {
|
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "Invalid application id",
|
"Invalid application id": "Invalid application id",
|
||||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||||
@ -120,22 +104,18 @@
|
|||||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||||
},
|
},
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "You are not authorized to access this resource"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
|
||||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||||
"Invalid client_id": "Invalid client_id",
|
"Invalid client_id": "Invalid client_id",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||||
|
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "Display name cannot be empty",
|
"Display name cannot be empty": "Display name cannot be empty",
|
||||||
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
||||||
"New password must have at least 6 characters": "New password must have at least 6 characters",
|
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "Failed to import users"
|
"Failed to import users": "Failed to import users"
|
||||||
@ -143,18 +123,14 @@
|
|||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||||
"Please login first": "Please login first",
|
"The provider: %s is not found": "The provider: %s is not found"
|
||||||
"The provider: %s is not found": "The provider: %s is not found",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||||
"Email is invalid": "Email is invalid",
|
"Email is invalid": "Email is invalid",
|
||||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||||
"Missing parameter": "Missing parameter",
|
|
||||||
"Organization does not exist": "Organization does not exist",
|
"Organization does not exist": "Organization does not exist",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||||
@ -165,8 +141,6 @@
|
|||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "Found no credentials for this user",
|
"Found no credentials for this user": "Found no credentials for this user",
|
||||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first",
|
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,25 @@
|
|||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||||
"Invalid information": "Invalid information",
|
"Invalid information": "Invalid information",
|
||||||
"Phone: %s": "Phone: %s",
|
"Phone: %s": "Phone: %s",
|
||||||
|
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||||
},
|
},
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Parameter organization is missing",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s No phone prefix",
|
"%s No phone prefix": "%s No phone prefix",
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
"Challenge method should be S256": "Challenge method should be S256",
|
||||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||||
"Failed to login in: %s": "Failed to login in: %s",
|
"Failed to login in: %s": "Failed to login in: %s",
|
||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
|
||||||
"Invalid token": "Invalid token",
|
"Invalid token": "Invalid token",
|
||||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
|
||||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||||
"The account does not exist": "The account does not exist",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||||
"The application: %s does not exist": "The application: %s does not exist",
|
"The application: %s does not exist": "The application: %s does not exist",
|
||||||
|
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
||||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unauthorized operation": "Unauthorized operation",
|
"Unauthorized operation": "Unauthorized operation",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||||
@ -53,11 +47,8 @@
|
|||||||
"Phone already exists": "Phone already exists",
|
"Phone already exists": "Phone already exists",
|
||||||
"Phone cannot be empty": "Phone cannot be empty",
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Session outdated, please login again": "Session outdated, please login again",
|
"Session outdated, please login again": "Session outdated, please login again",
|
||||||
"The user doesn't exist": "The user doesn't exist",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||||
"Username already exists": "Username already exists",
|
"Username already exists": "Username already exists",
|
||||||
"Username cannot be an email address": "Username cannot be an email address",
|
"Username cannot be an email address": "Username cannot be an email address",
|
||||||
@ -65,20 +56,17 @@
|
|||||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||||
"You don't have the permission to do this": "You don't have the permission to do this",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again",
|
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||||
"unsupported password type: %s": "unsupported password type: %s"
|
"unsupported password type: %s": "unsupported password type: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again",
|
"Missing parameter": "Missing parameter",
|
||||||
"password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances"
|
"Please login first": "Please login first",
|
||||||
},
|
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "Please sign in first"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap server exist",
|
"Ldap server exist": "Ldap server exist"
|
||||||
"Missing parameter": "Missing parameter"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "Please link first",
|
"Please link first": "Please link first",
|
||||||
@ -93,10 +81,6 @@
|
|||||||
"The %s is immutable.": "The %s is immutable.",
|
"The %s is immutable.": "The %s is immutable.",
|
||||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||||
},
|
},
|
||||||
"product": {
|
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "Invalid application id",
|
"Invalid application id": "Invalid application id",
|
||||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||||
@ -120,22 +104,18 @@
|
|||||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||||
},
|
},
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "You are not authorized to access this resource"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
|
||||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||||
"Invalid client_id": "Invalid client_id",
|
"Invalid client_id": "Invalid client_id",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||||
|
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "Display name cannot be empty",
|
"Display name cannot be empty": "Display name cannot be empty",
|
||||||
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
||||||
"New password must have at least 6 characters": "New password must have at least 6 characters",
|
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "Failed to import users"
|
"Failed to import users": "Failed to import users"
|
||||||
@ -143,18 +123,14 @@
|
|||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||||
"Please login first": "Please login first",
|
"The provider: %s is not found": "The provider: %s is not found"
|
||||||
"The provider: %s is not found": "The provider: %s is not found",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||||
"Email is invalid": "Email is invalid",
|
"Email is invalid": "Email is invalid",
|
||||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||||
"Missing parameter": "Missing parameter",
|
|
||||||
"Organization does not exist": "Organization does not exist",
|
"Organization does not exist": "Organization does not exist",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||||
@ -165,8 +141,6 @@
|
|||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "Found no credentials for this user",
|
"Found no credentials for this user": "Found no credentials for this user",
|
||||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first",
|
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,25 @@
|
|||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||||
"Invalid information": "Invalid information",
|
"Invalid information": "Invalid information",
|
||||||
"Phone: %s": "Phone: %s",
|
"Phone: %s": "Phone: %s",
|
||||||
|
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||||
},
|
},
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Parameter organization is missing",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s No phone prefix",
|
"%s No phone prefix": "%s No phone prefix",
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
"Challenge method should be S256": "Challenge method should be S256",
|
||||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||||
"Failed to login in: %s": "Failed to login in: %s",
|
"Failed to login in: %s": "Failed to login in: %s",
|
||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
|
||||||
"Invalid token": "Invalid token",
|
"Invalid token": "Invalid token",
|
||||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
|
||||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||||
"The account does not exist": "The account does not exist",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||||
"The application: %s does not exist": "The application: %s does not exist",
|
"The application: %s does not exist": "The application: %s does not exist",
|
||||||
|
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
||||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unauthorized operation": "Unauthorized operation",
|
"Unauthorized operation": "Unauthorized operation",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||||
@ -53,11 +47,8 @@
|
|||||||
"Phone already exists": "Phone already exists",
|
"Phone already exists": "Phone already exists",
|
||||||
"Phone cannot be empty": "Phone cannot be empty",
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Session outdated, please login again": "Session outdated, please login again",
|
"Session outdated, please login again": "Session outdated, please login again",
|
||||||
"The user doesn't exist": "The user doesn't exist",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||||
"Username already exists": "Username already exists",
|
"Username already exists": "Username already exists",
|
||||||
"Username cannot be an email address": "Username cannot be an email address",
|
"Username cannot be an email address": "Username cannot be an email address",
|
||||||
@ -65,20 +56,17 @@
|
|||||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||||
"You don't have the permission to do this": "You don't have the permission to do this",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again",
|
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||||
"unsupported password type: %s": "unsupported password type: %s"
|
"unsupported password type: %s": "unsupported password type: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again",
|
"Missing parameter": "Missing parameter",
|
||||||
"password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances"
|
"Please login first": "Please login first",
|
||||||
},
|
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "Please sign in first"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap server exist",
|
"Ldap server exist": "Ldap server exist"
|
||||||
"Missing parameter": "Missing parameter"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "Please link first",
|
"Please link first": "Please link first",
|
||||||
@ -93,10 +81,6 @@
|
|||||||
"The %s is immutable.": "The %s is immutable.",
|
"The %s is immutable.": "The %s is immutable.",
|
||||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||||
},
|
},
|
||||||
"product": {
|
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "Invalid application id",
|
"Invalid application id": "Invalid application id",
|
||||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||||
@ -120,22 +104,18 @@
|
|||||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||||
},
|
},
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "You are not authorized to access this resource"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
|
||||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||||
"Invalid client_id": "Invalid client_id",
|
"Invalid client_id": "Invalid client_id",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||||
|
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "Display name cannot be empty",
|
"Display name cannot be empty": "Display name cannot be empty",
|
||||||
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
||||||
"New password must have at least 6 characters": "New password must have at least 6 characters",
|
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "Failed to import users"
|
"Failed to import users": "Failed to import users"
|
||||||
@ -143,18 +123,14 @@
|
|||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||||
"Please login first": "Please login first",
|
"The provider: %s is not found": "The provider: %s is not found"
|
||||||
"The provider: %s is not found": "The provider: %s is not found",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||||
"Email is invalid": "Email is invalid",
|
"Email is invalid": "Email is invalid",
|
||||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||||
"Missing parameter": "Missing parameter",
|
|
||||||
"Organization does not exist": "Organization does not exist",
|
"Organization does not exist": "Organization does not exist",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||||
@ -165,8 +141,6 @@
|
|||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "Found no credentials for this user",
|
"Found no credentials for this user": "Found no credentials for this user",
|
||||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first",
|
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,25 @@
|
|||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||||
"Invalid information": "Invalid information",
|
"Invalid information": "Invalid information",
|
||||||
"Phone: %s": "Phone: %s",
|
"Phone: %s": "Phone: %s",
|
||||||
|
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||||
},
|
},
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Parameter organization is missing",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s No phone prefix",
|
"%s No phone prefix": "%s No phone prefix",
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
"Challenge method should be S256": "Challenge method should be S256",
|
||||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||||
"Failed to login in: %s": "Failed to login in: %s",
|
"Failed to login in: %s": "Failed to login in: %s",
|
||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
|
||||||
"Invalid token": "Invalid token",
|
"Invalid token": "Invalid token",
|
||||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
|
||||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||||
"The account does not exist": "The account does not exist",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||||
"The application: %s does not exist": "The application: %s does not exist",
|
"The application: %s does not exist": "The application: %s does not exist",
|
||||||
|
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
||||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unauthorized operation": "Unauthorized operation",
|
"Unauthorized operation": "Unauthorized operation",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||||
@ -53,11 +47,8 @@
|
|||||||
"Phone already exists": "Phone already exists",
|
"Phone already exists": "Phone already exists",
|
||||||
"Phone cannot be empty": "Phone cannot be empty",
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Session outdated, please login again": "Session outdated, please login again",
|
"Session outdated, please login again": "Session outdated, please login again",
|
||||||
"The user doesn't exist": "The user doesn't exist",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||||
"Username already exists": "Username already exists",
|
"Username already exists": "Username already exists",
|
||||||
"Username cannot be an email address": "Username cannot be an email address",
|
"Username cannot be an email address": "Username cannot be an email address",
|
||||||
@ -65,20 +56,17 @@
|
|||||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||||
"You don't have the permission to do this": "You don't have the permission to do this",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again",
|
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||||
"unsupported password type: %s": "unsupported password type: %s"
|
"unsupported password type: %s": "unsupported password type: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again",
|
"Missing parameter": "Missing parameter",
|
||||||
"password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances"
|
"Please login first": "Please login first",
|
||||||
},
|
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "Please sign in first"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap server exist",
|
"Ldap server exist": "Ldap server exist"
|
||||||
"Missing parameter": "Missing parameter"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "Please link first",
|
"Please link first": "Please link first",
|
||||||
@ -93,10 +81,6 @@
|
|||||||
"The %s is immutable.": "The %s is immutable.",
|
"The %s is immutable.": "The %s is immutable.",
|
||||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||||
},
|
},
|
||||||
"product": {
|
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "Invalid application id",
|
"Invalid application id": "Invalid application id",
|
||||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||||
@ -120,22 +104,18 @@
|
|||||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||||
},
|
},
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "You are not authorized to access this resource"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
|
||||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||||
"Invalid client_id": "Invalid client_id",
|
"Invalid client_id": "Invalid client_id",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||||
|
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "Display name cannot be empty",
|
"Display name cannot be empty": "Display name cannot be empty",
|
||||||
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
||||||
"New password must have at least 6 characters": "New password must have at least 6 characters",
|
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "Failed to import users"
|
"Failed to import users": "Failed to import users"
|
||||||
@ -143,18 +123,14 @@
|
|||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||||
"Please login first": "Please login first",
|
"The provider: %s is not found": "The provider: %s is not found"
|
||||||
"The provider: %s is not found": "The provider: %s is not found",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||||
"Email is invalid": "Email is invalid",
|
"Email is invalid": "Email is invalid",
|
||||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||||
"Missing parameter": "Missing parameter",
|
|
||||||
"Organization does not exist": "Organization does not exist",
|
"Organization does not exist": "Organization does not exist",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||||
@ -165,8 +141,6 @@
|
|||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "Found no credentials for this user",
|
"Found no credentials for this user": "Found no credentials for this user",
|
||||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first",
|
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,25 @@
|
|||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||||
"Invalid information": "Invalid information",
|
"Invalid information": "Invalid information",
|
||||||
"Phone: %s": "Phone: %s",
|
"Phone: %s": "Phone: %s",
|
||||||
|
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||||
},
|
},
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Parameter organization is missing",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s No phone prefix",
|
"%s No phone prefix": "%s No phone prefix",
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
"Challenge method should be S256": "Challenge method should be S256",
|
||||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||||
"Failed to login in: %s": "Failed to login in: %s",
|
"Failed to login in: %s": "Failed to login in: %s",
|
||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
|
||||||
"Invalid token": "Invalid token",
|
"Invalid token": "Invalid token",
|
||||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
|
||||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||||
"The account does not exist": "The account does not exist",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||||
"The application: %s does not exist": "The application: %s does not exist",
|
"The application: %s does not exist": "The application: %s does not exist",
|
||||||
|
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
||||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unauthorized operation": "Unauthorized operation",
|
"Unauthorized operation": "Unauthorized operation",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||||
@ -53,11 +47,8 @@
|
|||||||
"Phone already exists": "Phone already exists",
|
"Phone already exists": "Phone already exists",
|
||||||
"Phone cannot be empty": "Phone cannot be empty",
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Session outdated, please login again": "Session outdated, please login again",
|
"Session outdated, please login again": "Session outdated, please login again",
|
||||||
"The user doesn't exist": "The user doesn't exist",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||||
"Username already exists": "Username already exists",
|
"Username already exists": "Username already exists",
|
||||||
"Username cannot be an email address": "Username cannot be an email address",
|
"Username cannot be an email address": "Username cannot be an email address",
|
||||||
@ -65,20 +56,17 @@
|
|||||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||||
"You don't have the permission to do this": "You don't have the permission to do this",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again",
|
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||||
"unsupported password type: %s": "unsupported password type: %s"
|
"unsupported password type: %s": "unsupported password type: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again",
|
"Missing parameter": "Missing parameter",
|
||||||
"password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances"
|
"Please login first": "Please login first",
|
||||||
},
|
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "Please sign in first"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap server exist",
|
"Ldap server exist": "Ldap server exist"
|
||||||
"Missing parameter": "Missing parameter"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "Please link first",
|
"Please link first": "Please link first",
|
||||||
@ -93,10 +81,6 @@
|
|||||||
"The %s is immutable.": "The %s is immutable.",
|
"The %s is immutable.": "The %s is immutable.",
|
||||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||||
},
|
},
|
||||||
"product": {
|
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "Invalid application id",
|
"Invalid application id": "Invalid application id",
|
||||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||||
@ -120,22 +104,18 @@
|
|||||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||||
},
|
},
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "You are not authorized to access this resource"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
|
||||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||||
"Invalid client_id": "Invalid client_id",
|
"Invalid client_id": "Invalid client_id",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||||
|
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "Display name cannot be empty",
|
"Display name cannot be empty": "Display name cannot be empty",
|
||||||
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
||||||
"New password must have at least 6 characters": "New password must have at least 6 characters",
|
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "Failed to import users"
|
"Failed to import users": "Failed to import users"
|
||||||
@ -143,18 +123,14 @@
|
|||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||||
"Please login first": "Please login first",
|
"The provider: %s is not found": "The provider: %s is not found"
|
||||||
"The provider: %s is not found": "The provider: %s is not found",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||||
"Email is invalid": "Email is invalid",
|
"Email is invalid": "Email is invalid",
|
||||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||||
"Missing parameter": "Missing parameter",
|
|
||||||
"Organization does not exist": "Organization does not exist",
|
"Organization does not exist": "Organization does not exist",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||||
@ -165,8 +141,6 @@
|
|||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "Found no credentials for this user",
|
"Found no credentials for this user": "Found no credentials for this user",
|
||||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first",
|
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,25 @@
|
|||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||||
"Invalid information": "Invalid information",
|
"Invalid information": "Invalid information",
|
||||||
"Phone: %s": "Phone: %s",
|
"Phone: %s": "Phone: %s",
|
||||||
|
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||||
},
|
},
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Parameter organization is missing",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s No phone prefix",
|
"%s No phone prefix": "%s No phone prefix",
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
"Challenge method should be S256": "Challenge method should be S256",
|
||||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||||
"Failed to login in: %s": "Failed to login in: %s",
|
"Failed to login in: %s": "Failed to login in: %s",
|
||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
|
||||||
"Invalid token": "Invalid token",
|
"Invalid token": "Invalid token",
|
||||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
|
||||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||||
"The account does not exist": "The account does not exist",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||||
"The application: %s does not exist": "The application: %s does not exist",
|
"The application: %s does not exist": "The application: %s does not exist",
|
||||||
|
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
||||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unauthorized operation": "Unauthorized operation",
|
"Unauthorized operation": "Unauthorized operation",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||||
@ -53,11 +47,8 @@
|
|||||||
"Phone already exists": "Phone already exists",
|
"Phone already exists": "Phone already exists",
|
||||||
"Phone cannot be empty": "Phone cannot be empty",
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Session outdated, please login again": "Session outdated, please login again",
|
"Session outdated, please login again": "Session outdated, please login again",
|
||||||
"The user doesn't exist": "The user doesn't exist",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||||
"Username already exists": "Username already exists",
|
"Username already exists": "Username already exists",
|
||||||
"Username cannot be an email address": "Username cannot be an email address",
|
"Username cannot be an email address": "Username cannot be an email address",
|
||||||
@ -65,20 +56,17 @@
|
|||||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||||
"You don't have the permission to do this": "You don't have the permission to do this",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again",
|
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||||
"unsupported password type: %s": "unsupported password type: %s"
|
"unsupported password type: %s": "unsupported password type: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again",
|
"Missing parameter": "Missing parameter",
|
||||||
"password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances"
|
"Please login first": "Please login first",
|
||||||
},
|
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "Please sign in first"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap server exist",
|
"Ldap server exist": "Ldap server exist"
|
||||||
"Missing parameter": "Missing parameter"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "Please link first",
|
"Please link first": "Please link first",
|
||||||
@ -93,10 +81,6 @@
|
|||||||
"The %s is immutable.": "The %s is immutable.",
|
"The %s is immutable.": "The %s is immutable.",
|
||||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||||
},
|
},
|
||||||
"product": {
|
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "Invalid application id",
|
"Invalid application id": "Invalid application id",
|
||||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||||
@ -120,22 +104,18 @@
|
|||||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||||
},
|
},
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "You are not authorized to access this resource"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
|
||||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||||
"Invalid client_id": "Invalid client_id",
|
"Invalid client_id": "Invalid client_id",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||||
|
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "Display name cannot be empty",
|
"Display name cannot be empty": "Display name cannot be empty",
|
||||||
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
||||||
"New password must have at least 6 characters": "New password must have at least 6 characters",
|
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "Failed to import users"
|
"Failed to import users": "Failed to import users"
|
||||||
@ -143,18 +123,14 @@
|
|||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||||
"Please login first": "Please login first",
|
"The provider: %s is not found": "The provider: %s is not found"
|
||||||
"The provider: %s is not found": "The provider: %s is not found",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||||
"Email is invalid": "Email is invalid",
|
"Email is invalid": "Email is invalid",
|
||||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||||
"Missing parameter": "Missing parameter",
|
|
||||||
"Organization does not exist": "Organization does not exist",
|
"Organization does not exist": "Organization does not exist",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||||
@ -165,8 +141,6 @@
|
|||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "Found no credentials for this user",
|
"Found no credentials for this user": "Found no credentials for this user",
|
||||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first",
|
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,31 +4,25 @@
|
|||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||||
"Invalid information": "Invalid information",
|
"Invalid information": "Invalid information",
|
||||||
"Phone: %s": "Phone: %s",
|
"Phone: %s": "Phone: %s",
|
||||||
|
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||||
},
|
},
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Parameter organization is missing",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s No phone prefix",
|
"%s No phone prefix": "%s No phone prefix",
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
"Challenge method should be S256": "Challenge method should be S256",
|
||||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||||
"Failed to login in: %s": "Failed to login in: %s",
|
"Failed to login in: %s": "Failed to login in: %s",
|
||||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
|
||||||
"Invalid token": "Invalid token",
|
"Invalid token": "Invalid token",
|
||||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
|
||||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||||
"The account does not exist": "The account does not exist",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||||
"The application: %s does not exist": "The application: %s does not exist",
|
"The application: %s does not exist": "The application: %s does not exist",
|
||||||
|
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
"The provider type: %s is not supported": "The provider type: %s is not supported",
|
||||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unauthorized operation": "Unauthorized operation",
|
"Unauthorized operation": "Unauthorized operation",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||||
@ -53,11 +47,8 @@
|
|||||||
"Phone already exists": "Phone already exists",
|
"Phone already exists": "Phone already exists",
|
||||||
"Phone cannot be empty": "Phone cannot be empty",
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Session outdated, please login again": "Session outdated, please login again",
|
"Session outdated, please login again": "Session outdated, please login again",
|
||||||
"The user doesn't exist": "The user doesn't exist",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||||
"Username already exists": "Username already exists",
|
"Username already exists": "Username already exists",
|
||||||
"Username cannot be an email address": "Username cannot be an email address",
|
"Username cannot be an email address": "Username cannot be an email address",
|
||||||
@ -65,20 +56,17 @@
|
|||||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||||
"You don't have the permission to do this": "You don't have the permission to do this",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again",
|
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||||
"unsupported password type: %s": "unsupported password type: %s"
|
"unsupported password type: %s": "unsupported password type: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "You have entered the wrong password too many times, please wait for %d minutes and try again",
|
"Missing parameter": "Missing parameter",
|
||||||
"password is incorrect, you have %d remaining chances": "password is incorrect, you have %d remaining chances"
|
"Please login first": "Please login first",
|
||||||
},
|
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "Please sign in first"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap server exist",
|
"Ldap server exist": "Ldap server exist"
|
||||||
"Missing parameter": "Missing parameter"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "Please link first",
|
"Please link first": "Please link first",
|
||||||
@ -93,10 +81,6 @@
|
|||||||
"The %s is immutable.": "The %s is immutable.",
|
"The %s is immutable.": "The %s is immutable.",
|
||||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||||
},
|
},
|
||||||
"product": {
|
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "Invalid application id",
|
"Invalid application id": "Invalid application id",
|
||||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||||
@ -120,22 +104,18 @@
|
|||||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||||
},
|
},
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "You are not authorized to access this resource"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge method should be S256",
|
|
||||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||||
"Invalid client_id": "Invalid client_id",
|
"Invalid client_id": "Invalid client_id",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||||
|
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "Display name cannot be empty",
|
"Display name cannot be empty": "Display name cannot be empty",
|
||||||
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
"New password cannot contain blank space.": "New password cannot contain blank space.",
|
||||||
"New password must have at least 6 characters": "New password must have at least 6 characters",
|
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "Failed to import users"
|
"Failed to import users": "Failed to import users"
|
||||||
@ -143,18 +123,14 @@
|
|||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||||
"Please login first": "Please login first",
|
"The provider: %s is not found": "The provider: %s is not found"
|
||||||
"The provider: %s is not found": "The provider: %s is not found",
|
|
||||||
"The user: %s doesn't exist": "The user: %s doesn't exist"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||||
"Email is invalid": "Email is invalid",
|
"Email is invalid": "Email is invalid",
|
||||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||||
"Missing parameter": "Missing parameter",
|
|
||||||
"Organization does not exist": "Organization does not exist",
|
"Organization does not exist": "Organization does not exist",
|
||||||
"Phone number is invalid": "Phone number is invalid",
|
"Phone number is invalid": "Phone number is invalid",
|
||||||
"Please login first": "Please login first",
|
|
||||||
"Turing test failed.": "Turing test failed.",
|
"Turing test failed.": "Turing test failed.",
|
||||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||||
@ -165,8 +141,6 @@
|
|||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "Found no credentials for this user",
|
"Found no credentials for this user": "Found no credentials for this user",
|
||||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first",
|
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||||
"Please login first": "Please login first",
|
|
||||||
"The user: %s/%s doesn't exist": "The user: %s/%s doesn't exist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,170 +3,144 @@
|
|||||||
"Email: %s": "邮件: %s",
|
"Email: %s": "邮件: %s",
|
||||||
"Get init score failed, error: %w": "初始化分数失败: %w",
|
"Get init score failed, error: %w": "初始化分数失败: %w",
|
||||||
"Invalid information": "无效信息",
|
"Invalid information": "无效信息",
|
||||||
"Phone: %s": "电话: %s",
|
"Phone: %s": "手机号: %s",
|
||||||
"Please sign out first before signing up": "请在登陆前登出",
|
"Please sign out first before signing in": "请在登录前先退出登录",
|
||||||
"The application does not allow to sign up new account": "该应用不允许注册新账户"
|
"Please sign out first before signing up": "请在注册前先退出登录",
|
||||||
},
|
"The application does not allow to sign up new account": "该应用不允许注册新用户"
|
||||||
"application": {
|
|
||||||
"Parameter organization is missing": "Organization参数丢失",
|
|
||||||
"The user: %s doesn't exist": "用户不存在: %s"
|
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"%s No phone prefix": "%s 无此电话前缀",
|
"%s No phone prefix": "%s 无此手机号前缀",
|
||||||
"Challenge method should be S256": "Challenge 方法应该为 S256",
|
"Challenge method should be S256": "Challenge 方法应该为 S256",
|
||||||
"Failed to create user, user information is invalid: %s": "创建用户失败,用户信息无效: %s",
|
"Failed to create user, user information is invalid: %s": "创建用户失败,用户信息无效: %s",
|
||||||
"Failed to login in: %s": "无法登录: %s",
|
"Failed to login in: %s": "登录失败: %s",
|
||||||
"Get init score failed, error: %w": "初始化分数失败: %w",
|
|
||||||
"Invalid token": "无效token",
|
"Invalid token": "无效token",
|
||||||
"Please sign out first before signing in": "请在登陆前登出",
|
"State expected: %s, but got: %s": "期望状态为: %s, 实际状态为: %s",
|
||||||
"State expected: %s, but got: %s": "期望状态位: %s, 实际状态为: %s",
|
|
||||||
"The account does not exist": "账户不存在",
|
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许通过 %s 注册新账户, 请使用其他方式注册",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许通过 %s 注册新账户, 请使用其他方式注册",
|
||||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许注册新账户, 请联系IT支持",
|
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许注册新账户, 请联系IT支持",
|
||||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "提供商账户: %s 与用户名: %s (%s) 已经与其他账户绑定: %s (%s)",
|
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "提供商账户: %s 与用户名: %s (%s) 已经与其他账户绑定: %s (%s)",
|
||||||
"The application: %s does not exist": "应用 %s 不存在",
|
"The application: %s does not exist": "应用 %s 不存在",
|
||||||
|
"The login method: login with password is not enabled for the application": "该应用禁止采用密码登录方式",
|
||||||
"The provider type: %s is not supported": "不支持该类型的提供商: %s",
|
"The provider type: %s is not supported": "不支持该类型的提供商: %s",
|
||||||
"The provider: %s is not enabled for the application": "提供商: %s 未被启用",
|
"The provider: %s is not enabled for the application": "该应用的提供商: %s 未被启用",
|
||||||
"The user is forbidden to sign in, please contact the administrator": "该用户被禁止登陆,请联系管理员",
|
"The user is forbidden to sign in, please contact the administrator": "该用户被禁止登录,请联系管理员",
|
||||||
"The user: %s/%s doesn't exist": "用户不存在: %s/%s",
|
"Turing test failed.": "人机验证失败",
|
||||||
"Turing test failed.": "真人验证失败",
|
|
||||||
"Unauthorized operation": "未授权的操作",
|
"Unauthorized operation": "未授权的操作",
|
||||||
"Unknown authentication type (not password or provider), form = %s": "未授权的操作"
|
"Unknown authentication type (not password or provider), form = %s": "未知的认证类型(非密码或第三方提供商):%s"
|
||||||
},
|
},
|
||||||
"cas": {
|
"cas": {
|
||||||
"Service %s and %s do not match": "服务 %s 与 %s 不匹配"
|
"Service %s and %s do not match": "服务 %s 与 %s 不匹配"
|
||||||
},
|
},
|
||||||
"check": {
|
"check": {
|
||||||
"Affiliation cannot be blank": "联系方式不可为空",
|
"Affiliation cannot be blank": "工作单位不可为空",
|
||||||
"DisplayName cannot be blank": "展示名称不可为空",
|
"DisplayName cannot be blank": "显示名称不可为空",
|
||||||
"DisplayName is not valid real name": "展示名称无效",
|
"DisplayName is not valid real name": "显示名称必须是真实姓名",
|
||||||
"Email already exists": "该邮箱已存在",
|
"Email already exists": "该邮箱已存在",
|
||||||
"Email cannot be empty": "邮箱不可为空",
|
"Email cannot be empty": "邮箱不可为空",
|
||||||
"Email is invalid": "无效邮箱",
|
"Email is invalid": "无效邮箱",
|
||||||
"Empty username.": "用户名不可为空",
|
"Empty username.": "用户名不可为空",
|
||||||
"FirstName cannot be blank": "名不可以为空",
|
"FirstName cannot be blank": "名不可以为空",
|
||||||
"LastName cannot be blank": "姓不可以为空",
|
"LastName cannot be blank": "姓不可以为空",
|
||||||
"Ldap user name or password incorrect": "Ldap密码错误",
|
"Ldap user name or password incorrect": "LDAP密码错误",
|
||||||
"Multiple accounts with same uid, please check your ldap server": "多个帐户具有相同的uid,请检查您的 ldap 服务器",
|
"Multiple accounts with same uid, please check your ldap server": "多个帐户具有相同的uid,请检查您的 LDAP 服务器",
|
||||||
"Organization does not exist": "组织不存在",
|
"Organization does not exist": "组织不存在",
|
||||||
"Password must have at least 6 characters": "新密码至少为6位",
|
"Password must have at least 6 characters": "新密码至少为6位",
|
||||||
"Phone already exists": "该电话已存在",
|
"Phone already exists": "该手机号已存在",
|
||||||
"Phone cannot be empty": "电话不可为空",
|
"Phone cannot be empty": "手机号不可为空",
|
||||||
"Phone number is invalid": "无效电话",
|
"Phone number is invalid": "无效手机号",
|
||||||
"Please login first": "请先登录",
|
"Session outdated, please login again": "会话已过期,请重新登录",
|
||||||
"Session outdated, please login again": "Session已过期,请重新登陆",
|
"The user is forbidden to sign in, please contact the administrator": "该用户被禁止登录,请联系管理员",
|
||||||
"The user doesn't exist": "用户不存在",
|
|
||||||
"The user is forbidden to sign in, please contact the administrator": "该用户被禁止登陆,请联系管理员",
|
|
||||||
"The user: %s doesn't exist": "用户不存在: %s",
|
|
||||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "用户名只能包含字母数字字符、下划线或连字符,不能有连续的连字符或下划线,也不能以连字符或下划线开头或结尾",
|
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "用户名只能包含字母数字字符、下划线或连字符,不能有连续的连字符或下划线,也不能以连字符或下划线开头或结尾",
|
||||||
"Username already exists": "用户名已存在",
|
"Username already exists": "用户名已存在",
|
||||||
"Username cannot be an email address": "用户名不可以是邮箱地址",
|
"Username cannot be an email address": "用户名不可以是邮箱地址",
|
||||||
"Username cannot contain white spaces": "用户名不可以包含空格",
|
"Username cannot contain white spaces": "用户名禁止包含空格",
|
||||||
"Username cannot start with a digit": "用户名禁止使用数字作为第一个字符",
|
"Username cannot start with a digit": "用户名禁止使用数字开头",
|
||||||
"Username is too long (maximum is 39 characters).": "用户名过长(最大长度为39个字符)",
|
"Username is too long (maximum is 39 characters).": "用户名过长(最大允许长度为39个字符)",
|
||||||
"Username must have at least 2 characters": "用户名至少要有2个字符",
|
"Username must have at least 2 characters": "用户名至少要有2个字符",
|
||||||
"You don't have the permission to do this": "用户名至少要有2个字符",
|
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "密码错误次数已达上限,请在 %d 分后重试",
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again": "输入密码错误次数已达上限,请在 %d 分 %d 秒后重试",
|
"password or code is incorrect, you have %d remaining chances": "密码错误,您还有 %d 次尝试的机会",
|
||||||
"unsupported password type: %s": "不支持的密码类型: %s"
|
"unsupported password type: %s": "不支持的密码类型: %s"
|
||||||
},
|
},
|
||||||
"check_util": {
|
"general": {
|
||||||
"You have entered the wrong password too many times, please wait for %d minutes and try again": "输入密码错误次数已达上限,请在 %d 分后重试",
|
"Missing parameter": "缺少参数",
|
||||||
"password is incorrect, you have %d remaining chances": "密码错误,您还有 %d 次尝试的机会"
|
"Please login first": "请先登录",
|
||||||
},
|
"The user: %s doesn't exist": "用户: %s 不存在"
|
||||||
"enforcer": {
|
|
||||||
"Please sign in first": "请先登录"
|
|
||||||
},
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"Ldap server exist": "Ldap服务器已存在",
|
"Ldap server exist": "LDAP服务器已存在"
|
||||||
"Missing parameter": "参数丢失"
|
|
||||||
},
|
},
|
||||||
"link": {
|
"link": {
|
||||||
"Please link first": "请先绑定",
|
"Please link first": "请先绑定",
|
||||||
"This application has no providers": "该应用无提供商",
|
"This application has no providers": "该应用无可用的提供商",
|
||||||
"This application has no providers of type": "应用没有该类型的提供商",
|
"This application has no providers of type": "应用没有该类型的提供商",
|
||||||
"This provider can't be unlinked": "该提供商不可被链接",
|
"This provider can't be unlinked": "该提供商被禁止解绑",
|
||||||
"You are not the global admin, you can't unlink other users": "您不是全局管理员,无法取消链接其他用户",
|
"You are not the global admin, you can't unlink other users": "您不是全局管理员,无法解绑其他用户",
|
||||||
"You can't unlink yourself, you are not a member of any application": "您无法取消链接,您不是任何应用程序的成员"
|
"You can't unlink yourself, you are not a member of any application": "您无法自行解绑,您不是任何应用程序的成员"
|
||||||
},
|
},
|
||||||
"organization": {
|
"organization": {
|
||||||
"Only admin can modify the %s.": "您无法取消链接,您不是任何应用程序的成员",
|
"Only admin can modify the %s.": "仅允许管理员可以修改 %s",
|
||||||
"The %s is immutable.": "%s是不可变的",
|
"The %s is immutable.": "%s 是不可变的",
|
||||||
"Unknown modify rule %s.": "未知的修改规则"
|
"Unknown modify rule %s.": "未知的修改规则: %s"
|
||||||
},
|
|
||||||
"product": {
|
|
||||||
"Please login first": "请先登录",
|
|
||||||
"The user: %s doesn't exist": "用户不存在: %s"
|
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
"Invalid application id": "无效的Application ID",
|
"Invalid application id": "无效的应用ID",
|
||||||
"the provider: %s does not exist": "提供商: %s 不存在"
|
"the provider: %s does not exist": "提供商: %s 不存在"
|
||||||
},
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"User is nil for tag: avatar": "用户头像标签为空",
|
"User is nil for tag: avatar": "上传头像时用户为空",
|
||||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "username或FilePath为空: username = %s, fullFilePath = %s"
|
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "username或fullFilePath为空: username = %s, fullFilePath = %s"
|
||||||
},
|
},
|
||||||
"saml": {
|
"saml": {
|
||||||
"Application %s not found": "应用 %s 未找到"
|
"Application %s not found": "未找到应用: %s"
|
||||||
},
|
},
|
||||||
"saml_sp": {
|
"saml_sp": {
|
||||||
"provider %s's category is not SAML": "提供商 %s类型不是SAML"
|
"provider %s's category is not SAML": "提供商: %s 不是SAML类型"
|
||||||
},
|
},
|
||||||
"service": {
|
"service": {
|
||||||
"Empty parameters for emailForm: %v": "邮件参数为空: %v",
|
"Empty parameters for emailForm: %v": "邮件参数为空: %v",
|
||||||
"Invalid Email receivers: %s": " 无效的邮箱接收者: %s",
|
"Invalid Email receivers: %s": " 无效的邮箱收件人: %s",
|
||||||
"Invalid phone receivers: %s": "无效的电话接收者: %s"
|
"Invalid phone receivers: %s": "无效的手机短信收信人: %s"
|
||||||
},
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"The objectKey: %s is not allowed": "object key :%s 不被允许",
|
"The objectKey: %s is not allowed": "objectKey: %s 被禁止",
|
||||||
"The provider type: %s is not supported": "提供商类型: %s 尚未支持"
|
"The provider type: %s is not supported": "不支持的提供商类型: %s"
|
||||||
},
|
|
||||||
"system_info": {
|
|
||||||
"You are not authorized to access this resource": "您无权获取此资源"
|
|
||||||
},
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"Challenge method should be S256": "Challenge 方法应该为 S256",
|
|
||||||
"Empty clientId or clientSecret": "clientId或clientSecret为空",
|
"Empty clientId or clientSecret": "clientId或clientSecret为空",
|
||||||
"Grant_type: %s is not supported in this application": "此应用中不支持此授权类型: %s",
|
"Grant_type: %s is not supported in this application": "该应用不支持Grant_type: %s",
|
||||||
"Invalid application or wrong clientSecret": "无效应用或错误的clientSecret",
|
"Invalid application or wrong clientSecret": "无效应用或错误的clientSecret",
|
||||||
"Invalid client_id": "无效的ClientId",
|
"Invalid client_id": "无效的ClientId",
|
||||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "重定向 URI:%s 在可列表中未找到"
|
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "重定向 URI:%s 在许可跳转列表中未找到",
|
||||||
|
"Token not found, invalid accessToken": "未查询到对应token, accessToken无效"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"Display name cannot be empty": "展示名称不可为空",
|
"Display name cannot be empty": "显示名称不可为空",
|
||||||
"New password cannot contain blank space.": "新密码不可以包含空格",
|
"New password cannot contain blank space.": "新密码不可以包含空格",
|
||||||
"New password must have at least 6 characters": "新密码至少需要6位字符",
|
"New password must have at least 6 characters": "新密码至少需要6位字符"
|
||||||
"The user: %s/%s doesn't exist": "用户不存在: %s/%s"
|
|
||||||
},
|
},
|
||||||
"user_upload": {
|
"user_upload": {
|
||||||
"Failed to import users": "导入用户失败"
|
"Failed to import users": "导入用户失败"
|
||||||
},
|
},
|
||||||
"util": {
|
"util": {
|
||||||
"No application is found for userId: %s": "找不到该用户的应用程序 %s",
|
"No application is found for userId: %s": "未找到用户: %s 的应用",
|
||||||
"No provider for category: %s is found for application: %s": "找不到该用户的应用程序 %s",
|
"No provider for category: %s is found for application: %s": "未找到类别为: %s 的提供商来满足应用: %s",
|
||||||
"Please login first": "请先登录",
|
"The provider: %s is not found": "未找到提供商: %s"
|
||||||
"The provider: %s is not found": "该提供商未找到: %s",
|
|
||||||
"The user: %s doesn't exist": "用户不存在: %s"
|
|
||||||
},
|
},
|
||||||
"verification": {
|
"verification": {
|
||||||
"Code has not been sent yet!": "验证码还未发送",
|
"Code has not been sent yet!": "验证码还未发送",
|
||||||
"Email is invalid": "非法的邮箱",
|
"Email is invalid": "非法的邮箱",
|
||||||
"Invalid captcha provider.": "非法的验证码提供商",
|
"Invalid captcha provider.": "非法的验证码提供商",
|
||||||
"Missing parameter": "参数丢失",
|
|
||||||
"Organization does not exist": "组织不存在",
|
"Organization does not exist": "组织不存在",
|
||||||
"Phone number is invalid": "非法的电话号码",
|
"Phone number is invalid": "非法的手机号码",
|
||||||
"Please login first": "请先登录",
|
|
||||||
"Turing test failed.": "验证码还未发送",
|
"Turing test failed.": "验证码还未发送",
|
||||||
"Unable to get the email modify rule.": "无法得到邮箱修改规则",
|
"Unable to get the email modify rule.": "无法获取邮箱修改规则",
|
||||||
"Unable to get the phone modify rule.": "无法得到电话修改规则",
|
"Unable to get the phone modify rule.": "无法获取手机号修改规则",
|
||||||
"Unknown type": "未知类型",
|
"Unknown type": "未知类型",
|
||||||
"Wrong parameter": "参数错误",
|
"Wrong parameter": "参数错误",
|
||||||
"You should verify your code in %d min!": "请在 %d 分钟内输入正确验证码",
|
"You should verify your code in %d min!": "请在 %d 分钟内输入正确验证码",
|
||||||
"the user does not exist, please sign up first": "用户不存在,请先注册"
|
"the user does not exist, please sign up first": "用户不存在,请先注册"
|
||||||
},
|
},
|
||||||
"webauthn": {
|
"webauthn": {
|
||||||
"Found no credentials for this user": "该用户没有WebAuthn凭据",
|
"Found no credentials for this user": "该用户没有 WebAuthn 凭据",
|
||||||
"Please call WebAuthnSigninBegin first": "请先调用 WebAuthnSigninBegi",
|
"Please call WebAuthnSigninBegin first": "请先调用 WebAuthnSigninBegin"
|
||||||
"Please login first": "请先登录",
|
|
||||||
"The user: %s/%s doesn't exist": "用户: %s/%s 不存在"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
i18n/util.go
14
i18n/util.go
@ -27,18 +27,16 @@ var f embed.FS
|
|||||||
|
|
||||||
var langMap = make(map[string]map[string]map[string]string) // for example : langMap[en][account][Invalid information] = Invalid information
|
var langMap = make(map[string]map[string]map[string]string) // for example : langMap[en][account][Invalid information] = Invalid information
|
||||||
|
|
||||||
func getI18nFilePath(language string) string {
|
func getI18nFilePath(category string, language string) string {
|
||||||
if strings.Contains(language, "backend") {
|
if category == "backend" {
|
||||||
// change language from 'backend_en' to 'en'
|
|
||||||
language = language[8:]
|
|
||||||
return fmt.Sprintf("../i18n/locales/%s/data.json", language)
|
return fmt.Sprintf("../i18n/locales/%s/data.json", language)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("../web/src/locales/%s/data.json", language)
|
return fmt.Sprintf("../web/src/locales/%s/data.json", language)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readI18nFile(language string) *I18nData {
|
func readI18nFile(category string, language string) *I18nData {
|
||||||
s := util.ReadStringFromPath(getI18nFilePath(language))
|
s := util.ReadStringFromPath(getI18nFilePath(category, language))
|
||||||
|
|
||||||
data := &I18nData{}
|
data := &I18nData{}
|
||||||
err := util.JsonToStruct(s, data)
|
err := util.JsonToStruct(s, data)
|
||||||
@ -48,13 +46,13 @@ func readI18nFile(language string) *I18nData {
|
|||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeI18nFile(language string, data *I18nData) {
|
func writeI18nFile(category string, language string, data *I18nData) {
|
||||||
s := util.StructToJsonFormatted(data)
|
s := util.StructToJsonFormatted(data)
|
||||||
s = strings.ReplaceAll(s, "\\u0026", "&")
|
s = strings.ReplaceAll(s, "\\u0026", "&")
|
||||||
s += "\n"
|
s += "\n"
|
||||||
println(s)
|
println(s)
|
||||||
|
|
||||||
util.WriteStringToPath(s, getI18nFilePath(language))
|
util.WriteStringToPath(s, getI18nFilePath(category, language))
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyData(data1 *I18nData, data2 *I18nData) {
|
func applyData(data1 *I18nData, data2 *I18nData) {
|
||||||
|
@ -25,10 +25,10 @@ import (
|
|||||||
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
||||||
_ "github.com/go-sql-driver/mysql" // db = mysql
|
_ "github.com/go-sql-driver/mysql" // db = mysql
|
||||||
_ "github.com/lib/pq" // db = postgres
|
_ "github.com/lib/pq" // db = postgres
|
||||||
"xorm.io/xorm/migrate"
|
_ "modernc.org/sqlite" // db = sqlite
|
||||||
//_ "github.com/mattn/go-sqlite3" // db = sqlite3
|
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
"xorm.io/xorm/migrate"
|
||||||
)
|
)
|
||||||
|
|
||||||
var adapter *Adapter
|
var adapter *Adapter
|
||||||
@ -222,6 +222,11 @@ func (a *Adapter) createTable() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = a.Engine.Sync2(new(Session))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
|
func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
|
||||||
|
@ -50,6 +50,7 @@ type Application struct {
|
|||||||
EnableCodeSignin bool `json:"enableCodeSignin"`
|
EnableCodeSignin bool `json:"enableCodeSignin"`
|
||||||
EnableSamlCompress bool `json:"enableSamlCompress"`
|
EnableSamlCompress bool `json:"enableSamlCompress"`
|
||||||
EnableWebAuthn bool `json:"enableWebAuthn"`
|
EnableWebAuthn bool `json:"enableWebAuthn"`
|
||||||
|
EnableLinkWithEmail bool `json:"enableLinkWithEmail"`
|
||||||
SamlReplyUrl string `xorm:"varchar(100)" json:"samlReplyUrl"`
|
SamlReplyUrl string `xorm:"varchar(100)" json:"samlReplyUrl"`
|
||||||
Providers []*ProviderItem `xorm:"mediumtext" json:"providers"`
|
Providers []*ProviderItem `xorm:"mediumtext" json:"providers"`
|
||||||
SignupItems []*SignupItem `xorm:"varchar(1000)" json:"signupItems"`
|
SignupItems []*SignupItem `xorm:"varchar(1000)" json:"signupItems"`
|
||||||
@ -286,7 +287,8 @@ func GetMaskedApplications(applications []*Application, userId string) []*Applic
|
|||||||
|
|
||||||
func UpdateApplication(id string, application *Application) bool {
|
func UpdateApplication(id string, application *Application) bool {
|
||||||
owner, name := util.GetOwnerAndNameFromId(id)
|
owner, name := util.GetOwnerAndNameFromId(id)
|
||||||
if getApplication(owner, name) == nil {
|
oldApplication := getApplication(owner, name)
|
||||||
|
if oldApplication == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +303,10 @@ func UpdateApplication(id string, application *Application) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if oldApplication.ClientId != application.ClientId && GetApplicationByClientId(application.ClientId) != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
for _, providerItem := range application.Providers {
|
for _, providerItem := range application.Providers {
|
||||||
providerItem.Provider = nil
|
providerItem.Provider = nil
|
||||||
}
|
}
|
||||||
@ -324,6 +330,9 @@ func AddApplication(application *Application) bool {
|
|||||||
if application.ClientSecret == "" {
|
if application.ClientSecret == "" {
|
||||||
application.ClientSecret = util.GenerateClientSecret()
|
application.ClientSecret = util.GenerateClientSecret()
|
||||||
}
|
}
|
||||||
|
if GetApplicationByClientId(application.ClientId) != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
for _, providerItem := range application.Providers {
|
for _, providerItem := range application.Providers {
|
||||||
providerItem.Provider = nil
|
providerItem.Provider = nil
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,8 @@ func CheckUserSignup(application *Application, organization *Organization, usern
|
|||||||
if reWhiteSpace.MatchString(username) {
|
if reWhiteSpace.MatchString(username) {
|
||||||
return i18n.Translate(lang, "check:Username cannot contain white spaces")
|
return i18n.Translate(lang, "check:Username cannot contain white spaces")
|
||||||
}
|
}
|
||||||
msg := CheckUsername(username, lang)
|
|
||||||
if msg != "" {
|
if msg := CheckUsername(username, lang); msg != "" {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,11 +143,11 @@ func checkSigninErrorTimes(user *User, lang string) string {
|
|||||||
if user.SigninWrongTimes >= SigninWrongTimesLimit {
|
if user.SigninWrongTimes >= SigninWrongTimesLimit {
|
||||||
lastSignWrongTime, _ := time.Parse(time.RFC3339, user.LastSigninWrongTime)
|
lastSignWrongTime, _ := time.Parse(time.RFC3339, user.LastSigninWrongTime)
|
||||||
passedTime := time.Now().UTC().Sub(lastSignWrongTime)
|
passedTime := time.Now().UTC().Sub(lastSignWrongTime)
|
||||||
seconds := int(LastSignWrongTimeDuration.Seconds() - passedTime.Seconds())
|
minutes := int(LastSignWrongTimeDuration.Minutes() - passedTime.Minutes())
|
||||||
|
|
||||||
// deny the login if the error times is greater than the limit and the last login time is less than the duration
|
// deny the login if the error times is greater than the limit and the last login time is less than the duration
|
||||||
if seconds > 0 {
|
if minutes > 0 {
|
||||||
return fmt.Sprintf(i18n.Translate(lang, "check:You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again"), seconds/60, seconds%60)
|
return fmt.Sprintf(i18n.Translate(lang, "check:You have entered the wrong password or code too many times, please wait for %d minutes and try again"), minutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the error times
|
// reset the error times
|
||||||
@ -229,7 +229,7 @@ func checkLdapUserPassword(user *User, password string, lang string) (*User, str
|
|||||||
func CheckUserPassword(organization string, username string, password string, lang string) (*User, string) {
|
func CheckUserPassword(organization string, username string, password string, lang string) (*User, string) {
|
||||||
user := GetUserByFields(organization, username)
|
user := GetUserByFields(organization, username)
|
||||||
if user == nil || user.IsDeleted == true {
|
if user == nil || user.IsDeleted == true {
|
||||||
return nil, i18n.Translate(lang, "check:The user doesn't exist")
|
return nil, fmt.Sprintf(i18n.Translate(lang, "general:The user: %s doesn't exist"), util.GetId(organization, username))
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.IsForbidden {
|
if user.IsForbidden {
|
||||||
@ -254,13 +254,13 @@ func filterField(field string) bool {
|
|||||||
|
|
||||||
func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, lang string) (bool, error) {
|
func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, lang string) (bool, error) {
|
||||||
if requestUserId == "" {
|
if requestUserId == "" {
|
||||||
return false, fmt.Errorf(i18n.Translate(lang, "check:Please login first"))
|
return false, fmt.Errorf(i18n.Translate(lang, "general:Please login first"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if userId != "" {
|
if userId != "" {
|
||||||
targetUser := GetUser(userId)
|
targetUser := GetUser(userId)
|
||||||
if targetUser == nil {
|
if targetUser == nil {
|
||||||
return false, fmt.Errorf(i18n.Translate(lang, "check:The user: %s doesn't exist"), userId)
|
return false, fmt.Errorf(i18n.Translate(lang, "general:The user: %s doesn't exist"), userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
userOwner = targetUser.Owner
|
userOwner = targetUser.Owner
|
||||||
@ -287,7 +287,7 @@ func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasPermission, fmt.Errorf(i18n.Translate(lang, "check:You don't have the permission to do this"))
|
return hasPermission, fmt.Errorf(i18n.Translate(lang, "auth:Unauthorized operation"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAccessPermission(userId string, application *Application) (bool, error) {
|
func CheckAccessPermission(userId string, application *Application) (bool, error) {
|
||||||
@ -342,6 +342,33 @@ func CheckUsername(username string, lang string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckUpdateUser(oldUser *User, user *User, lang string) string {
|
||||||
|
if user.DisplayName == "" {
|
||||||
|
return i18n.Translate(lang, "user:Display name cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.Name != user.Name {
|
||||||
|
if msg := CheckUsername(user.Name, lang); msg != "" {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
if HasUserByField(user.Owner, "name", user.Name) {
|
||||||
|
return i18n.Translate(lang, "check:Username already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if oldUser.Email != user.Email {
|
||||||
|
if HasUserByField(user.Name, "email", user.Email) {
|
||||||
|
return i18n.Translate(lang, "check:Email already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if oldUser.Phone != user.Phone {
|
||||||
|
if HasUserByField(user.Owner, "phone", user.Phone) {
|
||||||
|
return i18n.Translate(lang, "check:Phone already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func CheckToEnableCaptcha(application *Application) bool {
|
func CheckToEnableCaptcha(application *Application) bool {
|
||||||
if len(application.Providers) == 0 {
|
if len(application.Providers) == 0 {
|
||||||
return false
|
return false
|
||||||
|
@ -58,9 +58,9 @@ func recordSigninErrorInfo(user *User, lang string) string {
|
|||||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, user.IsGlobalAdmin)
|
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, user.IsGlobalAdmin)
|
||||||
leftChances := SigninWrongTimesLimit - user.SigninWrongTimes
|
leftChances := SigninWrongTimesLimit - user.SigninWrongTimes
|
||||||
if leftChances > 0 {
|
if leftChances > 0 {
|
||||||
return fmt.Sprintf(i18n.Translate(lang, "check_util:password is incorrect, you have %d remaining chances"), leftChances)
|
return fmt.Sprintf(i18n.Translate(lang, "check:password or code is incorrect, you have %d remaining chances"), leftChances)
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't show the chance error message if the user has no chance left
|
// don't show the chance error message if the user has no chance left
|
||||||
return fmt.Sprintf(i18n.Translate(lang, "check_util:You have entered the wrong password too many times, please wait for %d minutes and try again"), int(LastSignWrongTimeDuration.Minutes()))
|
return fmt.Sprintf(i18n.Translate(lang, "check:You have entered the wrong password or code too many times, please wait for %d minutes and try again"), int(LastSignWrongTimeDuration.Minutes()))
|
||||||
}
|
}
|
||||||
|
@ -68,14 +68,14 @@ func getModel(owner string, name string) *Model {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
model := Model{Owner: owner, Name: name}
|
m := Model{Owner: owner, Name: name}
|
||||||
existed, err := adapter.Engine.Get(&model)
|
existed, err := adapter.Engine.Get(&m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if existed {
|
if existed {
|
||||||
return &model
|
return &m
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -152,3 +152,7 @@ func modelChangeTrigger(oldName string, newName string) error {
|
|||||||
|
|
||||||
return session.Commit()
|
return session.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HasRoleDefinition(m model.Model) bool {
|
||||||
|
return m["g"] != nil
|
||||||
|
}
|
||||||
|
@ -40,6 +40,7 @@ type OidcDiscovery struct {
|
|||||||
ClaimsSupported []string `json:"claims_supported"`
|
ClaimsSupported []string `json:"claims_supported"`
|
||||||
RequestParameterSupported bool `json:"request_parameter_supported"`
|
RequestParameterSupported bool `json:"request_parameter_supported"`
|
||||||
RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported"`
|
RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported"`
|
||||||
|
EndSessionEndpoint string `json:"end_session_endpoint"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOriginFromHost(host string) (string, string) {
|
func getOriginFromHost(host string) (string, string) {
|
||||||
@ -76,7 +77,7 @@ func GetOidcDiscovery(host string) OidcDiscovery {
|
|||||||
JwksUri: fmt.Sprintf("%s/.well-known/jwks", originBackend),
|
JwksUri: fmt.Sprintf("%s/.well-known/jwks", originBackend),
|
||||||
IntrospectionEndpoint: fmt.Sprintf("%s/api/login/oauth/introspect", originBackend),
|
IntrospectionEndpoint: fmt.Sprintf("%s/api/login/oauth/introspect", originBackend),
|
||||||
ResponseTypesSupported: []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none"},
|
ResponseTypesSupported: []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none"},
|
||||||
ResponseModesSupported: []string{"login", "code", "link"},
|
ResponseModesSupported: []string{"query", "fragment", "login", "code", "link"},
|
||||||
GrantTypesSupported: []string{"password", "authorization_code"},
|
GrantTypesSupported: []string{"password", "authorization_code"},
|
||||||
SubjectTypesSupported: []string{"public"},
|
SubjectTypesSupported: []string{"public"},
|
||||||
IdTokenSigningAlgValuesSupported: []string{"RS256"},
|
IdTokenSigningAlgValuesSupported: []string{"RS256"},
|
||||||
@ -84,6 +85,7 @@ func GetOidcDiscovery(host string) OidcDiscovery {
|
|||||||
ClaimsSupported: []string{"iss", "ver", "sub", "aud", "iat", "exp", "id", "type", "displayName", "avatar", "permanentAvatar", "email", "phone", "location", "affiliation", "title", "homepage", "bio", "tag", "region", "language", "score", "ranking", "isOnline", "isAdmin", "isGlobalAdmin", "isForbidden", "signupApplication", "ldap"},
|
ClaimsSupported: []string{"iss", "ver", "sub", "aud", "iat", "exp", "id", "type", "displayName", "avatar", "permanentAvatar", "email", "phone", "location", "affiliation", "title", "homepage", "bio", "tag", "region", "language", "score", "ranking", "isOnline", "isAdmin", "isGlobalAdmin", "isForbidden", "signupApplication", "ldap"},
|
||||||
RequestParameterSupported: true,
|
RequestParameterSupported: true,
|
||||||
RequestObjectSigningAlgValuesSupported: []string{"HS256", "HS384", "HS512"},
|
RequestObjectSigningAlgValuesSupported: []string{"HS256", "HS384", "HS512"},
|
||||||
|
EndSessionEndpoint: fmt.Sprintf("%s/api/logout", originBackend),
|
||||||
}
|
}
|
||||||
|
|
||||||
return oidcDiscovery
|
return oidcDiscovery
|
||||||
|
@ -204,7 +204,7 @@ func GetAccountItemByName(name string, organization *Organization) *AccountItem
|
|||||||
func CheckAccountItemModifyRule(accountItem *AccountItem, user *User, lang string) (bool, string) {
|
func CheckAccountItemModifyRule(accountItem *AccountItem, user *User, lang string) (bool, string) {
|
||||||
switch accountItem.ModifyRule {
|
switch accountItem.ModifyRule {
|
||||||
case "Admin":
|
case "Admin":
|
||||||
if !(user.IsAdmin || user.IsGlobalAdmin) {
|
if user == nil || !user.IsAdmin && !user.IsGlobalAdmin {
|
||||||
return false, fmt.Sprintf(i18n.Translate(lang, "organization:Only admin can modify the %s."), accountItem.Name)
|
return false, fmt.Sprintf(i18n.Translate(lang, "organization:Only admin can modify the %s."), accountItem.Name)
|
||||||
}
|
}
|
||||||
case "Immutable":
|
case "Immutable":
|
||||||
|
@ -57,6 +57,40 @@ type PermissionRule struct {
|
|||||||
Id string `xorm:"varchar(100) index not null default ''" json:"id"`
|
Id string `xorm:"varchar(100) index not null default ''" json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
builtInAvailableField = 5 // Casdoor built-in adapter, use V5 to filter permission, so has 5 available field
|
||||||
|
builtInAdapter = "permission_rule"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Permission) GetId() string {
|
||||||
|
return util.GetId(p.Owner, p.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PermissionRule) GetRequest(adapterName string, permissionId string) ([]interface{}, error) {
|
||||||
|
request := []interface{}{p.V0, p.V1, p.V2}
|
||||||
|
|
||||||
|
if p.V3 != "" {
|
||||||
|
request = append(request, p.V3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.V4 != "" {
|
||||||
|
request = append(request, p.V4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if adapterName == builtInAdapter {
|
||||||
|
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 != "" {
|
||||||
|
request = append(request, p.V5)
|
||||||
|
}
|
||||||
|
return request, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func GetPermissionCount(owner, field, value string) int {
|
func GetPermissionCount(owner, field, value string) int {
|
||||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||||
count, err := session.Count(&Permission{})
|
count, err := session.Count(&Permission{})
|
||||||
@ -115,19 +149,25 @@ func GetPermission(id string) *Permission {
|
|||||||
func checkPermissionValid(permission *Permission) {
|
func checkPermissionValid(permission *Permission) {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getEnforcer(permission)
|
||||||
enforcer.EnableAutoSave(false)
|
enforcer.EnableAutoSave(false)
|
||||||
policies, groupingPolicies := getPolicies(permission)
|
|
||||||
|
|
||||||
|
policies := getPolicies(permission)
|
||||||
|
_, err := enforcer.AddPolicies(policies)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !HasRoleDefinition(enforcer.GetModel()) {
|
||||||
|
permission.Roles = []string{}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
groupingPolicies := getGroupingPolicies(permission)
|
||||||
if len(groupingPolicies) > 0 {
|
if len(groupingPolicies) > 0 {
|
||||||
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
|
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := enforcer.AddPolicies(policies)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdatePermission(id string, permission *Permission) bool {
|
func UpdatePermission(id string, permission *Permission) bool {
|
||||||
@ -144,6 +184,7 @@ func UpdatePermission(id string, permission *Permission) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if affected != 0 {
|
if affected != 0 {
|
||||||
|
removeGroupingPolicies(oldPermission)
|
||||||
removePolicies(oldPermission)
|
removePolicies(oldPermission)
|
||||||
if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
|
if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
|
||||||
isEmpty, _ := adapter.Engine.IsTableEmpty(oldPermission.Adapter)
|
isEmpty, _ := adapter.Engine.IsTableEmpty(oldPermission.Adapter)
|
||||||
@ -154,6 +195,7 @@ func UpdatePermission(id string, permission *Permission) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addGroupingPolicies(permission)
|
||||||
addPolicies(permission)
|
addPolicies(permission)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +209,7 @@ func AddPermission(permission *Permission) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if affected != 0 {
|
if affected != 0 {
|
||||||
|
addGroupingPolicies(permission)
|
||||||
addPolicies(permission)
|
addPolicies(permission)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,6 +223,7 @@ func DeletePermission(permission *Permission) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if affected != 0 {
|
if affected != 0 {
|
||||||
|
removeGroupingPolicies(permission)
|
||||||
removePolicies(permission)
|
removePolicies(permission)
|
||||||
if permission.Adapter != "" && permission.Adapter != "permission_rule" {
|
if permission.Adapter != "" && permission.Adapter != "permission_rule" {
|
||||||
isEmpty, _ := adapter.Engine.IsTableEmpty(permission.Adapter)
|
isEmpty, _ := adapter.Engine.IsTableEmpty(permission.Adapter)
|
||||||
@ -195,10 +239,6 @@ func DeletePermission(permission *Permission) bool {
|
|||||||
return affected != 0
|
return affected != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (permission *Permission) GetId() string {
|
|
||||||
return fmt.Sprintf("%s/%s", permission.Owner, permission.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPermissionsByUser(userId string) []*Permission {
|
func GetPermissionsByUser(userId string) []*Permission {
|
||||||
permissions := []*Permission{}
|
permissions := []*Permission{}
|
||||||
err := adapter.Engine.Where("users like ?", "%"+userId+"%").Find(&permissions)
|
err := adapter.Engine.Where("users like ?", "%"+userId+"%").Find(&permissions)
|
||||||
@ -269,3 +309,12 @@ func ContainsAsterisk(userId string, users []string) bool {
|
|||||||
|
|
||||||
return containsAsterisk
|
return containsAsterisk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetMaskedPermissions(permissions []*Permission) []*Permission {
|
||||||
|
for _, permission := range permissions {
|
||||||
|
permission.Users = nil
|
||||||
|
permission.Submitter = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions
|
||||||
|
}
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casbin/casbin/v2"
|
"github.com/casbin/casbin/v2"
|
||||||
|
"github.com/casbin/casbin/v2/config"
|
||||||
"github.com/casbin/casbin/v2/model"
|
"github.com/casbin/casbin/v2/model"
|
||||||
xormadapter "github.com/casbin/xorm-adapter/v3"
|
xormadapter "github.com/casbin/xorm-adapter/v3"
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
@ -36,47 +38,48 @@ func getEnforcer(permission *Permission) *casbin.Enforcer {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
modelText := `
|
|
||||||
[request_definition]
|
|
||||||
r = sub, obj, act
|
|
||||||
|
|
||||||
[policy_definition]
|
|
||||||
p = sub, obj, act, "", "", permissionId
|
|
||||||
|
|
||||||
[role_definition]
|
|
||||||
g = _, _
|
|
||||||
|
|
||||||
[policy_effect]
|
|
||||||
e = some(where (p.eft == allow))
|
|
||||||
|
|
||||||
[matchers]
|
|
||||||
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
|
|
||||||
permissionModel := getModel(permission.Owner, permission.Model)
|
permissionModel := getModel(permission.Owner, permission.Model)
|
||||||
|
m := model.Model{}
|
||||||
if permissionModel != nil {
|
if permissionModel != nil {
|
||||||
modelText = permissionModel.ModelText
|
m, err = GetBuiltInModel(permissionModel.ModelText)
|
||||||
|
} else {
|
||||||
|
m, err = GetBuiltInModel("")
|
||||||
}
|
}
|
||||||
m, err := model.NewModelFromString(modelText)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
policyFilter := xormadapter.Filter{}
|
||||||
|
|
||||||
|
if !HasRoleDefinition(m) {
|
||||||
|
policyFilter.Ptype = []string{"p"}
|
||||||
|
err = adapter.LoadFilteredPolicy(m, policyFilter)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enforcer, err := casbin.NewEnforcer(m, adapter)
|
enforcer, err := casbin.NewEnforcer(m, adapter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// load Policy with a specific Permission
|
// load Policy with a specific Permission
|
||||||
enforcer.LoadFilteredPolicy(xormadapter.Filter{
|
policyFilter.V5 = []string{permission.GetId()}
|
||||||
V5: []string{permission.Owner + "/" + permission.Name},
|
err = enforcer.LoadFilteredPolicy(policyFilter)
|
||||||
})
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return enforcer
|
return enforcer
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPolicies(permission *Permission) ([][]string, [][]string) {
|
func getPolicies(permission *Permission) [][]string {
|
||||||
var policies [][]string
|
var policies [][]string
|
||||||
var groupingPolicies [][]string
|
|
||||||
permissionId := permission.Owner + "/" + permission.Name
|
permissionId := permission.GetId()
|
||||||
domainExist := len(permission.Domains) > 0
|
domainExist := len(permission.Domains) > 0
|
||||||
|
|
||||||
for _, user := range permission.Users {
|
for _, user := range permission.Users {
|
||||||
for _, resource := range permission.Resources {
|
for _, resource := range permission.Resources {
|
||||||
for _, action := range permission.Actions {
|
for _, action := range permission.Actions {
|
||||||
@ -90,26 +93,8 @@ func getPolicies(permission *Permission) ([][]string, [][]string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, role := range permission.Roles {
|
for _, role := range permission.Roles {
|
||||||
roleObj := GetRole(role)
|
|
||||||
for _, subUser := range roleObj.Users {
|
|
||||||
if domainExist {
|
|
||||||
for _, domain := range permission.Domains {
|
|
||||||
groupingPolicies = append(groupingPolicies, []string{subUser, domain, role, "", "", permissionId})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
groupingPolicies = append(groupingPolicies, []string{subUser, role, "", "", "", permissionId})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, subRole := range roleObj.Roles {
|
|
||||||
if domainExist {
|
|
||||||
for _, domain := range permission.Domains {
|
|
||||||
groupingPolicies = append(groupingPolicies, []string{subRole, domain, role, "", "", permissionId})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
groupingPolicies = append(groupingPolicies, []string{subRole, role, "", "", "", permissionId})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, resource := range permission.Resources {
|
for _, resource := range permission.Resources {
|
||||||
for _, action := range permission.Actions {
|
for _, action := range permission.Actions {
|
||||||
if domainExist {
|
if domainExist {
|
||||||
@ -122,19 +107,49 @@ func getPolicies(permission *Permission) ([][]string, [][]string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return policies, groupingPolicies
|
|
||||||
|
return policies
|
||||||
|
}
|
||||||
|
|
||||||
|
func getGroupingPolicies(permission *Permission) [][]string {
|
||||||
|
var groupingPolicies [][]string
|
||||||
|
|
||||||
|
domainExist := len(permission.Domains) > 0
|
||||||
|
permissionId := permission.GetId()
|
||||||
|
|
||||||
|
for _, role := range permission.Roles {
|
||||||
|
roleObj := GetRole(role)
|
||||||
|
if roleObj == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, subUser := range roleObj.Users {
|
||||||
|
if domainExist {
|
||||||
|
for _, domain := range permission.Domains {
|
||||||
|
groupingPolicies = append(groupingPolicies, []string{subUser, domain, role, "", "", permissionId})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupingPolicies = append(groupingPolicies, []string{subUser, role, "", "", "", permissionId})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, subRole := range roleObj.Roles {
|
||||||
|
if domainExist {
|
||||||
|
for _, domain := range permission.Domains {
|
||||||
|
groupingPolicies = append(groupingPolicies, []string{subRole, domain, role, "", "", permissionId})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupingPolicies = append(groupingPolicies, []string{subRole, role, "", "", "", permissionId})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupingPolicies
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPolicies(permission *Permission) {
|
func addPolicies(permission *Permission) {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getEnforcer(permission)
|
||||||
policies, groupingPolicies := getPolicies(permission)
|
policies := getPolicies(permission)
|
||||||
|
|
||||||
if len(groupingPolicies) > 0 {
|
|
||||||
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := enforcer.AddPolicies(policies)
|
_, err := enforcer.AddPolicies(policies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -142,9 +157,21 @@ func addPolicies(permission *Permission) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func removePolicies(permission *Permission) {
|
func addGroupingPolicies(permission *Permission) {
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getEnforcer(permission)
|
||||||
policies, groupingPolicies := getPolicies(permission)
|
groupingPolicies := getGroupingPolicies(permission)
|
||||||
|
|
||||||
|
if len(groupingPolicies) > 0 {
|
||||||
|
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeGroupingPolicies(permission *Permission) {
|
||||||
|
enforcer := getEnforcer(permission)
|
||||||
|
groupingPolicies := getGroupingPolicies(permission)
|
||||||
|
|
||||||
if len(groupingPolicies) > 0 {
|
if len(groupingPolicies) > 0 {
|
||||||
_, err := enforcer.RemoveGroupingPolicies(groupingPolicies)
|
_, err := enforcer.RemoveGroupingPolicies(groupingPolicies)
|
||||||
@ -152,6 +179,11 @@ func removePolicies(permission *Permission) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removePolicies(permission *Permission) {
|
||||||
|
enforcer := getEnforcer(permission)
|
||||||
|
policies := getPolicies(permission)
|
||||||
|
|
||||||
_, err := enforcer.RemovePolicies(policies)
|
_, err := enforcer.RemovePolicies(policies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -163,10 +195,8 @@ func Enforce(permissionRule *PermissionRule) bool {
|
|||||||
permission := GetPermission(permissionRule.Id)
|
permission := GetPermission(permissionRule.Id)
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getEnforcer(permission)
|
||||||
|
|
||||||
request := []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2}
|
request, _ := permissionRule.GetRequest(builtInAdapter, permissionRule.Id)
|
||||||
if permissionRule.V3 != "" {
|
|
||||||
request = append(request, permissionRule.V3)
|
|
||||||
}
|
|
||||||
allow, err := enforcer.Enforce(request...)
|
allow, err := enforcer.Enforce(request...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -177,11 +207,8 @@ func Enforce(permissionRule *PermissionRule) bool {
|
|||||||
func BatchEnforce(permissionRules []PermissionRule) []bool {
|
func BatchEnforce(permissionRules []PermissionRule) []bool {
|
||||||
var requests [][]interface{}
|
var requests [][]interface{}
|
||||||
for _, permissionRule := range permissionRules {
|
for _, permissionRule := range permissionRules {
|
||||||
if permissionRule.V3 != "" {
|
request, _ := permissionRule.GetRequest(builtInAdapter, permissionRule.Id)
|
||||||
requests = append(requests, []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2, permissionRule.V3})
|
requests = append(requests, request)
|
||||||
} else {
|
|
||||||
requests = append(requests, []interface{}{permissionRule.V0, permissionRule.V1, permissionRule.V2})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
permission := GetPermission(permissionRules[0].Id)
|
permission := GetPermission(permissionRules[0].Id)
|
||||||
enforcer := getEnforcer(permission)
|
enforcer := getEnforcer(permission)
|
||||||
@ -226,3 +253,46 @@ func GetAllRoles(userId string) []string {
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetBuiltInModel(modelText string) (model.Model, error) {
|
||||||
|
if modelText == "" {
|
||||||
|
modelText = `
|
||||||
|
[request_definition]
|
||||||
|
r = sub, obj, act
|
||||||
|
|
||||||
|
[policy_definition]
|
||||||
|
p = sub, obj, act, "", "", permissionId
|
||||||
|
|
||||||
|
[role_definition]
|
||||||
|
g = _, _
|
||||||
|
|
||||||
|
[policy_effect]
|
||||||
|
e = some(where (p.eft == allow))
|
||||||
|
|
||||||
|
[matchers]
|
||||||
|
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
|
||||||
|
return model.NewModelFromString(modelText)
|
||||||
|
} else {
|
||||||
|
cfg, err := config.NewConfigFromText(modelText)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// load [policy_definition]
|
||||||
|
policyDefinition := strings.Split(cfg.String("policy_definition::p"), ",")
|
||||||
|
fieldsNum := len(policyDefinition)
|
||||||
|
if fieldsNum > builtInAvailableField {
|
||||||
|
panic(fmt.Errorf("the maximum policy_definition field number cannot exceed %d", builtInAvailableField))
|
||||||
|
}
|
||||||
|
// filled empty field with "" and V5 with "permissionId"
|
||||||
|
for i := builtInAvailableField - fieldsNum; i > 0; i-- {
|
||||||
|
policyDefinition = append(policyDefinition, "")
|
||||||
|
}
|
||||||
|
policyDefinition = append(policyDefinition, "permissionId")
|
||||||
|
|
||||||
|
m, _ := model.NewModelFromString(modelText)
|
||||||
|
m.AddDef("p", "p", strings.Join(policyDefinition, ","))
|
||||||
|
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -95,6 +95,12 @@ func UpdateRole(id string, role *Role) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
permissions := GetPermissionsByRole(id)
|
||||||
|
for _, permission := range permissions {
|
||||||
|
removeGroupingPolicies(permission)
|
||||||
|
removePolicies(permission)
|
||||||
|
}
|
||||||
|
|
||||||
if name != role.Name {
|
if name != role.Name {
|
||||||
err := roleChangeTrigger(name, role.Name)
|
err := roleChangeTrigger(name, role.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -107,6 +113,13 @@ func UpdateRole(id string, role *Role) bool {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newRoleID := role.GetId()
|
||||||
|
permissions = GetPermissionsByRole(newRoleID)
|
||||||
|
for _, permission := range permissions {
|
||||||
|
addGroupingPolicies(permission)
|
||||||
|
addPolicies(permission)
|
||||||
|
}
|
||||||
|
|
||||||
return affected != 0
|
return affected != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +133,13 @@ func AddRole(role *Role) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DeleteRole(role *Role) bool {
|
func DeleteRole(role *Role) bool {
|
||||||
|
roleId := role.GetId()
|
||||||
|
permissions := GetPermissionsByRole(roleId)
|
||||||
|
for _, permission := range permissions {
|
||||||
|
permission.Roles = util.DeleteVal(permission.Roles, roleId)
|
||||||
|
UpdatePermission(permission.GetId(), permission)
|
||||||
|
}
|
||||||
|
|
||||||
affected, err := adapter.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
|
affected, err := adapter.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -192,3 +212,11 @@ func roleChangeTrigger(oldName string, newName string) error {
|
|||||||
|
|
||||||
return session.Commit()
|
return session.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetMaskedRoles(roles []*Role) []*Role {
|
||||||
|
for _, role := range roles {
|
||||||
|
role.Users = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return roles
|
||||||
|
}
|
||||||
|
@ -223,11 +223,14 @@ func GetSamlMeta(application *Application, host string) (*IdpEntityDescriptor, e
|
|||||||
|
|
||||||
// GetSamlResponse generates a SAML2.0 response
|
// GetSamlResponse generates a SAML2.0 response
|
||||||
// parameter samlRequest is saml request in base64 format
|
// parameter samlRequest is saml request in base64 format
|
||||||
func GetSamlResponse(application *Application, user *User, samlRequest string, host string) (string, string, error) {
|
func GetSamlResponse(application *Application, user *User, samlRequest string, host string) (string, string, string, error) {
|
||||||
|
// request type
|
||||||
|
method := "GET"
|
||||||
|
|
||||||
// base64 decode
|
// base64 decode
|
||||||
defated, err := base64.StdEncoding.DecodeString(samlRequest)
|
defated, err := base64.StdEncoding.DecodeString(samlRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||||
}
|
}
|
||||||
// decompress
|
// decompress
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
@ -236,12 +239,12 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
|||||||
var authnRequest saml.AuthnRequest
|
var authnRequest saml.AuthnRequest
|
||||||
err = xml.Unmarshal(buffer.Bytes(), &authnRequest)
|
err = xml.Unmarshal(buffer.Bytes(), &authnRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify samlRequest
|
// verify samlRequest
|
||||||
if isValid := application.IsRedirectUriValid(authnRequest.Issuer.Url); !isValid {
|
if isValid := application.IsRedirectUriValid(authnRequest.Issuer.Url); !isValid {
|
||||||
return "", "", fmt.Errorf("err: Issuer URI: %s doesn't exist in the allowed Redirect URI list", authnRequest.Issuer.Url)
|
return "", "", method, fmt.Errorf("err: Issuer URI: %s doesn't exist in the allowed Redirect URI list", authnRequest.Issuer.Url)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get certificate string
|
// get certificate string
|
||||||
@ -253,6 +256,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
|||||||
|
|
||||||
// redirect Url (Assertion Consumer Url)
|
// redirect Url (Assertion Consumer Url)
|
||||||
if application.SamlReplyUrl != "" {
|
if application.SamlReplyUrl != "" {
|
||||||
|
method = "POST"
|
||||||
authnRequest.AssertionConsumerServiceURL = application.SamlReplyUrl
|
authnRequest.AssertionConsumerServiceURL = application.SamlReplyUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +279,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
|||||||
doc.SetRoot(samlResponse)
|
doc.SetRoot(samlResponse)
|
||||||
xmlBytes, err := doc.WriteToBytes()
|
xmlBytes, err := doc.WriteToBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// compress
|
// compress
|
||||||
@ -283,7 +287,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
|||||||
flated := bytes.NewBuffer(nil)
|
flated := bytes.NewBuffer(nil)
|
||||||
writer, err := flate.NewWriter(flated, flate.DefaultCompression)
|
writer, err := flate.NewWriter(flated, flate.DefaultCompression)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||||
}
|
}
|
||||||
writer.Write(xmlBytes)
|
writer.Write(xmlBytes)
|
||||||
writer.Close()
|
writer.Close()
|
||||||
@ -291,7 +295,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
|||||||
}
|
}
|
||||||
// base64 encode
|
// base64 encode
|
||||||
res := base64.StdEncoding.EncodeToString(xmlBytes)
|
res := base64.StdEncoding.EncodeToString(xmlBytes)
|
||||||
return res, authnRequest.AssertionConsumerServiceURL, nil
|
return res, authnRequest.AssertionConsumerServiceURL, method, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSamlResponse11 return a saml1.1 response(not 2.0)
|
// NewSamlResponse11 return a saml1.1 response(not 2.0)
|
||||||
|
130
object/session.go
Normal file
130
object/session.go
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package object
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/beego/beego"
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
|
"xorm.io/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Session struct {
|
||||||
|
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
||||||
|
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||||
|
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||||
|
|
||||||
|
SessionId []string `json:"sessionId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetSession(id string, sessionId string) {
|
||||||
|
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
|
||||||
|
session := &Session{Owner: owner, Name: name}
|
||||||
|
get, err := adapter.Engine.Get(session)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
session.SessionId = append(session.SessionId, sessionId)
|
||||||
|
if get {
|
||||||
|
_, err = adapter.Engine.ID(core.PK{owner, name}).Update(session)
|
||||||
|
} else {
|
||||||
|
session.CreatedTime = util.GetCurrentTime()
|
||||||
|
_, err = adapter.Engine.Insert(session)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteSession(id string) bool {
|
||||||
|
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
|
||||||
|
|
||||||
|
session := &Session{Owner: owner, Name: name}
|
||||||
|
_, err := adapter.Engine.ID(core.PK{owner, name}).Get(session)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteBeegoSession(session.SessionId)
|
||||||
|
|
||||||
|
affected, err := adapter.Engine.ID(core.PK{owner, name}).Delete(session)
|
||||||
|
return affected != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteSessionId(id string, sessionId string) bool {
|
||||||
|
owner, name := util.GetOwnerAndNameFromId(id)
|
||||||
|
|
||||||
|
session := &Session{Owner: owner, Name: name}
|
||||||
|
_, err := adapter.Engine.ID(core.PK{owner, name}).Get(session)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteBeegoSession([]string{sessionId})
|
||||||
|
session.SessionId = util.DeleteVal(session.SessionId, sessionId)
|
||||||
|
|
||||||
|
if len(session.SessionId) < 1 {
|
||||||
|
affected, _ := adapter.Engine.ID(core.PK{owner, name}).Delete(session)
|
||||||
|
return affected != 0
|
||||||
|
} else {
|
||||||
|
affected, _ := adapter.Engine.ID(core.PK{owner, name}).Update(session)
|
||||||
|
return affected != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteBeegoSession(sessionIds []string) {
|
||||||
|
for _, sessionId := range sessionIds {
|
||||||
|
err := beego.GlobalSessions.GetProvider().SessionDestroy(sessionId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSessions(owner string) []*Session {
|
||||||
|
sessions := []*Session{}
|
||||||
|
var err error
|
||||||
|
if owner != "" {
|
||||||
|
err = adapter.Engine.Desc("created_time").Where("owner = ?", owner).Find(&sessions)
|
||||||
|
} else {
|
||||||
|
err = adapter.Engine.Desc("created_time").Find(&sessions)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessions
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetPaginationSessions(owner string, offset, limit int, field, value, sortField, sortOrder string) []*Session {
|
||||||
|
sessions := []*Session{}
|
||||||
|
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||||
|
err := session.Find(&sessions)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessions
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSessionCount(owner, field, value string) int {
|
||||||
|
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||||
|
count, err := session.Count(&Session{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(count)
|
||||||
|
}
|
@ -27,7 +27,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
hourSeconds = 3600
|
hourMinutes = 60
|
||||||
InvalidRequest = "invalid_request"
|
InvalidRequest = "invalid_request"
|
||||||
InvalidClient = "invalid_client"
|
InvalidClient = "invalid_client"
|
||||||
InvalidGrant = "invalid_grant"
|
InvalidGrant = "invalid_grant"
|
||||||
@ -204,7 +204,7 @@ func DeleteToken(token *Token) bool {
|
|||||||
return affected != 0
|
return affected != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteTokenByAccessToken(accessToken string) (bool, *Application) {
|
func ExpireTokenByAccessToken(accessToken string) (bool, *Application, *Token) {
|
||||||
token := Token{AccessToken: accessToken}
|
token := Token{AccessToken: accessToken}
|
||||||
existed, err := adapter.Engine.Get(&token)
|
existed, err := adapter.Engine.Get(&token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -212,15 +212,17 @@ func DeleteTokenByAccessToken(accessToken string) (bool, *Application) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !existed {
|
if !existed {
|
||||||
return false, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
application := getApplication(token.Owner, token.Application)
|
|
||||||
affected, err := adapter.Engine.Where("access_token=?", accessToken).Delete(&Token{})
|
token.ExpiresIn = 0
|
||||||
|
affected, err := adapter.Engine.ID(core.PK{token.Owner, token.Name}).Cols("expires_in").Update(&token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return affected != 0, application
|
application := getApplication(token.Owner, token.Application)
|
||||||
|
return affected != 0, application, &token
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTokenByAccessToken(accessToken string) *Token {
|
func GetTokenByAccessToken(accessToken string) *Token {
|
||||||
@ -265,7 +267,7 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
|||||||
user := GetUser(userId)
|
user := GetUser(userId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return &Code{
|
return &Code{
|
||||||
Message: fmt.Sprintf("token:The user: %s doesn't exist", userId),
|
Message: fmt.Sprintf("general:The user: %s doesn't exist", userId),
|
||||||
Code: "",
|
Code: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,7 +306,7 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
|||||||
Code: util.GenerateClientId(),
|
Code: util.GenerateClientId(),
|
||||||
AccessToken: accessToken,
|
AccessToken: accessToken,
|
||||||
RefreshToken: refreshToken,
|
RefreshToken: refreshToken,
|
||||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||||
Scope: scope,
|
Scope: scope,
|
||||||
TokenType: "Bearer",
|
TokenType: "Bearer",
|
||||||
CodeChallenge: challenge,
|
CodeChallenge: challenge,
|
||||||
@ -438,7 +440,7 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
|||||||
Code: util.GenerateClientId(),
|
Code: util.GenerateClientId(),
|
||||||
AccessToken: newAccessToken,
|
AccessToken: newAccessToken,
|
||||||
RefreshToken: newRefreshToken,
|
RefreshToken: newRefreshToken,
|
||||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||||
Scope: scope,
|
Scope: scope,
|
||||||
TokenType: "Bearer",
|
TokenType: "Bearer",
|
||||||
}
|
}
|
||||||
@ -588,7 +590,7 @@ func GetPasswordToken(application *Application, username string, password string
|
|||||||
Code: util.GenerateClientId(),
|
Code: util.GenerateClientId(),
|
||||||
AccessToken: accessToken,
|
AccessToken: accessToken,
|
||||||
RefreshToken: refreshToken,
|
RefreshToken: refreshToken,
|
||||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||||
Scope: scope,
|
Scope: scope,
|
||||||
TokenType: "Bearer",
|
TokenType: "Bearer",
|
||||||
CodeIsUsed: true,
|
CodeIsUsed: true,
|
||||||
@ -628,7 +630,7 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
|
|||||||
User: nullUser.Name,
|
User: nullUser.Name,
|
||||||
Code: util.GenerateClientId(),
|
Code: util.GenerateClientId(),
|
||||||
AccessToken: accessToken,
|
AccessToken: accessToken,
|
||||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||||
Scope: scope,
|
Scope: scope,
|
||||||
TokenType: "Bearer",
|
TokenType: "Bearer",
|
||||||
CodeIsUsed: true,
|
CodeIsUsed: true,
|
||||||
@ -655,7 +657,7 @@ func GetTokenByUser(application *Application, user *User, scope string, host str
|
|||||||
Code: util.GenerateClientId(),
|
Code: util.GenerateClientId(),
|
||||||
AccessToken: accessToken,
|
AccessToken: accessToken,
|
||||||
RefreshToken: refreshToken,
|
RefreshToken: refreshToken,
|
||||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||||
Scope: scope,
|
Scope: scope,
|
||||||
TokenType: "Bearer",
|
TokenType: "Bearer",
|
||||||
CodeIsUsed: true,
|
CodeIsUsed: true,
|
||||||
|
@ -110,8 +110,8 @@ type User struct {
|
|||||||
Ldap string `xorm:"ldap varchar(100)" json:"ldap"`
|
Ldap string `xorm:"ldap varchar(100)" json:"ldap"`
|
||||||
Properties map[string]string `json:"properties"`
|
Properties map[string]string `json:"properties"`
|
||||||
|
|
||||||
Roles []*Role `json:"roles"`
|
Roles []*Role `xorm:"-" json:"roles"`
|
||||||
Permissions []*Permission `json:"permissions"`
|
Permissions []*Permission `xorm:"-" json:"permissions"`
|
||||||
|
|
||||||
LastSigninWrongTime string `xorm:"varchar(100)" json:"lastSigninWrongTime"`
|
LastSigninWrongTime string `xorm:"varchar(100)" json:"lastSigninWrongTime"`
|
||||||
SigninWrongTimes int `json:"signinWrongTimes"`
|
SigninWrongTimes int `json:"signinWrongTimes"`
|
||||||
@ -529,6 +529,9 @@ func AddUsersInBatch(users []*User) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DeleteUser(user *User) bool {
|
func DeleteUser(user *User) bool {
|
||||||
|
// Forced offline the user first
|
||||||
|
DeleteSession(user.GetId())
|
||||||
|
|
||||||
affected, err := adapter.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
|
affected, err := adapter.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -26,6 +26,10 @@ import (
|
|||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
wrongCode = "wrongCode"
|
||||||
|
)
|
||||||
|
|
||||||
type VerificationRecord struct {
|
type VerificationRecord struct {
|
||||||
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
||||||
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||||
@ -167,7 +171,7 @@ func CheckVerificationCode(dest, code, lang string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if record.Code != code {
|
if record.Code != code {
|
||||||
return "Wrong code!"
|
return wrongCode
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
@ -186,6 +190,24 @@ func DisableVerificationCode(dest string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckSigninCode(user *User, dest, code, lang string) string {
|
||||||
|
// check the login error times
|
||||||
|
if msg := checkSigninErrorTimes(user, lang); msg != "" {
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
result := CheckVerificationCode(dest, code, lang)
|
||||||
|
switch result {
|
||||||
|
case "":
|
||||||
|
resetUserSigninErrorTimes(user)
|
||||||
|
return ""
|
||||||
|
case wrongCode:
|
||||||
|
return recordSigninErrorInfo(user, lang)
|
||||||
|
default:
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// From Casnode/object/validateCode.go line 116
|
// From Casnode/object/validateCode.go line 116
|
||||||
var stdNums = []byte("0123456789")
|
var stdNums = []byte("0123456789")
|
||||||
|
|
||||||
|
@ -158,12 +158,13 @@ func initAPI() {
|
|||||||
beego.Router("/api/login/oauth/access_token", &controllers.ApiController{}, "POST:GetOAuthToken")
|
beego.Router("/api/login/oauth/access_token", &controllers.ApiController{}, "POST:GetOAuthToken")
|
||||||
beego.Router("/api/login/oauth/refresh_token", &controllers.ApiController{}, "POST:RefreshToken")
|
beego.Router("/api/login/oauth/refresh_token", &controllers.ApiController{}, "POST:RefreshToken")
|
||||||
beego.Router("/api/login/oauth/introspect", &controllers.ApiController{}, "POST:IntrospectToken")
|
beego.Router("/api/login/oauth/introspect", &controllers.ApiController{}, "POST:IntrospectToken")
|
||||||
beego.Router("/api/login/oauth/logout", &controllers.ApiController{}, "GET:TokenLogout")
|
|
||||||
|
|
||||||
beego.Router("/api/get-records", &controllers.ApiController{}, "GET:GetRecords")
|
beego.Router("/api/get-records", &controllers.ApiController{}, "GET:GetRecords")
|
||||||
beego.Router("/api/get-records-filter", &controllers.ApiController{}, "POST:GetRecordsByFilter")
|
beego.Router("/api/get-records-filter", &controllers.ApiController{}, "POST:GetRecordsByFilter")
|
||||||
beego.Router("/api/add-record", &controllers.ApiController{}, "POST:AddRecord")
|
beego.Router("/api/add-record", &controllers.ApiController{}, "POST:AddRecord")
|
||||||
|
|
||||||
|
beego.Router("/api/get-sessions", &controllers.ApiController{}, "GET:GetSessions")
|
||||||
|
beego.Router("/api/delete-session", &controllers.ApiController{}, "POST:DeleteSession")
|
||||||
|
|
||||||
beego.Router("/api/get-webhooks", &controllers.ApiController{}, "GET:GetWebhooks")
|
beego.Router("/api/get-webhooks", &controllers.ApiController{}, "GET:GetWebhooks")
|
||||||
beego.Router("/api/get-webhook", &controllers.ApiController{}, "GET:GetWebhook")
|
beego.Router("/api/get-webhook", &controllers.ApiController{}, "GET:GetWebhook")
|
||||||
beego.Router("/api/update-webhook", &controllers.ApiController{}, "POST:UpdateWebhook")
|
beego.Router("/api/update-webhook", &controllers.ApiController{}, "POST:UpdateWebhook")
|
||||||
|
@ -275,6 +275,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/add-record": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Record API"
|
||||||
|
],
|
||||||
|
"description": "add a record",
|
||||||
|
"operationId": "ApiController.AddRecord",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "The details of the record",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.Record"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controllers.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/add-resource": {
|
"/api/add-resource": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -431,6 +459,14 @@
|
|||||||
"operationId": "ApiController.GetCaptcha"
|
"operationId": "ApiController.GetCaptcha"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/api/get-webhook-event": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"GetWebhookEventType API"
|
||||||
|
],
|
||||||
|
"operationId": "ApiController.GetWebhookEventType"
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/api/reset-email-or-phone": {
|
"/api/api/reset-email-or-phone": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -523,6 +559,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/api/webhook": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"HandleOfficialAccountEvent API"
|
||||||
|
],
|
||||||
|
"operationId": "ApiController.HandleOfficialAccountEvent"
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/buy-product": {
|
"/api/buy-product": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -840,6 +884,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/delete-session": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Session API"
|
||||||
|
],
|
||||||
|
"description": "Delete session by userId",
|
||||||
|
"operationId": "ApiController.DeleteSession",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "ID",
|
||||||
|
"description": "The ID(owner/name) of user.",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/delete-syncer": {
|
"/api/delete-syncer": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -1133,6 +1206,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/get-default-application": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Organization API"
|
||||||
|
],
|
||||||
|
"description": "get default application",
|
||||||
|
"operationId": "ApiController.GetDefaultApplication",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id",
|
||||||
|
"description": "organization id",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/get-email-and-phone": {
|
"/api/get-email-and-phone": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -1166,6 +1265,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/get-global-providers": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Provider API"
|
||||||
|
],
|
||||||
|
"description": "get Global providers",
|
||||||
|
"operationId": "ApiController.GetGlobalProviders",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/object.Provider"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/get-global-users": {
|
"/api/get-global-users": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -1459,6 +1578,55 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/get-permissions-by-role": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Permission API"
|
||||||
|
],
|
||||||
|
"description": "get permissions by role",
|
||||||
|
"operationId": "ApiController.GetPermissionsByRole",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id",
|
||||||
|
"description": "The id of the role",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/object.Permission"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/get-permissions-by-submitter": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Permission API"
|
||||||
|
],
|
||||||
|
"description": "get permissions by submitter",
|
||||||
|
"operationId": "ApiController.GetPermissionsBySubmitter",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/object.Permission"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/get-product": {
|
"/api/get-product": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -1631,6 +1799,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/get-release": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"System API"
|
||||||
|
],
|
||||||
|
"description": "get local github repo's latest release version info",
|
||||||
|
"operationId": "ApiController.GitRepoVersion",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "{string} local latest version hash of casdoor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/get-resource": {
|
"/api/get-resource": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -1702,6 +1884,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/get-sessions": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Session API"
|
||||||
|
],
|
||||||
|
"description": "Get organization user sessions",
|
||||||
|
"operationId": "ApiController.GetSessions",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "owner",
|
||||||
|
"description": "The organization name",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/get-sorted-users": {
|
"/api/get-sorted-users": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -1799,6 +2010,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/get-system-info": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"System API"
|
||||||
|
],
|
||||||
|
"description": "get user's system info",
|
||||||
|
"operationId": "ApiController.GetSystemInfo",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id",
|
||||||
|
"description": "The id of the user",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.SystemInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/get-token": {
|
"/api/get-token": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -2360,45 +2597,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/login/oauth/logout": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"Token API"
|
|
||||||
],
|
|
||||||
"description": "delete token by AccessToken",
|
|
||||||
"operationId": "ApiController.TokenLogout",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "query",
|
|
||||||
"name": "id_token_hint",
|
|
||||||
"description": "id_token_hint",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "query",
|
|
||||||
"name": "post_logout_redirect_uri",
|
|
||||||
"description": "post_logout_redirect_uri",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "query",
|
|
||||||
"name": "state",
|
|
||||||
"description": "state",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "The Response object",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/controllers.Response"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/api/login/oauth/refresh_token": {
|
"/api/login/oauth/refresh_token": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -2471,6 +2669,26 @@
|
|||||||
],
|
],
|
||||||
"description": "logout the current user",
|
"description": "logout the current user",
|
||||||
"operationId": "ApiController.Logout",
|
"operationId": "ApiController.Logout",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id_token_hint",
|
||||||
|
"description": "id_token_hint",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "post_logout_redirect_uri",
|
||||||
|
"description": "post_logout_redirect_uri",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "state",
|
||||||
|
"description": "state",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The Response object",
|
"description": "The Response object",
|
||||||
@ -2486,6 +2704,26 @@
|
|||||||
],
|
],
|
||||||
"description": "logout the current user",
|
"description": "logout the current user",
|
||||||
"operationId": "ApiController.Logout",
|
"operationId": "ApiController.Logout",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id_token_hint",
|
||||||
|
"description": "id_token_hint",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "post_logout_redirect_uri",
|
||||||
|
"description": "post_logout_redirect_uri",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "state",
|
||||||
|
"description": "state",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The Response object",
|
"description": "The Response object",
|
||||||
@ -3267,11 +3505,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"2200.0xc0003f8480.false": {
|
"2268.0xc0000f9650.false": {
|
||||||
"title": "false",
|
"title": "false",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"2235.0xc0003f84b0.false": {
|
"2302.0xc0000f9680.false": {
|
||||||
"title": "false",
|
"title": "false",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
@ -3316,6 +3554,15 @@
|
|||||||
"autoSignin": {
|
"autoSignin": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"captchaToken": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"captchaType": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"clientSecret": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"code": {
|
"code": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -3389,10 +3636,10 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"$ref": "#/definitions/2200.0xc0003f8480.false"
|
"$ref": "#/definitions/2268.0xc0000f9650.false"
|
||||||
},
|
},
|
||||||
"data2": {
|
"data2": {
|
||||||
"$ref": "#/definitions/2235.0xc0003f84b0.false"
|
"$ref": "#/definitions/2302.0xc0000f9680.false"
|
||||||
},
|
},
|
||||||
"msg": {
|
"msg": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -3491,9 +3738,15 @@
|
|||||||
"displayName": {
|
"displayName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"enableAutoSignin": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"enableCodeSignin": {
|
"enableCodeSignin": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"enableLinkWithEmail": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"enablePassword": {
|
"enablePassword": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
@ -3516,6 +3769,19 @@
|
|||||||
"forgetUrl": {
|
"forgetUrl": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"formBackgroundUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"formCss": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"formOffset": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"formSideHtml": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"grantTypes": {
|
"grantTypes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -3556,6 +3822,9 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64"
|
"format": "int64"
|
||||||
},
|
},
|
||||||
|
"samlReplyUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"signinHtml": {
|
"signinHtml": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -3689,6 +3958,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object.ManagedAccount": {
|
||||||
|
"title": "ManagedAccount",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"application": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"signinUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"object.Model": {
|
"object.Model": {
|
||||||
"title": "Model",
|
"title": "Model",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -3726,6 +4013,9 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"end_session_endpoint": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"grant_types_supported": {
|
"grant_types_supported": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -3801,6 +4091,9 @@
|
|||||||
"createdTime": {
|
"createdTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"defaultApplication": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"defaultAvatar": {
|
"defaultAvatar": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -3813,9 +4106,19 @@
|
|||||||
"favicon": {
|
"favicon": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"initScore": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
"isProfilePublic": {
|
"isProfilePublic": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"languages": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"masterPassword": {
|
"masterPassword": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -3943,12 +4246,27 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"adapter": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"approveTime": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"approver": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"createdTime": {
|
"createdTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"displayName": {
|
"displayName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"domains": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"effect": {
|
"effect": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -3979,6 +4297,12 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"state": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"submitter": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -3997,6 +4321,9 @@
|
|||||||
"currency": {
|
"currency": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"detail": {
|
"detail": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -4016,6 +4343,12 @@
|
|||||||
"type": "number",
|
"type": "number",
|
||||||
"format": "double"
|
"format": "double"
|
||||||
},
|
},
|
||||||
|
"providerObjs": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/object.Provider"
|
||||||
|
}
|
||||||
|
},
|
||||||
"providers": {
|
"providers": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -4090,6 +4423,9 @@
|
|||||||
"customUserInfoUrl": {
|
"customUserInfoUrl": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"disableSsl": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"displayName": {
|
"displayName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -4126,6 +4462,9 @@
|
|||||||
"owner": {
|
"owner": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"pathPrefix": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"port": {
|
"port": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64"
|
"format": "int64"
|
||||||
@ -4133,6 +4472,9 @@
|
|||||||
"providerUrl": {
|
"providerUrl": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"receiver": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"regionId": {
|
"regionId": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -4172,11 +4514,17 @@
|
|||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"prompted": {
|
"prompted": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"provider": {
|
"provider": {
|
||||||
"$ref": "#/definitions/object.Provider"
|
"$ref": "#/definitions/object.Provider"
|
||||||
|
},
|
||||||
|
"rule": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -4233,6 +4581,12 @@
|
|||||||
"displayName": {
|
"displayName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"domains": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"isEnabled": {
|
"isEnabled": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
@ -4345,6 +4699,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object.SystemInfo": {
|
||||||
|
"title": "SystemInfo",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"object.TableColumn": {
|
"object.TableColumn": {
|
||||||
"title": "TableColumn",
|
"title": "TableColumn",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -4605,15 +4963,27 @@
|
|||||||
"lastSigninTime": {
|
"lastSigninTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"lastSigninWrongTime": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"ldap": {
|
"ldap": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"line": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"linkedin": {
|
"linkedin": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"location": {
|
"location": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"managedAccounts": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/object.ManagedAccount"
|
||||||
|
}
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -4669,6 +5039,10 @@
|
|||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64"
|
"format": "int64"
|
||||||
},
|
},
|
||||||
|
"signinWrongTimes": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
"signupApplication": {
|
"signupApplication": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -4687,9 +5061,6 @@
|
|||||||
"type": {
|
"type": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"unionId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"updatedTime": {
|
"updatedTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -177,6 +177,24 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
|
/api/add-record:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Record API
|
||||||
|
description: add a record
|
||||||
|
operationId: ApiController.AddRecord
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: The details of the record
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.Record'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/controllers.Response'
|
||||||
/api/add-resource:
|
/api/add-resource:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -277,6 +295,11 @@ paths:
|
|||||||
tags:
|
tags:
|
||||||
- Login API
|
- Login API
|
||||||
operationId: ApiController.GetCaptcha
|
operationId: ApiController.GetCaptcha
|
||||||
|
/api/api/get-webhook-event:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- GetWebhookEventType API
|
||||||
|
operationId: ApiController.GetWebhookEventType
|
||||||
/api/api/reset-email-or-phone:
|
/api/api/reset-email-or-phone:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -338,6 +361,11 @@ paths:
|
|||||||
description: object
|
description: object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Response'
|
$ref: '#/definitions/Response'
|
||||||
|
/api/api/webhook:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- HandleOfficialAccountEvent API
|
||||||
|
operationId: ApiController.HandleOfficialAccountEvent
|
||||||
/api/buy-product:
|
/api/buy-product:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -542,6 +570,25 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
|
/api/delete-session:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Session API
|
||||||
|
description: Delete session by userId
|
||||||
|
operationId: ApiController.DeleteSession
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: ID
|
||||||
|
description: The ID(owner/name) of user.
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
/api/delete-syncer:
|
/api/delete-syncer:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -734,6 +781,23 @@ paths:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/object.Cert'
|
$ref: '#/definitions/object.Cert'
|
||||||
|
/api/get-default-application:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Organization API
|
||||||
|
description: get default application
|
||||||
|
operationId: ApiController.GetDefaultApplication
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id
|
||||||
|
description: organization id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Response'
|
||||||
/api/get-email-and-phone:
|
/api/get-email-and-phone:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -756,6 +820,19 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.Response'
|
$ref: '#/definitions/controllers.Response'
|
||||||
|
/api/get-global-providers:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Provider API
|
||||||
|
description: get Global providers
|
||||||
|
operationId: ApiController.GetGlobalProviders
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/object.Provider'
|
||||||
/api/get-global-users:
|
/api/get-global-users:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -947,6 +1024,38 @@ paths:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/object.Permission'
|
$ref: '#/definitions/object.Permission'
|
||||||
|
/api/get-permissions-by-role:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Permission API
|
||||||
|
description: get permissions by role
|
||||||
|
operationId: ApiController.GetPermissionsByRole
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id
|
||||||
|
description: The id of the role
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/object.Permission'
|
||||||
|
/api/get-permissions-by-submitter:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Permission API
|
||||||
|
description: get permissions by submitter
|
||||||
|
operationId: ApiController.GetPermissionsBySubmitter
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/object.Permission'
|
||||||
/api/get-product:
|
/api/get-product:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -1060,6 +1169,15 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/object.Record'
|
$ref: '#/definitions/object.Record'
|
||||||
|
/api/get-release:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- System API
|
||||||
|
description: get local github repo's latest release version info
|
||||||
|
operationId: ApiController.GitRepoVersion
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: '{string} local latest version hash of casdoor'
|
||||||
/api/get-resource:
|
/api/get-resource:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -1106,6 +1224,25 @@ paths:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/object.Role'
|
$ref: '#/definitions/object.Role'
|
||||||
|
/api/get-sessions:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Session API
|
||||||
|
description: Get organization user sessions
|
||||||
|
operationId: ApiController.GetSessions
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: owner
|
||||||
|
description: The organization name
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
/api/get-sorted-users:
|
/api/get-sorted-users:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -1170,6 +1307,23 @@ paths:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/definitions/object.Syncer'
|
$ref: '#/definitions/object.Syncer'
|
||||||
|
/api/get-system-info:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- System API
|
||||||
|
description: get user's system info
|
||||||
|
operationId: ApiController.GetSystemInfo
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id
|
||||||
|
description: The id of the user
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.SystemInfo'
|
||||||
/api/get-token:
|
/api/get-token:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -1544,32 +1698,6 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/object.TokenError'
|
$ref: '#/definitions/object.TokenError'
|
||||||
/api/login/oauth/logout:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- Token API
|
|
||||||
description: delete token by AccessToken
|
|
||||||
operationId: ApiController.TokenLogout
|
|
||||||
parameters:
|
|
||||||
- in: query
|
|
||||||
name: id_token_hint
|
|
||||||
description: id_token_hint
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
- in: query
|
|
||||||
name: post_logout_redirect_uri
|
|
||||||
description: post_logout_redirect_uri
|
|
||||||
type: string
|
|
||||||
- in: query
|
|
||||||
name: state
|
|
||||||
description: state
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: The Response object
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/controllers.Response'
|
|
||||||
/api/login/oauth/refresh_token:
|
/api/login/oauth/refresh_token:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -1620,6 +1748,19 @@ paths:
|
|||||||
- Login API
|
- Login API
|
||||||
description: logout the current user
|
description: logout the current user
|
||||||
operationId: ApiController.Logout
|
operationId: ApiController.Logout
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id_token_hint
|
||||||
|
description: id_token_hint
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: post_logout_redirect_uri
|
||||||
|
description: post_logout_redirect_uri
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: state
|
||||||
|
description: state
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: The Response object
|
description: The Response object
|
||||||
@ -1630,6 +1771,19 @@ paths:
|
|||||||
- Login API
|
- Login API
|
||||||
description: logout the current user
|
description: logout the current user
|
||||||
operationId: ApiController.Logout
|
operationId: ApiController.Logout
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id_token_hint
|
||||||
|
description: id_token_hint
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: post_logout_redirect_uri
|
||||||
|
description: post_logout_redirect_uri
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: state
|
||||||
|
description: state
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: The Response object
|
description: The Response object
|
||||||
@ -2139,10 +2293,10 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Response'
|
$ref: '#/definitions/Response'
|
||||||
definitions:
|
definitions:
|
||||||
2200.0xc0003f8480.false:
|
2268.0xc0000f9650.false:
|
||||||
title: "false"
|
title: "false"
|
||||||
type: object
|
type: object
|
||||||
2235.0xc0003f84b0.false:
|
2302.0xc0000f9680.false:
|
||||||
title: "false"
|
title: "false"
|
||||||
type: object
|
type: object
|
||||||
Response:
|
Response:
|
||||||
@ -2174,6 +2328,12 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
autoSignin:
|
autoSignin:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
captchaToken:
|
||||||
|
type: string
|
||||||
|
captchaType:
|
||||||
|
type: string
|
||||||
|
clientSecret:
|
||||||
|
type: string
|
||||||
code:
|
code:
|
||||||
type: string
|
type: string
|
||||||
email:
|
email:
|
||||||
@ -2223,9 +2383,9 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
data:
|
data:
|
||||||
$ref: '#/definitions/2200.0xc0003f8480.false'
|
$ref: '#/definitions/2268.0xc0000f9650.false'
|
||||||
data2:
|
data2:
|
||||||
$ref: '#/definitions/2235.0xc0003f84b0.false'
|
$ref: '#/definitions/2302.0xc0000f9680.false'
|
||||||
msg:
|
msg:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
@ -2291,8 +2451,12 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
displayName:
|
displayName:
|
||||||
type: string
|
type: string
|
||||||
|
enableAutoSignin:
|
||||||
|
type: boolean
|
||||||
enableCodeSignin:
|
enableCodeSignin:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
enableLinkWithEmail:
|
||||||
|
type: boolean
|
||||||
enablePassword:
|
enablePassword:
|
||||||
type: boolean
|
type: boolean
|
||||||
enableSamlCompress:
|
enableSamlCompress:
|
||||||
@ -2308,6 +2472,15 @@ definitions:
|
|||||||
format: int64
|
format: int64
|
||||||
forgetUrl:
|
forgetUrl:
|
||||||
type: string
|
type: string
|
||||||
|
formBackgroundUrl:
|
||||||
|
type: string
|
||||||
|
formCss:
|
||||||
|
type: string
|
||||||
|
formOffset:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
formSideHtml:
|
||||||
|
type: string
|
||||||
grantTypes:
|
grantTypes:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -2335,6 +2508,8 @@ definitions:
|
|||||||
refreshExpireInHours:
|
refreshExpireInHours:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
samlReplyUrl:
|
||||||
|
type: string
|
||||||
signinHtml:
|
signinHtml:
|
||||||
type: string
|
type: string
|
||||||
signinUrl:
|
signinUrl:
|
||||||
@ -2424,6 +2599,18 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
username:
|
username:
|
||||||
type: string
|
type: string
|
||||||
|
object.ManagedAccount:
|
||||||
|
title: ManagedAccount
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
application:
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
signinUrl:
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
object.Model:
|
object.Model:
|
||||||
title: Model
|
title: Model
|
||||||
type: object
|
type: object
|
||||||
@ -2450,6 +2637,8 @@ definitions:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
end_session_endpoint:
|
||||||
|
type: string
|
||||||
grant_types_supported:
|
grant_types_supported:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -2500,6 +2689,8 @@ definitions:
|
|||||||
$ref: '#/definitions/object.AccountItem'
|
$ref: '#/definitions/object.AccountItem'
|
||||||
createdTime:
|
createdTime:
|
||||||
type: string
|
type: string
|
||||||
|
defaultApplication:
|
||||||
|
type: string
|
||||||
defaultAvatar:
|
defaultAvatar:
|
||||||
type: string
|
type: string
|
||||||
displayName:
|
displayName:
|
||||||
@ -2508,8 +2699,15 @@ definitions:
|
|||||||
type: boolean
|
type: boolean
|
||||||
favicon:
|
favicon:
|
||||||
type: string
|
type: string
|
||||||
|
initScore:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
isProfilePublic:
|
isProfilePublic:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
languages:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
masterPassword:
|
masterPassword:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
@ -2595,10 +2793,20 @@ definitions:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
adapter:
|
||||||
|
type: string
|
||||||
|
approveTime:
|
||||||
|
type: string
|
||||||
|
approver:
|
||||||
|
type: string
|
||||||
createdTime:
|
createdTime:
|
||||||
type: string
|
type: string
|
||||||
displayName:
|
displayName:
|
||||||
type: string
|
type: string
|
||||||
|
domains:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
effect:
|
effect:
|
||||||
type: string
|
type: string
|
||||||
isEnabled:
|
isEnabled:
|
||||||
@ -2619,6 +2827,10 @@ definitions:
|
|||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
state:
|
||||||
|
type: string
|
||||||
|
submitter:
|
||||||
|
type: string
|
||||||
users:
|
users:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -2631,6 +2843,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
currency:
|
currency:
|
||||||
type: string
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
detail:
|
detail:
|
||||||
type: string
|
type: string
|
||||||
displayName:
|
displayName:
|
||||||
@ -2644,6 +2858,10 @@ definitions:
|
|||||||
price:
|
price:
|
||||||
type: number
|
type: number
|
||||||
format: double
|
format: double
|
||||||
|
providerObjs:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/object.Provider'
|
||||||
providers:
|
providers:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -2694,6 +2912,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
customUserInfoUrl:
|
customUserInfoUrl:
|
||||||
type: string
|
type: string
|
||||||
|
disableSsl:
|
||||||
|
type: boolean
|
||||||
displayName:
|
displayName:
|
||||||
type: string
|
type: string
|
||||||
domain:
|
domain:
|
||||||
@ -2718,11 +2938,15 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
owner:
|
owner:
|
||||||
type: string
|
type: string
|
||||||
|
pathPrefix:
|
||||||
|
type: string
|
||||||
port:
|
port:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
providerUrl:
|
providerUrl:
|
||||||
type: string
|
type: string
|
||||||
|
receiver:
|
||||||
|
type: string
|
||||||
regionId:
|
regionId:
|
||||||
type: string
|
type: string
|
||||||
signName:
|
signName:
|
||||||
@ -2749,10 +2973,14 @@ definitions:
|
|||||||
type: boolean
|
type: boolean
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
|
owner:
|
||||||
|
type: string
|
||||||
prompted:
|
prompted:
|
||||||
type: boolean
|
type: boolean
|
||||||
provider:
|
provider:
|
||||||
$ref: '#/definitions/object.Provider'
|
$ref: '#/definitions/object.Provider'
|
||||||
|
rule:
|
||||||
|
type: string
|
||||||
object.Record:
|
object.Record:
|
||||||
title: Record
|
title: Record
|
||||||
type: object
|
type: object
|
||||||
@ -2790,6 +3018,10 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
displayName:
|
displayName:
|
||||||
type: string
|
type: string
|
||||||
|
domains:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
isEnabled:
|
isEnabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
name:
|
name:
|
||||||
@ -2864,6 +3096,9 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
type: string
|
type: string
|
||||||
|
object.SystemInfo:
|
||||||
|
title: SystemInfo
|
||||||
|
type: object
|
||||||
object.TableColumn:
|
object.TableColumn:
|
||||||
title: TableColumn
|
title: TableColumn
|
||||||
type: object
|
type: object
|
||||||
@ -3040,12 +3275,20 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
lastSigninTime:
|
lastSigninTime:
|
||||||
type: string
|
type: string
|
||||||
|
lastSigninWrongTime:
|
||||||
|
type: string
|
||||||
ldap:
|
ldap:
|
||||||
type: string
|
type: string
|
||||||
|
line:
|
||||||
|
type: string
|
||||||
linkedin:
|
linkedin:
|
||||||
type: string
|
type: string
|
||||||
location:
|
location:
|
||||||
type: string
|
type: string
|
||||||
|
managedAccounts:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/object.ManagedAccount'
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
okta:
|
okta:
|
||||||
@ -3083,6 +3326,9 @@ definitions:
|
|||||||
score:
|
score:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
signinWrongTimes:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
signupApplication:
|
signupApplication:
|
||||||
type: string
|
type: string
|
||||||
slack:
|
slack:
|
||||||
@ -3095,8 +3341,6 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
unionId:
|
|
||||||
type: string
|
|
||||||
updatedTime:
|
updatedTime:
|
||||||
type: string
|
type: string
|
||||||
webauthnCredentials:
|
webauthnCredentials:
|
||||||
|
25
util/slice.go
Normal file
25
util/slice.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
func DeleteVal(values []string, val string) []string {
|
||||||
|
newValues := []string{}
|
||||||
|
for _, v := range values {
|
||||||
|
if v != val {
|
||||||
|
newValues = append(newValues, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newValues
|
||||||
|
}
|
@ -53,7 +53,7 @@ func Test_IsTokenExpired(t *testing.T) {
|
|||||||
|
|
||||||
for _, scenario := range []testCases{
|
for _, scenario := range []testCases{
|
||||||
{
|
{
|
||||||
description: "Token emited now is valid for 60 minutes",
|
description: "Token emitted now is valid for 60 minutes",
|
||||||
input: input{
|
input: input{
|
||||||
createdTime: time.Now().Format(time.RFC3339),
|
createdTime: time.Now().Format(time.RFC3339),
|
||||||
expiresIn: 60,
|
expiresIn: 60,
|
||||||
@ -61,7 +61,7 @@ func Test_IsTokenExpired(t *testing.T) {
|
|||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Token emited 60 minutes before now is valid for 60 minutes",
|
description: "Token emitted 60 minutes before now is valid for 60 minutes",
|
||||||
input: input{
|
input: input{
|
||||||
createdTime: time.Now().Add(-time.Minute * 60).Format(time.RFC3339),
|
createdTime: time.Now().Add(-time.Minute * 60).Format(time.RFC3339),
|
||||||
expiresIn: 61,
|
expiresIn: 61,
|
||||||
@ -69,7 +69,7 @@ func Test_IsTokenExpired(t *testing.T) {
|
|||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Token emited 2 hours before now is Expired after 60 minutes",
|
description: "Token emitted 2 hours before now is Expired after 60 minutes",
|
||||||
input: input{
|
input: input{
|
||||||
createdTime: time.Now().Add(-time.Hour * 2).Format(time.RFC3339),
|
createdTime: time.Now().Add(-time.Hour * 2).Format(time.RFC3339),
|
||||||
expiresIn: 60,
|
expiresIn: 60,
|
||||||
@ -77,7 +77,7 @@ func Test_IsTokenExpired(t *testing.T) {
|
|||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Token emited 61 minutes before now is Expired after 60 minutes",
|
description: "Token emitted 61 minutes before now is Expired after 60 minutes",
|
||||||
input: input{
|
input: input{
|
||||||
createdTime: time.Now().Add(-time.Minute * 61).Format(time.RFC3339),
|
createdTime: time.Now().Add(-time.Minute * 61).Format(time.RFC3339),
|
||||||
expiresIn: 60,
|
expiresIn: 60,
|
||||||
@ -85,7 +85,7 @@ func Test_IsTokenExpired(t *testing.T) {
|
|||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Token emited 2 hours before now is velid for 120 minutes",
|
description: "Token emitted 2 hours before now is valid for 120 minutes",
|
||||||
input: input{
|
input: input{
|
||||||
createdTime: time.Now().Add(-time.Hour * 2).Format(time.RFC3339),
|
createdTime: time.Now().Add(-time.Hour * 2).Format(time.RFC3339),
|
||||||
expiresIn: 121,
|
expiresIn: 121,
|
||||||
@ -93,7 +93,7 @@ func Test_IsTokenExpired(t *testing.T) {
|
|||||||
expected: false,
|
expected: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
description: "Token emited 159 minutes before now is Expired after 60 minutes",
|
description: "Token emitted 159 minutes before now is Expired after 60 minutes",
|
||||||
input: input{
|
input: input{
|
||||||
createdTime: time.Now().Add(-time.Minute * 159).Format(time.RFC3339),
|
createdTime: time.Now().Add(-time.Minute * 159).Format(time.RFC3339),
|
||||||
expiresIn: 120,
|
expiresIn: 120,
|
||||||
|
7
web/cypress.config.js
Normal file
7
web/cypress.config.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
e2e: {
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
// implement node event listeners here
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
56
web/cypress/e2e/login.cy.js
Normal file
56
web/cypress/e2e/login.cy.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
describe("Login test", () => {
|
||||||
|
const selector = {
|
||||||
|
username: "#input",
|
||||||
|
password: "#normal_login_password",
|
||||||
|
loginButton: ".ant-btn",
|
||||||
|
};
|
||||||
|
it("Login succeeded", () => {
|
||||||
|
cy.request({
|
||||||
|
method: "POST",
|
||||||
|
url: "http://localhost:7001/api/login",
|
||||||
|
body: {
|
||||||
|
"application": "app-built-in",
|
||||||
|
"organization": "built-in",
|
||||||
|
"username": "admin",
|
||||||
|
"password": "123",
|
||||||
|
"autoSignin": true,
|
||||||
|
"type": "login",
|
||||||
|
"phonePrefix": "86",
|
||||||
|
},
|
||||||
|
}).then((Response) => {
|
||||||
|
expect(Response).property("body").property("status").to.equal("ok");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("ui Login succeeded", () => {
|
||||||
|
cy.visit("http://localhost:7001");
|
||||||
|
cy.get(selector.username).type("admin");
|
||||||
|
cy.get(selector.password).type("123");
|
||||||
|
cy.get(selector.loginButton).click();
|
||||||
|
cy.url().should("eq", "http://localhost:7001/");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Login failed", () => {
|
||||||
|
cy.request({
|
||||||
|
method: "POST",
|
||||||
|
url: "http://localhost:7001/api/login",
|
||||||
|
body: {
|
||||||
|
"application": "app-built-in",
|
||||||
|
"organization": "built-in",
|
||||||
|
"username": "admin",
|
||||||
|
"password": "1234",
|
||||||
|
"autoSignin": true,
|
||||||
|
"type": "login",
|
||||||
|
"phonePrefix": "86",
|
||||||
|
},
|
||||||
|
}).then((Response) => {
|
||||||
|
expect(Response).property("body").property("status").to.equal("error");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("ui Login failed", () => {
|
||||||
|
cy.visit("http://localhost:7001");
|
||||||
|
cy.get(selector.username).type("admin");
|
||||||
|
cy.get(selector.password).type("1234");
|
||||||
|
cy.get(selector.loginButton).click();
|
||||||
|
cy.url().should("eq", "http://localhost:7001/login");
|
||||||
|
});
|
||||||
|
});
|
25
web/cypress/support/commands.js
Normal file
25
web/cypress/support/commands.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// ***********************************************
|
||||||
|
// This example commands.js shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
20
web/cypress/support/e2e.js
Normal file
20
web/cypress/support/e2e.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// ***********************************************************
|
||||||
|
// This example support/e2e.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands'
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
@ -9,7 +9,7 @@
|
|||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.3.2",
|
"@testing-library/react": "^9.3.2",
|
||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^7.1.2",
|
||||||
"antd": "5.0.5",
|
"antd": "5.1.2",
|
||||||
"codemirror": "^5.61.1",
|
"codemirror": "^5.61.1",
|
||||||
"copy-to-clipboard": "^3.3.1",
|
"copy-to-clipboard": "^3.3.1",
|
||||||
"core-js": "^3.25.0",
|
"core-js": "^3.25.0",
|
||||||
|
@ -1,16 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script>
|
|
||||||
var _hmt = _hmt || [];
|
|
||||||
(function() {
|
|
||||||
var hm = document.createElement("script");
|
|
||||||
hm.src = "https://hm.baidu.com/hm.js?5998fcd123c220efc0936edf4f250504";
|
|
||||||
var s = document.getElementsByTagName("script")[0];
|
|
||||||
s.parentNode.insertBefore(hm, s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.png" />-->
|
<!-- <link rel="icon" href="%PUBLIC_URL%/favicon.png" />-->
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
@ -170,7 +170,7 @@ class AccountTable extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let options;
|
let options;
|
||||||
if (record.viewRule === "Admin") {
|
if (record.viewRule === "Admin" || record.name === "Is admin" || record.name === "Is global admin") {
|
||||||
options = [
|
options = [
|
||||||
{id: "Admin", name: "Admin"},
|
{id: "Admin", name: "Admin"},
|
||||||
{id: "Immutable", name: "Immutable"},
|
{id: "Immutable", name: "Immutable"},
|
||||||
|
@ -260,6 +260,13 @@ class AdapterListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
181
web/src/App.js
181
web/src/App.js
@ -17,7 +17,7 @@ import "./App.less";
|
|||||||
import {Helmet} from "react-helmet";
|
import {Helmet} from "react-helmet";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import {BarsOutlined, DownOutlined, LogoutOutlined, SettingOutlined} from "@ant-design/icons";
|
import {BarsOutlined, DownOutlined, LogoutOutlined, SettingOutlined} from "@ant-design/icons";
|
||||||
import {Avatar, Button, Card, ConfigProvider, Drawer, Dropdown, FloatButton, Layout, Menu, Result} from "antd";
|
import {Avatar, Button, Card, ConfigProvider, Drawer, Dropdown, FloatButton, Layout, Menu, Result, theme} from "antd";
|
||||||
import {Link, Redirect, Route, Switch, withRouter} from "react-router-dom";
|
import {Link, Redirect, Route, Switch, withRouter} from "react-router-dom";
|
||||||
import OrganizationListPage from "./OrganizationListPage";
|
import OrganizationListPage from "./OrganizationListPage";
|
||||||
import OrganizationEditPage from "./OrganizationEditPage";
|
import OrganizationEditPage from "./OrganizationEditPage";
|
||||||
@ -69,6 +69,8 @@ import SystemInfo from "./SystemInfo";
|
|||||||
import AdapterListPage from "./AdapterListPage";
|
import AdapterListPage from "./AdapterListPage";
|
||||||
import AdapterEditPage from "./AdapterEditPage";
|
import AdapterEditPage from "./AdapterEditPage";
|
||||||
import {withTranslation} from "react-i18next";
|
import {withTranslation} from "react-i18next";
|
||||||
|
import SelectThemeBox from "./SelectThemeBox";
|
||||||
|
import SessionListPage from "./SessionListPage";
|
||||||
|
|
||||||
const {Header, Footer, Content} = Layout;
|
const {Header, Footer, Content} = Layout;
|
||||||
|
|
||||||
@ -81,6 +83,8 @@ class App extends Component {
|
|||||||
account: undefined,
|
account: undefined,
|
||||||
uri: null,
|
uri: null,
|
||||||
menuVisible: false,
|
menuVisible: false,
|
||||||
|
themeAlgorithm: null,
|
||||||
|
logo: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
Setting.initServerUrl();
|
Setting.initServerUrl();
|
||||||
@ -95,6 +99,16 @@ class App extends Component {
|
|||||||
this.getAccount();
|
this.getAccount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
localStorage.getItem("theme") ?
|
||||||
|
this.setState({"themeAlgorithm": this.getTheme()}) : this.setState({"themeAlgorithm": theme.defaultAlgorithm});
|
||||||
|
this.setState({"logo": Setting.getLogo(localStorage.getItem("theme"))});
|
||||||
|
addEventListener("themeChange", (e) => {
|
||||||
|
this.setState({"themeAlgorithm": this.getTheme()});
|
||||||
|
this.setState({"logo": Setting.getLogo(localStorage.getItem("theme"))});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
// eslint-disable-next-line no-restricted-globals
|
// eslint-disable-next-line no-restricted-globals
|
||||||
const uri = location.pathname;
|
const uri = location.pathname;
|
||||||
@ -184,6 +198,10 @@ class App extends Component {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTheme() {
|
||||||
|
return Setting.Themes.find(t => t.key === localStorage.getItem("theme"))["style"];
|
||||||
|
}
|
||||||
|
|
||||||
setLanguage(account) {
|
setLanguage(account) {
|
||||||
const language = account?.language;
|
const language = account?.language;
|
||||||
if (language !== "" && language !== i18next.language) {
|
if (language !== "" && language !== i18next.language) {
|
||||||
@ -404,6 +422,10 @@ class App extends Component {
|
|||||||
"/tokens"
|
"/tokens"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
res.push(Setting.getItem(<Link to="/sessions">{i18next.t("general:Sessions")}</Link>,
|
||||||
|
"/sessions"
|
||||||
|
));
|
||||||
|
|
||||||
res.push(Setting.getItem(<Link to="/webhooks">{i18next.t("general:Webhooks")}</Link>,
|
res.push(Setting.getItem(<Link to="/webhooks">{i18next.t("general:Webhooks")}</Link>,
|
||||||
"/webhooks"
|
"/webhooks"
|
||||||
));
|
));
|
||||||
@ -465,54 +487,63 @@ class App extends Component {
|
|||||||
|
|
||||||
renderRouter() {
|
renderRouter() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<ConfigProvider theme={{
|
||||||
<Switch>
|
token: {
|
||||||
<Route exact path="/result" render={(props) => this.renderHomeIfLoggedIn(<ResultPage {...props} />)} />
|
colorPrimary: "rgb(89,54,213)",
|
||||||
<Route exact path="/result/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ResultPage {...props} />)} />
|
colorInfo: "rgb(89,54,213)",
|
||||||
<Route exact path="/" render={(props) => this.renderLoginIfNotLoggedIn(<HomePage account={this.state.account} {...props} />)} />
|
},
|
||||||
<Route exact path="/account" render={(props) => this.renderLoginIfNotLoggedIn(<AccountPage account={this.state.account} {...props} />)} />
|
algorithm: this.state.themeAlgorithm,
|
||||||
<Route exact path="/organizations" render={(props) => this.renderLoginIfNotLoggedIn(<OrganizationListPage account={this.state.account} {...props} />)} />
|
}}>
|
||||||
<Route exact path="/organizations/:organizationName" render={(props) => this.renderLoginIfNotLoggedIn(<OrganizationEditPage account={this.state.account} {...props} />)} />
|
<div>
|
||||||
<Route exact path="/organizations/:organizationName/users" render={(props) => this.renderLoginIfNotLoggedIn(<UserListPage account={this.state.account} {...props} />)} />
|
<Switch>
|
||||||
<Route exact path="/users" render={(props) => this.renderLoginIfNotLoggedIn(<UserListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/result" render={(props) => this.renderHomeIfLoggedIn(<ResultPage {...props} />)} />
|
||||||
<Route exact path="/users/:organizationName/:userName" render={(props) => <UserEditPage account={this.state.account} {...props} />} />
|
<Route exact path="/result/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ResultPage {...props} />)} />
|
||||||
<Route exact path="/roles" render={(props) => this.renderLoginIfNotLoggedIn(<RoleListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/" render={(props) => this.renderLoginIfNotLoggedIn(<HomePage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/roles/:organizationName/:roleName" render={(props) => this.renderLoginIfNotLoggedIn(<RoleEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/account" render={(props) => this.renderLoginIfNotLoggedIn(<AccountPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/permissions" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/organizations" render={(props) => this.renderLoginIfNotLoggedIn(<OrganizationListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/permissions/:organizationName/:permissionName" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/organizations/:organizationName" render={(props) => this.renderLoginIfNotLoggedIn(<OrganizationEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/models" render={(props) => this.renderLoginIfNotLoggedIn(<ModelListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/organizations/:organizationName/users" render={(props) => this.renderLoginIfNotLoggedIn(<UserListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/models/:organizationName/:modelName" render={(props) => this.renderLoginIfNotLoggedIn(<ModelEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/users" render={(props) => this.renderLoginIfNotLoggedIn(<UserListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/adapters" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/users/:organizationName/:userName" render={(props) => <UserEditPage account={this.state.account} {...props} />} />
|
||||||
<Route exact path="/adapters/:organizationName/:adapterName" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/roles" render={(props) => this.renderLoginIfNotLoggedIn(<RoleListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/providers" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/roles/:organizationName/:roleName" render={(props) => this.renderLoginIfNotLoggedIn(<RoleEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/providers/:organizationName/:providerName" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/permissions" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/applications" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/permissions/:organizationName/:permissionName" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/applications/:organizationName/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/models" render={(props) => this.renderLoginIfNotLoggedIn(<ModelListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/resources" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/models/:organizationName/:modelName" render={(props) => this.renderLoginIfNotLoggedIn(<ModelEditPage account={this.state.account} {...props} />)} />
|
||||||
{/* <Route exact path="/resources/:resourceName" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceEditPage account={this.state.account} {...props} />)}/>*/}
|
<Route exact path="/adapters" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/ldap/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/adapters/:organizationName/:adapterName" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/ldap/sync/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapSyncPage account={this.state.account} {...props} />)} />
|
<Route exact path="/providers" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/tokens" render={(props) => this.renderLoginIfNotLoggedIn(<TokenListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/providers/:organizationName/:providerName" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/tokens/:tokenName" render={(props) => this.renderLoginIfNotLoggedIn(<TokenEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/applications" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/webhooks" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/applications/:organizationName/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<ApplicationEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/webhooks/:webhookName" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/resources" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/syncers" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerListPage account={this.state.account} {...props} />)} />
|
{/* <Route exact path="/resources/:resourceName" render={(props) => this.renderLoginIfNotLoggedIn(<ResourceEditPage account={this.state.account} {...props} />)}/>*/}
|
||||||
<Route exact path="/syncers/:syncerName" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/ldap/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/certs" render={(props) => this.renderLoginIfNotLoggedIn(<CertListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/ldap/sync/:ldapId" render={(props) => this.renderLoginIfNotLoggedIn(<LdapSyncPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/certs/:certName" render={(props) => this.renderLoginIfNotLoggedIn(<CertEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/tokens" render={(props) => this.renderLoginIfNotLoggedIn(<TokenListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/products" render={(props) => this.renderLoginIfNotLoggedIn(<ProductListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/sessions" render={(props) => this.renderLoginIfNotLoggedIn(<SessionListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/products/:productName" render={(props) => this.renderLoginIfNotLoggedIn(<ProductEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/tokens/:tokenName" render={(props) => this.renderLoginIfNotLoggedIn(<TokenEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/products/:productName/buy" render={(props) => this.renderLoginIfNotLoggedIn(<ProductBuyPage account={this.state.account} {...props} />)} />
|
<Route exact path="/webhooks" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/payments" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/webhooks/:webhookName" render={(props) => this.renderLoginIfNotLoggedIn(<WebhookEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/payments/:paymentName" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentEditPage account={this.state.account} {...props} />)} />
|
<Route exact path="/syncers" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/payments/:paymentName/result" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentResultPage account={this.state.account} {...props} />)} />
|
<Route exact path="/syncers/:syncerName" render={(props) => this.renderLoginIfNotLoggedIn(<SyncerEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/records" render={(props) => this.renderLoginIfNotLoggedIn(<RecordListPage account={this.state.account} {...props} />)} />
|
<Route exact path="/certs" render={(props) => this.renderLoginIfNotLoggedIn(<CertListPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/.well-known/openid-configuration" render={(props) => <OdicDiscoveryPage />} />
|
<Route exact path="/certs/:certName" render={(props) => this.renderLoginIfNotLoggedIn(<CertEditPage account={this.state.account} {...props} />)} />
|
||||||
<Route exact path="/sysinfo" render={(props) => this.renderLoginIfNotLoggedIn(<SystemInfo account={this.state.account} {...props} />)} />
|
<Route exact path="/products" render={(props) => this.renderLoginIfNotLoggedIn(<ProductListPage account={this.state.account} {...props} />)} />
|
||||||
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
|
<Route exact path="/products/:productName" render={(props) => this.renderLoginIfNotLoggedIn(<ProductEditPage account={this.state.account} {...props} />)} />
|
||||||
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
|
<Route exact path="/products/:productName/buy" render={(props) => this.renderLoginIfNotLoggedIn(<ProductBuyPage account={this.state.account} {...props} />)} />
|
||||||
</Switch>
|
<Route exact path="/payments" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentListPage account={this.state.account} {...props} />)} />
|
||||||
</div>
|
<Route exact path="/payments/:paymentName" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentEditPage account={this.state.account} {...props} />)} />
|
||||||
|
<Route exact path="/payments/:paymentName/result" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentResultPage account={this.state.account} {...props} />)} />
|
||||||
|
<Route exact path="/records" render={(props) => this.renderLoginIfNotLoggedIn(<RecordListPage account={this.state.account} {...props} />)} />
|
||||||
|
<Route exact path="/.well-known/openid-configuration" render={(props) => <OdicDiscoveryPage />} />
|
||||||
|
<Route exact path="/sysinfo" render={(props) => this.renderLoginIfNotLoggedIn(<SystemInfo account={this.state.account} {...props} />)} />
|
||||||
|
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
|
||||||
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
</ConfigProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,30 +563,27 @@ class App extends Component {
|
|||||||
if (!Setting.isMobile()) {
|
if (!Setting.isMobile()) {
|
||||||
return (
|
return (
|
||||||
<Layout id="parent-area">
|
<Layout id="parent-area">
|
||||||
<Header style={{marginBottom: "3px", paddingInline: 0}}>
|
<Header style={{marginBottom: "3px", paddingInline: 0, backgroundColor: this.state.themeAlgorithm === theme.darkAlgorithm ? "black" : "white"}}>
|
||||||
{
|
{
|
||||||
Setting.isMobile() ? null : (
|
Setting.isMobile() ? null : (
|
||||||
<Link to={"/"}>
|
<Link to={"/"}>
|
||||||
<div className="logo" />
|
<div className="logo" style={{background: `url(${this.state.logo})`}} />
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<div>
|
<Menu
|
||||||
<Menu
|
items={this.renderMenu()}
|
||||||
// theme="dark"
|
mode={(Setting.isMobile() && this.isStartPages()) ? "inline" : "horizontal"}
|
||||||
items={this.renderMenu()}
|
selectedKeys={[`${this.state.selectedMenuKey}`]}
|
||||||
mode={(Setting.isMobile() && this.isStartPages()) ? "inline" : "horizontal"}
|
style={{position: "absolute", left: "145px", backgroundColor: this.state.themeAlgorithm === theme.darkAlgorithm ? "black" : "white"}}
|
||||||
selectedKeys={[`${this.state.selectedMenuKey}`]}
|
/>
|
||||||
style={{lineHeight: "64px", position: "absolute", left: "145px", right: "200px"}}
|
{
|
||||||
>
|
this.renderAccount()
|
||||||
</Menu>
|
}
|
||||||
{
|
{this.state.account && <SelectThemeBox themes={this.state.account.organization.themes} />}
|
||||||
this.renderAccount()
|
{this.state.account && <SelectLanguageBox languages={this.state.account.organization.languages} />}
|
||||||
}
|
|
||||||
{this.state.account && <SelectLanguageBox languages={this.state.account.organization.languages} />}
|
|
||||||
</div>
|
|
||||||
</Header>
|
</Header>
|
||||||
<Content style={{backgroundColor: "#f5f5f5", alignItems: "stretch", display: "flex", flexDirection: "column"}}>
|
<Content style={{alignItems: "stretch", display: "flex", flexDirection: "column"}}>
|
||||||
<Card className="content-warp-card">
|
<Card className="content-warp-card">
|
||||||
{
|
{
|
||||||
this.renderRouter()
|
this.renderRouter()
|
||||||
@ -570,11 +598,11 @@ class App extends Component {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Header style={{padding: "0", marginBottom: "3px"}}>
|
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: this.state.themeAlgorithm === theme.darkAlgorithm ? "black" : "white"}}>
|
||||||
{
|
{
|
||||||
Setting.isMobile() ? null : (
|
Setting.isMobile() ? null : (
|
||||||
<Link to={"/"}>
|
<Link to={"/"}>
|
||||||
<div className="logo" />
|
<div className="logo" style={{background: `url(${this.state.logo})`}} />
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -592,12 +620,11 @@ class App extends Component {
|
|||||||
<Button icon={<BarsOutlined />} onClick={this.showMenu} type="text">
|
<Button icon={<BarsOutlined />} onClick={this.showMenu} type="text">
|
||||||
{i18next.t("general:Menu")}
|
{i18next.t("general:Menu")}
|
||||||
</Button>
|
</Button>
|
||||||
<div style = {{float: "right"}}>
|
{
|
||||||
{
|
this.renderAccount()
|
||||||
this.renderAccount()
|
}
|
||||||
}
|
{this.state.account && <SelectThemeBox themes={this.state.account.organization.themes} />}
|
||||||
{this.state.account && <SelectLanguageBox languages={this.state.account.organization.languages} />}
|
{this.state.account && <SelectLanguageBox languages={this.state.account.organization.languages} />}
|
||||||
</div>
|
|
||||||
</Header>
|
</Header>
|
||||||
<Content style={{display: "flex", flexDirection: "column"}} >{
|
<Content style={{display: "flex", flexDirection: "column"}} >{
|
||||||
this.renderRouter()}
|
this.renderRouter()}
|
||||||
@ -617,12 +644,10 @@ class App extends Component {
|
|||||||
{!this.state.account ? null : <div style={{display: "none"}} id="CasdoorApplicationName" value={this.state.account.signupApplication} />}
|
{!this.state.account ? null : <div style={{display: "none"}} id="CasdoorApplicationName" value={this.state.account.signupApplication} />}
|
||||||
<Footer id="footer" style={
|
<Footer id="footer" style={
|
||||||
{
|
{
|
||||||
borderTop: "1px solid #e8e8e8",
|
|
||||||
backgroundColor: "white",
|
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
Powered by <a target="_blank" href="https://casdoor.org" rel="noreferrer"><img style={{paddingBottom: "3px"}} height={"20px"} alt={"Casdoor"} src={`${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`} /></a>
|
Powered by <a target="_blank" href="https://casdoor.org" rel="noreferrer"><img style={{paddingBottom: "3px"}} height={"20px"} alt={"Casdoor"} src={this.state.logo} /></a>
|
||||||
</Footer>
|
</Footer>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
@ -690,6 +715,7 @@ class App extends Component {
|
|||||||
colorPrimary: "rgb(89,54,213)",
|
colorPrimary: "rgb(89,54,213)",
|
||||||
colorInfo: "rgb(89,54,213)",
|
colorInfo: "rgb(89,54,213)",
|
||||||
},
|
},
|
||||||
|
algorithm: this.state.themeAlgorithm,
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
this.renderPage()
|
this.renderPage()
|
||||||
@ -711,6 +737,7 @@ class App extends Component {
|
|||||||
colorPrimary: "rgb(89,54,213)",
|
colorPrimary: "rgb(89,54,213)",
|
||||||
colorInfo: "rgb(89,54,213)",
|
colorInfo: "rgb(89,54,213)",
|
||||||
},
|
},
|
||||||
|
algorithm: this.state.themeAlgorithm,
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
this.renderPage()
|
this.renderPage()
|
||||||
|
@ -13,14 +13,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.App-header {
|
.App-header {
|
||||||
background-color: #282c34;
|
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: calc(10px + 2vmin);
|
font-size: calc(10px + 2vmin);
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.App-link {
|
.App-link {
|
||||||
@ -41,7 +39,6 @@ img {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-logo {
|
.panel-logo {
|
||||||
@ -55,7 +52,7 @@ img {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
width: 45px;
|
width: 45px;
|
||||||
height: 65px;
|
height: 100%;
|
||||||
float: right;
|
float: right;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
@ -64,9 +61,32 @@ img {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-form .language-box {
|
||||||
|
height: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-box {
|
||||||
|
background: url("@{StaticBaseUrl}/img/muti_language.svg");
|
||||||
|
background-size: 25px, 25px;
|
||||||
|
background-position: center !important;
|
||||||
|
background-repeat: no-repeat !important;
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 45px;
|
||||||
|
height: 100%;
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f5f5 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.rightDropDown {
|
.rightDropDown {
|
||||||
|
border-radius: 7px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,3 +148,9 @@ img {
|
|||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-menu-horizontal {
|
||||||
|
border-bottom: none !important;
|
||||||
|
margin-right: 30px;
|
||||||
|
right: 230px;
|
||||||
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Card, Col, Input, Popover, Radio, Row, Select, Switch, Upload} from "antd";
|
import {Button, Card, Col, Input, Popover, Radio, Result, Row, Select, Switch, Upload} from "antd";
|
||||||
import {CopyOutlined, LinkOutlined, UploadOutlined} from "@ant-design/icons";
|
import {CopyOutlined, LinkOutlined, UploadOutlined} from "@ant-design/icons";
|
||||||
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||||
import * as CertBackend from "./backend/CertBackend";
|
import * as CertBackend from "./backend/CertBackend";
|
||||||
@ -103,6 +103,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
uploading: false,
|
uploading: false,
|
||||||
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
||||||
samlMetadata: null,
|
samlMetadata: null,
|
||||||
|
isAuthorized: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,9 +130,15 @@ class ApplicationEditPage extends React.Component {
|
|||||||
getOrganizations() {
|
getOrganizations() {
|
||||||
OrganizationBackend.getOrganizations("admin")
|
OrganizationBackend.getOrganizations("admin")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
if (res?.status === "error") {
|
||||||
organizations: (res.msg === undefined) ? res : [],
|
this.setState({
|
||||||
});
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
organizations: (res.msg === undefined) ? res : [],
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,12 +343,9 @@ class ApplicationEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("application:Token format"), i18next.t("application:Token format - Tooltip"))} :
|
{Setting.getLabel(i18next.t("application:Token format"), i18next.t("application:Token format - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.application.tokenFormat} onChange={(value => {this.updateApplicationField("tokenFormat", value);})}>
|
<Select virtual={false} style={{width: "100%"}} value={this.state.application.tokenFormat} onChange={(value => {this.updateApplicationField("tokenFormat", value);})}
|
||||||
{
|
options={["JWT", "JWT-Empty"].map((item) => Setting.getOption(item, item))}
|
||||||
["JWT", "JWT-Empty"]
|
/>
|
||||||
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -599,6 +603,16 @@ class ApplicationEditPage extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col span={(Setting.isMobile()) ? 19 : 6}>
|
||||||
|
{Setting.getLabel(i18next.t("application:Enable link accounts that with the same email"), i18next.t("application:Enable link accounts that with the same email - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={1} >
|
||||||
|
<Switch checked={this.state.application.enableLinkWithEmail} onChange={checked => {
|
||||||
|
this.updateApplicationField("enableLinkWithEmail", checked);
|
||||||
|
}} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("general:Preview"), i18next.t("general:Preview - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Preview"), i18next.t("general:Preview - Tooltip"))} :
|
||||||
@ -726,7 +740,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
renderSignupSigninPreview() {
|
renderSignupSigninPreview() {
|
||||||
let signUpUrl = `/signup/${this.state.application.name}`;
|
let signUpUrl = `/signup/${this.state.application.name}`;
|
||||||
const signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${this.state.application.redirectUris[0]}&scope=read&state=casdoor`;
|
const signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${this.state.application.redirectUris[0]}&scope=read&state=casdoor`;
|
||||||
const maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "100%", width: "100%", background: "rgba(0,0,0,0.4)"};
|
const maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "97%", width: "100%", background: "rgba(0,0,0,0.4)"};
|
||||||
if (!this.state.application.enablePassword) {
|
if (!this.state.application.enablePassword) {
|
||||||
signUpUrl = signInUrl.replace("/login/oauth/authorize", "/signup/oauth/authorize");
|
signUpUrl = signInUrl.replace("/login/oauth/authorize", "/signup/oauth/authorize");
|
||||||
}
|
}
|
||||||
@ -742,15 +756,19 @@ class ApplicationEditPage extends React.Component {
|
|||||||
{i18next.t("application:Copy signup page URL")}
|
{i18next.t("application:Copy signup page URL")}
|
||||||
</Button>
|
</Button>
|
||||||
<br />
|
<br />
|
||||||
<div style={{position: "relative", width: previewWidth, border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
|
<div style={{position: "relative", width: previewWidth, border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", overflow: "auto"}}>
|
||||||
{
|
{
|
||||||
this.state.application.enablePassword ? (
|
this.state.application.enablePassword ? (
|
||||||
<SignupPage application={this.state.application} />
|
<div className="loginBackground" style={{backgroundImage: `url(${this.state.application?.formBackgroundUrl})`, overflow: "auto"}}>
|
||||||
|
<SignupPage application={this.state.application} preview = "auto" />
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<LoginPage type={"login"} mode={"signup"} application={this.state.application} />
|
<div className="loginBackground" style={{backgroundImage: `url(${this.state.application?.formBackgroundUrl})`, overflow: "auto"}}>
|
||||||
|
<LoginPage type={"login"} mode={"signup"} application={this.state.application} preview = "auto" />
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<div style={maskStyle} />
|
<div style={{overflow: "auto", ...maskStyle}} />
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={previewGrid}>
|
<Col span={previewGrid}>
|
||||||
@ -762,9 +780,11 @@ class ApplicationEditPage extends React.Component {
|
|||||||
{i18next.t("application:Copy signin page URL")}
|
{i18next.t("application:Copy signin page URL")}
|
||||||
</Button>
|
</Button>
|
||||||
<br />
|
<br />
|
||||||
<div style={{position: "relative", width: previewWidth, border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
|
<div style={{position: "relative", width: previewWidth, border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", overflow: "auto"}}>
|
||||||
<LoginPage type={"login"} mode={"signin"} application={this.state.application} />
|
<div className="loginBackground" style={{backgroundImage: `url(${this.state.application?.formBackgroundUrl})`, overflow: "auto"}}>
|
||||||
<div style={maskStyle} />
|
<LoginPage type={"login"} mode={"signin"} application={this.state.application} preview = "auto" />
|
||||||
|
</div>
|
||||||
|
<div style={{overflow: "auto", ...maskStyle}} />
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
@ -832,6 +852,17 @@ class ApplicationEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (!this.state.isAuthorized) {
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status="403"
|
||||||
|
title="403 Unauthorized"
|
||||||
|
subTitle={i18next.t("general:Sorry, you do not have permission to access this page or logged in status invalid.")}
|
||||||
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Button, Col, List, Popconfirm, Row, Table, Tooltip} from "antd";
|
import {Button, Col, List, Popconfirm, Result, Row, Table, Tooltip} from "antd";
|
||||||
import {EditOutlined} from "@ant-design/icons";
|
import {EditOutlined} from "@ant-design/icons";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
@ -36,6 +36,7 @@ class ApplicationListPage extends BaseListPage {
|
|||||||
loading: false,
|
loading: false,
|
||||||
searchText: "",
|
searchText: "",
|
||||||
searchedColumn: "",
|
searchedColumn: "",
|
||||||
|
isAuthorized: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,6 +259,17 @@ class ApplicationListPage extends BaseListPage {
|
|||||||
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!this.state.isAuthorized) {
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status="403"
|
||||||
|
title="403 Unauthorized"
|
||||||
|
subTitle={i18next.t("general:Sorry, you do not have permission to access this page or logged in status invalid.")}
|
||||||
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={applications} rowKey="name" size="middle" bordered pagination={paginationProps}
|
<Table scroll={{x: "max-content"}} columns={columns} dataSource={applications} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||||
@ -292,6 +304,13 @@ class ApplicationListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Input, Space} from "antd";
|
import {Button, Input, Result, Space} from "antd";
|
||||||
import {SearchOutlined} from "@ant-design/icons";
|
import {SearchOutlined} from "@ant-design/icons";
|
||||||
import Highlighter from "react-highlight-words";
|
import Highlighter from "react-highlight-words";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
class BaseListPage extends React.Component {
|
class BaseListPage extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -127,6 +128,17 @@ class BaseListPage extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (!this.state.isAuthorized) {
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status="403"
|
||||||
|
title="403 Unauthorized"
|
||||||
|
subTitle={i18next.t("general:Sorry, you do not have permission to access this page or logged in status invalid.")}
|
||||||
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
|
@ -227,6 +227,13 @@ class CertListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -153,7 +153,7 @@ export const CropperDiv = (props) => {
|
|||||||
<Row style={{width: "100%", marginBottom: "20px"}}>
|
<Row style={{width: "100%", marginBottom: "20px"}}>
|
||||||
<input style={{display: "none"}} ref={input => uploadButton = input} type="file" accept="image/*" onChange={onChange} />
|
<input style={{display: "none"}} ref={input => uploadButton = input} type="file" accept="image/*" onChange={onChange} />
|
||||||
<Button block onClick={selectFile}>{i18next.t("user:Select a photo...")}</Button>
|
<Button block onClick={selectFile}>{i18next.t("user:Select a photo...")}</Button>
|
||||||
<Select
|
<Select virtual={false}
|
||||||
style={{width: "100%"}}
|
style={{width: "100%"}}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
placeholder={i18next.t("user:Please select avatar from resources")}
|
placeholder={i18next.t("user:Please select avatar from resources")}
|
||||||
|
@ -200,6 +200,13 @@ class ModelListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -165,12 +165,9 @@ class OrganizationEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:Password type"), i18next.t("general:Password type - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Password type"), i18next.t("general:Password type - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.passwordType} onChange={(value => {this.updateOrganizationField("passwordType", value);})}>
|
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.passwordType} onChange={(value => {this.updateOrganizationField("passwordType", value);})}
|
||||||
{
|
options={["plain", "salt", "md5-salt", "bcrypt", "pbkdf2-salt", "argon2id"].map(item => Setting.getOption(item, item))}
|
||||||
["plain", "salt", "md5-salt", "bcrypt", "pbkdf2-salt", "argon2id"]
|
/>
|
||||||
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -225,11 +222,9 @@ class OrganizationEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:Default application"), i18next.t("general:Default application - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Default application"), i18next.t("general:Default application - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.defaultApplication} onChange={(value => {this.updateOrganizationField("defaultApplication", value);})}>
|
<Select virtual={false} style={{width: "100%"}} value={this.state.organization.defaultApplication} onChange={(value => {this.updateOrganizationField("defaultApplication", value);})}
|
||||||
{
|
options={this.state.applications?.map((item) => Setting.getOption(item.name, item.name))
|
||||||
this.state.applications?.map((item, index) => <Option key={index} value={item.name}>{item.name}</Option>)
|
} />
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
@ -251,7 +251,7 @@ class OrganizationListPage extends BaseListPage {
|
|||||||
<Result
|
<Result
|
||||||
status="403"
|
status="403"
|
||||||
title="403 Unauthorized"
|
title="403 Unauthorized"
|
||||||
subTitle={i18next.t("general:Sorry, you do not have permission to access this page.")}
|
subTitle={i18next.t("general:Sorry, you do not have permission to access this page or logged in status invalid.")}
|
||||||
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -302,7 +302,7 @@ class PaymentEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("payment:Invoice type"), i18next.t("payment:Invoice type - Tooltip"))} :
|
{Setting.getLabel(i18next.t("payment:Invoice type"), i18next.t("payment:Invoice type - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select disabled={this.state.payment.invoiceUrl !== ""} virtual={false} style={{width: "100%"}} value={this.state.payment.invoiceType} onChange={(value => {
|
<Select virtual={false} disabled={this.state.payment.invoiceUrl !== ""} style={{width: "100%"}} value={this.state.payment.invoiceType} onChange={(value => {
|
||||||
this.updatePaymentField("invoiceType", value);
|
this.updatePaymentField("invoiceType", value);
|
||||||
if (value === "Individual") {
|
if (value === "Individual") {
|
||||||
this.updatePaymentField("invoiceTitle", this.state.payment.personName);
|
this.updatePaymentField("invoiceTitle", this.state.payment.personName);
|
||||||
|
@ -278,6 +278,13 @@ class PaymentListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -24,8 +24,6 @@ import * as ModelBackend from "./backend/ModelBackend";
|
|||||||
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||||
import moment from "moment/moment";
|
import moment from "moment/moment";
|
||||||
|
|
||||||
const {Option} = Select;
|
|
||||||
|
|
||||||
class PermissionEditPage extends React.Component {
|
class PermissionEditPage extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -163,16 +161,13 @@ class PermissionEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.owner} onChange={(owner => {
|
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.owner} onChange={(owner => {
|
||||||
this.updatePermissionField("owner", owner);
|
this.updatePermissionField("owner", owner);
|
||||||
|
|
||||||
this.getUsers(owner);
|
this.getUsers(owner);
|
||||||
this.getRoles(owner);
|
this.getRoles(owner);
|
||||||
this.getModels(owner);
|
this.getModels(owner);
|
||||||
this.getResources(owner);
|
this.getResources(owner);
|
||||||
})}>
|
})}
|
||||||
{
|
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
|
||||||
this.state.organizations.map((organization, index) => <Option key={index} value={organization.name}>{organization.name}</Option>)
|
} />
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -202,11 +197,9 @@ class PermissionEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.model} onChange={(model => {
|
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.model} onChange={(model => {
|
||||||
this.updatePermissionField("model", model);
|
this.updatePermissionField("model", model);
|
||||||
})}>
|
})}
|
||||||
{
|
options={this.state.models.map((model) => Setting.getOption(model.name, model.name))
|
||||||
this.state.models.map((model, index) => <Option key={index} value={model.name}>{model.name}</Option>)
|
} />
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -224,11 +217,10 @@ class PermissionEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
|
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.users} onChange={(value => {this.updatePermissionField("users", value);})}>
|
<Select mode="tags" style={{width: "100%"}} value={this.state.permission.users}
|
||||||
{
|
onChange={(value => {this.updatePermissionField("users", value);})}
|
||||||
this.state.users.map((user, index) => <Option key={index} value={`${user.owner}/${user.name}`}>{`${user.owner}/${user.name}`}</Option>)
|
options={this.state.users.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`))}
|
||||||
}
|
/>
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -236,11 +228,10 @@ class PermissionEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
|
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} disabled={!this.hasRoleDefinition(this.state.model)} mode="tags" style={{width: "100%"}} value={this.state.permission.roles} onChange={(value => {this.updatePermissionField("roles", value);})}>
|
<Select virtual={false} disabled={!this.hasRoleDefinition(this.state.model)} mode="tags" style={{width: "100%"}} value={this.state.permission.roles}
|
||||||
{
|
onChange={(value => {this.updatePermissionField("roles", value);})}
|
||||||
this.state.roles.filter(roles => (roles.owner !== this.state.roles.owner || roles.name !== this.state.roles.name)).map((permission, index) => <Option key={index} value={`${permission.owner}/${permission.name}`}>{`${permission.owner}/${permission.name}`}</Option>)
|
options={this.state.roles.filter(roles => (roles.owner !== this.state.roles.owner || roles.name !== this.state.roles.name)).map((permission) => Setting.getOption(`${permission.owner}/${permission.name}`, `${permission.owner}/${permission.name}`))
|
||||||
}
|
} />
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -248,13 +239,12 @@ class PermissionEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("role:Sub domains"), i18next.t("role:Sub domains - Tooltip"))} :
|
{Setting.getLabel(i18next.t("role:Sub domains"), i18next.t("role:Sub domains - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.domains} onChange={(value => {
|
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.domains}
|
||||||
this.updatePermissionField("domains", value);
|
onChange={(value => {
|
||||||
})}>
|
this.updatePermissionField("domains", value);
|
||||||
{
|
})}
|
||||||
this.state.permission.domains.map((domain, index) => <Option key={index} value={domain}>{domain}</Option>)
|
options={this.state.permission.domains.map((domain) => Setting.getOption(domain, domain))
|
||||||
}
|
} />
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -264,14 +254,12 @@ class PermissionEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.resourceType} onChange={(value => {
|
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.resourceType} onChange={(value => {
|
||||||
this.updatePermissionField("resourceType", value);
|
this.updatePermissionField("resourceType", value);
|
||||||
})}>
|
})}
|
||||||
{
|
options={[
|
||||||
[
|
{value: "Application", name: i18next.t("general:Application")},
|
||||||
{id: "Application", name: i18next.t("general:Application")},
|
{value: "TreeNode", name: i18next.t("permission:TreeNode")},
|
||||||
{id: "TreeNode", name: i18next.t("permission:TreeNode")},
|
].map((item) => Setting.getOption(item.name, item.value))}
|
||||||
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
/>
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -279,11 +267,10 @@ class PermissionEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("permission:Resources"), i18next.t("permission:Resources - Tooltip"))} :
|
{Setting.getLabel(i18next.t("permission:Resources"), i18next.t("permission:Resources - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.resources} onChange={(value => {this.updatePermissionField("resources", value);})}>
|
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.resources}
|
||||||
{
|
onChange={(value => {this.updatePermissionField("resources", value);})}
|
||||||
this.state.resources.map((resource, index) => <Option key={index} value={`${resource.name}`}>{`${resource.name}`}</Option>)
|
options={this.state.resources.map((resource) => Setting.getOption(`${resource.name}`, `${resource.name}`))
|
||||||
}
|
} />
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -293,15 +280,13 @@ class PermissionEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.actions} onChange={(value => {
|
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.permission.actions} onChange={(value => {
|
||||||
this.updatePermissionField("actions", value);
|
this.updatePermissionField("actions", value);
|
||||||
})}>
|
})}
|
||||||
{
|
options={[
|
||||||
[
|
{value: "Read", name: i18next.t("permission:Read")},
|
||||||
{id: "Read", name: i18next.t("permission:Read")},
|
{value: "Write", name: i18next.t("permission:Write")},
|
||||||
{id: "Write", name: i18next.t("permission:Write")},
|
{value: "Admin", name: i18next.t("permission:Admin")},
|
||||||
{id: "Admin", name: i18next.t("permission:Admin")},
|
].map((item) => Setting.getOption(item.name, item.value))}
|
||||||
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
/>
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -311,14 +296,12 @@ class PermissionEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.effect} onChange={(value => {
|
<Select virtual={false} style={{width: "100%"}} value={this.state.permission.effect} onChange={(value => {
|
||||||
this.updatePermissionField("effect", value);
|
this.updatePermissionField("effect", value);
|
||||||
})}>
|
})}
|
||||||
{
|
options={[
|
||||||
[
|
{value: "Allow", name: i18next.t("permission:Allow")},
|
||||||
{id: "Allow", name: i18next.t("permission:Allow")},
|
{value: "Deny", name: i18next.t("permission:Deny")},
|
||||||
{id: "Deny", name: i18next.t("permission:Deny")},
|
].map((item) => Setting.getOption(item.name, item.value))}
|
||||||
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
/>
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -366,7 +349,7 @@ class PermissionEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("permission:State"), i18next.t("permission:State - Tooltip"))} :
|
{Setting.getLabel(i18next.t("permission:State"), i18next.t("permission:State - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select disabled={!Setting.isLocalAdminUser(this.props.account)} virtual={false} style={{width: "100%"}} value={this.state.permission.state} onChange={(value => {
|
<Select virtual={false} disabled={!Setting.isLocalAdminUser(this.props.account)} style={{width: "100%"}} value={this.state.permission.state} onChange={(value => {
|
||||||
if (this.state.permission.state !== value) {
|
if (this.state.permission.state !== value) {
|
||||||
if (value === "Approved") {
|
if (value === "Approved") {
|
||||||
this.updatePermissionField("approver", this.props.account.name);
|
this.updatePermissionField("approver", this.props.account.name);
|
||||||
@ -378,14 +361,12 @@ class PermissionEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updatePermissionField("state", value);
|
this.updatePermissionField("state", value);
|
||||||
})}>
|
})}
|
||||||
{
|
options={[
|
||||||
[
|
{value: "Approved", name: i18next.t("permission:Approved")},
|
||||||
{id: "Approved", name: i18next.t("permission:Approved")},
|
{value: "Pending", name: i18next.t("permission:Pending")},
|
||||||
{id: "Pending", name: i18next.t("permission:Pending")},
|
].map((item) => Setting.getOption(item.name, item.value))}
|
||||||
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
/>
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -358,6 +358,13 @@ class PermissionListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -295,6 +295,13 @@ class ProductListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Button, Popconfirm, Table} from "antd";
|
import {Button, Popconfirm, Result, Table} from "antd";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import * as ProviderBackend from "./backend/ProviderBackend";
|
import * as ProviderBackend from "./backend/ProviderBackend";
|
||||||
@ -36,6 +36,7 @@ class ProviderListPage extends BaseListPage {
|
|||||||
loading: false,
|
loading: false,
|
||||||
searchText: "",
|
searchText: "",
|
||||||
searchedColumn: "",
|
searchedColumn: "",
|
||||||
|
isAuthorized: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
newProvider() {
|
newProvider() {
|
||||||
@ -227,6 +228,17 @@ class ProviderListPage extends BaseListPage {
|
|||||||
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!this.state.isAuthorized) {
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status="403"
|
||||||
|
title="403 Unauthorized"
|
||||||
|
subTitle={i18next.t("general:Sorry, you do not have permission to access this page or logged in status invalid.")}
|
||||||
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={providers} rowKey="name" size="middle" bordered pagination={paginationProps}
|
<Table scroll={{x: "max-content"}} columns={columns} dataSource={providers} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||||
@ -268,6 +280,13 @@ class ProviderListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -179,7 +179,7 @@ class ProviderTable extends React.Component {
|
|||||||
// width: '120px',
|
// width: '120px',
|
||||||
// render: (text, record, index) => {
|
// render: (text, record, index) => {
|
||||||
// return (
|
// return (
|
||||||
// <Select virtual={false} style={{width: '100%'}} value={text} onChange={(value => {
|
// <Select virtual={false} style={{width: '100%'}} value={text} onChange={(value => {
|
||||||
// this.updateField(table, index, 'alertType', value);
|
// this.updateField(table, index, 'alertType', value);
|
||||||
// })}>
|
// })}>
|
||||||
// {
|
// {
|
||||||
|
@ -222,6 +222,13 @@ class RecordListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.data.includes("Please login first")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -37,7 +37,11 @@ export const ResetModal = (props) => {
|
|||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
if (dest === "") {
|
if (dest === "") {
|
||||||
Setting.showMessage("error", i18next.t("user:Empty " + destType));
|
if (destType === "phone") {
|
||||||
|
Setting.showMessage("error", i18next.t("user:Phone cannot be empty"));
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", i18next.t("user:Email cannot be empty"));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (code === "") {
|
if (code === "") {
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Popconfirm, Table, Upload} from "antd";
|
import {Button, Popconfirm, Result, Table, Upload} from "antd";
|
||||||
import {UploadOutlined} from "@ant-design/icons";
|
import {UploadOutlined} from "@ant-design/icons";
|
||||||
import copy from "copy-to-clipboard";
|
import copy from "copy-to-clipboard";
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
@ -37,6 +37,7 @@ class ResourceListPage extends BaseListPage {
|
|||||||
searchedColumn: "",
|
searchedColumn: "",
|
||||||
fileList: [],
|
fileList: [],
|
||||||
uploading: false,
|
uploading: false,
|
||||||
|
isAuthorized: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +273,17 @@ class ResourceListPage extends BaseListPage {
|
|||||||
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!this.state.isAuthorized) {
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status="403"
|
||||||
|
title="403 Unauthorized"
|
||||||
|
subTitle={i18next.t("general:Sorry, you do not have permission to access this page or logged in status invalid.")}
|
||||||
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={resources} rowKey="name" size="middle" bordered pagination={paginationProps}
|
<Table scroll={{x: "max-content"}} columns={columns} dataSource={resources} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||||
@ -308,6 +320,13 @@ class ResourceListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.data.includes("Please login first")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -16,11 +16,9 @@ import React from "react";
|
|||||||
import {Button, Card, Col, Input, Row, Select, Switch} from "antd";
|
import {Button, Card, Col, Input, Row, Select, Switch} from "antd";
|
||||||
import * as RoleBackend from "./backend/RoleBackend";
|
import * as RoleBackend from "./backend/RoleBackend";
|
||||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||||
import * as UserBackend from "./backend/UserBackend";
|
|
||||||
import * as Setting from "./Setting";
|
import * as Setting from "./Setting";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import * as UserBackend from "./backend/UserBackend";
|
||||||
const {Option} = Select;
|
|
||||||
|
|
||||||
class RoleEditPage extends React.Component {
|
class RoleEditPage extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -113,11 +111,9 @@ class RoleEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.role.owner} onChange={(value => {this.updateRoleField("owner", value);})}>
|
<Select virtual={false} style={{width: "100%"}} value={this.state.role.owner} onChange={(value => {this.updateRoleField("owner", value);})}
|
||||||
{
|
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
|
||||||
this.state.organizations.map((organization, index) => <Option key={index} value={organization.name}>{organization.name}</Option>)
|
} />
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -145,11 +141,10 @@ class RoleEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
|
{Setting.getLabel(i18next.t("role:Sub users"), i18next.t("role:Sub users - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.users} onChange={(value => {this.updateRoleField("users", value);})}>
|
<Select mode="tags" style={{width: "100%"}} value={this.state.role.users}
|
||||||
{
|
onChange={(value => {this.updateRoleField("users", value);})}
|
||||||
this.state.users.map((user, index) => <Option key={index} value={`${user.owner}/${user.name}`}>{`${user.owner}/${user.name}`}</Option>)
|
options={this.state.users.map((user) => Setting.getOption(`${user.owner}/${user.name}`, `${user.owner}/${user.name}`))}
|
||||||
}
|
/>
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -157,11 +152,9 @@ class RoleEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
|
{Setting.getLabel(i18next.t("role:Sub roles"), i18next.t("role:Sub roles - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.roles} onChange={(value => {this.updateRoleField("roles", value);})}>
|
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.roles} onChange={(value => {this.updateRoleField("roles", value);})}
|
||||||
{
|
options={this.state.roles.filter(role => (role.owner !== this.state.role.owner || role.name !== this.state.role.name)).map((role) => Setting.getOption(`${role.owner}/${role.name}`, `${role.owner}/${role.name}`))
|
||||||
this.state.roles.filter(role => (role.owner !== this.state.role.owner || role.name !== this.state.role.name)).map((role, index) => <Option key={index} value={`${role.owner}/${role.name}`}>{`${role.owner}/${role.name}`}</Option>)
|
} />
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
@ -171,11 +164,9 @@ class RoleEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.domains} onChange={(value => {
|
<Select virtual={false} mode="tags" style={{width: "100%"}} value={this.state.role.domains} onChange={(value => {
|
||||||
this.updateRoleField("domains", value);
|
this.updateRoleField("domains", value);
|
||||||
})}>
|
})}
|
||||||
{
|
options={this.state.role.domains?.map((domain) => Setting.getOption(domain, domain))
|
||||||
this.state.role.domains?.map((domain, index) => <Option key={index} value={domain}>{domain}</Option>)
|
} />
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
@ -231,6 +231,13 @@ class RoleListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
81
web/src/SelectThemeBox.js
Normal file
81
web/src/SelectThemeBox.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import * as Setting from "./Setting";
|
||||||
|
import {Dropdown} from "antd";
|
||||||
|
import "./App.less";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
function themeIcon(themeKey) {
|
||||||
|
return <img width={24} alt={themeKey} src={getLogoURL(themeKey)} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLogoURL(themeKey) {
|
||||||
|
if (themeKey) {
|
||||||
|
return Setting.Themes.find(t => t.key === themeKey)["selectThemeLogo"];
|
||||||
|
} else {
|
||||||
|
return Setting.Themes.find(t => t.key === localStorage.getItem("theme"))["selectThemeLogo"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SelectThemeBox extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
classes: props,
|
||||||
|
themes: props.theme ?? ["Default", "Dark", "Compact"],
|
||||||
|
icon: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
items = this.getThemes();
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
i18next.on("languageChanged", () => {
|
||||||
|
this.items = this.getThemes();
|
||||||
|
});
|
||||||
|
localStorage.getItem("theme") ? this.setState({"icon": getLogoURL()}) : this.setState({"icon": getLogoURL("Default")});
|
||||||
|
addEventListener("themeChange", (e) => {
|
||||||
|
this.setState({"icon": getLogoURL()});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getThemes() {
|
||||||
|
return Setting.Themes.map((theme) => Setting.getItem(i18next.t(`general:${theme.label}`), theme.key, themeIcon(theme.key)));
|
||||||
|
}
|
||||||
|
|
||||||
|
getOrganizationThemes(themes) {
|
||||||
|
const select = [];
|
||||||
|
for (const theme of themes) {
|
||||||
|
this.items.map((item, index) => item.key === theme ? select.push(item) : null);
|
||||||
|
}
|
||||||
|
return select;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const themeItems = this.getOrganizationThemes(this.state.themes);
|
||||||
|
const onClick = (e) => {
|
||||||
|
Setting.setTheme(e.key);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dropdown menu={{items: themeItems, onClick}} >
|
||||||
|
<div className="theme-box" style={{display: themeItems.length === 0 ? "none" : null, background: `url(${this.state.icon})`, ...this.props.style}} />
|
||||||
|
</Dropdown>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectThemeBox;
|
162
web/src/SessionListPage.js
Normal file
162
web/src/SessionListPage.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
import BaseListPage from "./BaseListPage";
|
||||||
|
import * as Setting from "./Setting";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import {Link} from "react-router-dom";
|
||||||
|
import {Button, Popconfirm, Table, Tag} from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import * as SessionBackend from "./backend/SessionBackend";
|
||||||
|
|
||||||
|
class SessionListPage extends BaseListPage {
|
||||||
|
|
||||||
|
deleteSession(i) {
|
||||||
|
SessionBackend.deleteSession(this.state.data[i])
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||||
|
this.setState({
|
||||||
|
data: Setting.deleteRow(this.state.data, i),
|
||||||
|
pagination: {total: this.state.pagination.total - 1},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTable(sessions) {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Name"),
|
||||||
|
dataIndex: "name",
|
||||||
|
key: "name",
|
||||||
|
width: "150px",
|
||||||
|
fixed: "left",
|
||||||
|
sorter: true,
|
||||||
|
...this.getColumnSearchProps("name"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Organization"),
|
||||||
|
dataIndex: "owner",
|
||||||
|
key: "organization",
|
||||||
|
width: "110px",
|
||||||
|
sorter: true,
|
||||||
|
...this.getColumnSearchProps("organization"),
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return (
|
||||||
|
<Link to={`/organizations/${text}`}>
|
||||||
|
{text}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Created time"),
|
||||||
|
dataIndex: "createdTime",
|
||||||
|
key: "createdTime",
|
||||||
|
width: "180px",
|
||||||
|
sorter: true,
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return Setting.getFormattedDate(text);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Session ID"),
|
||||||
|
dataIndex: "sessionId",
|
||||||
|
key: "sessionId",
|
||||||
|
width: "180px",
|
||||||
|
sorter: true,
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return text.map((item, index) =>
|
||||||
|
<Tag key={index}>{item}</Tag>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Action"),
|
||||||
|
dataIndex: "",
|
||||||
|
key: "op",
|
||||||
|
width: "70px",
|
||||||
|
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Popconfirm
|
||||||
|
title={`Sure to delete session: ${record.name} ?`}
|
||||||
|
onConfirm={() => this.deleteSession(index)}
|
||||||
|
>
|
||||||
|
<Button style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const paginationProps = {
|
||||||
|
total: this.state.pagination.total,
|
||||||
|
showQuickJumper: true,
|
||||||
|
showSizeChanger: true,
|
||||||
|
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table scroll={{x: "max-content"}} columns={columns} dataSource={sessions} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||||
|
loading={this.state.loading}
|
||||||
|
onChange={this.handleTableChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch = (params = {}) => {
|
||||||
|
let field = params.searchedColumn, value = params.searchText;
|
||||||
|
const sortField = params.sortField, sortOrder = params.sortOrder;
|
||||||
|
if (params.contentType !== undefined && params.contentType !== null) {
|
||||||
|
field = "contentType";
|
||||||
|
value = params.contentType;
|
||||||
|
}
|
||||||
|
this.setState({loading: true});
|
||||||
|
SessionBackend.getSessions("", params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.status === "ok") {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
data: res.data,
|
||||||
|
pagination: {
|
||||||
|
...params.pagination,
|
||||||
|
total: res.data2,
|
||||||
|
},
|
||||||
|
searchText: params.searchText,
|
||||||
|
searchedColumn: params.searchedColumn,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SessionListPage;
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Tag, Tooltip, message} from "antd";
|
import {Checkbox, Form, Modal, Tag, Tooltip, message, theme} from "antd";
|
||||||
import {QuestionCircleTwoTone} from "@ant-design/icons";
|
import {QuestionCircleTwoTone} from "@ant-design/icons";
|
||||||
import {isMobile as isMobileDevice} from "react-device-detect";
|
import {isMobile as isMobileDevice} from "react-device-detect";
|
||||||
import "./i18n";
|
import "./i18n";
|
||||||
@ -43,6 +43,13 @@ export const Countries = [{label: "English", key: "en", country: "US", alt: "Eng
|
|||||||
{label: "Русский", key: "ru", country: "RU", alt: "Русский"},
|
{label: "Русский", key: "ru", country: "RU", alt: "Русский"},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const {defaultAlgorithm, darkAlgorithm, compactAlgorithm} = theme;
|
||||||
|
|
||||||
|
export const Themes = [{label: i18next.t("general:Dark"), key: "Dark", style: darkAlgorithm, selectThemeLogo: `${StaticBaseUrl}/img/dark.svg`},
|
||||||
|
{label: i18next.t("general:Compact"), key: "Compact", style: compactAlgorithm, selectThemeLogo: `${StaticBaseUrl}/img/compact.svg`},
|
||||||
|
{label: i18next.t("general:Default"), key: "Default", style: defaultAlgorithm, selectThemeLogo: `${StaticBaseUrl}/img/light.svg`},
|
||||||
|
];
|
||||||
|
|
||||||
export const OtherProviderInfo = {
|
export const OtherProviderInfo = {
|
||||||
SMS: {
|
SMS: {
|
||||||
"Aliyun SMS": {
|
"Aliyun SMS": {
|
||||||
@ -502,6 +509,78 @@ export function isMobile() {
|
|||||||
return isMobileDevice;
|
return isMobileDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTermsOfUseContent(url, setTermsOfUseContent) {
|
||||||
|
fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
}).then(r => {
|
||||||
|
r.text().then(setTermsOfUseContent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isAgreementRequired(application) {
|
||||||
|
if (application) {
|
||||||
|
const agreementItem = application.signupItems.find(item => item.name === "Agreement");
|
||||||
|
if (agreementItem.rule === "None" || !agreementItem.rule) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (agreementItem && agreementItem.required) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isDefaultTrue(application) {
|
||||||
|
const agreementItem = application.signupItems.find(item => item.name === "Agreement");
|
||||||
|
if (isAgreementRequired(application) && agreementItem.rule === "Signin (Default True)") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderAgreement(required, onClick, noStyle, layout, initialValue) {
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
name="agreement"
|
||||||
|
key="agreement"
|
||||||
|
valuePropName="checked"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: required,
|
||||||
|
message: i18next.t("signup:Please accept the agreement!"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
{...layout}
|
||||||
|
noStyle={noStyle}
|
||||||
|
initialValue={initialValue}
|
||||||
|
>
|
||||||
|
<Checkbox style={{float: "left"}}>
|
||||||
|
{i18next.t("signup:Accept")}
|
||||||
|
<a onClick={onClick}>
|
||||||
|
{i18next.t("signup:Terms of Use")}
|
||||||
|
</a>
|
||||||
|
</Checkbox>
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderModal(isOpen, onOk, onCancel, doc) {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title={i18next.t("signup:Terms of Use")}
|
||||||
|
open={isOpen}
|
||||||
|
width={"55vw"}
|
||||||
|
closable={false}
|
||||||
|
okText={i18next.t("signup:Accept")}
|
||||||
|
cancelText={i18next.t("signup:Decline")}
|
||||||
|
onOk={onOk}
|
||||||
|
onCancel={onCancel}
|
||||||
|
>
|
||||||
|
<iframe title={"terms"} style={{border: 0, width: "100%", height: "60vh"}} srcDoc={doc} />
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function getFormattedDate(date) {
|
export function getFormattedDate(date) {
|
||||||
if (date === undefined) {
|
if (date === undefined) {
|
||||||
return null;
|
return null;
|
||||||
@ -562,6 +641,14 @@ export function getAvatarColor(s) {
|
|||||||
return colorList[hash % 4];
|
return colorList[hash % 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLogo(theme) {
|
||||||
|
if (theme === "Dark") {
|
||||||
|
return `${StaticBaseUrl}/img/casdoor-logo_1185x256_dark.png`;
|
||||||
|
} else {
|
||||||
|
return `${StaticBaseUrl}/img/casdoor-logo_1185x256.png`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getLanguageText(text) {
|
export function getLanguageText(text) {
|
||||||
if (!text.includes("|")) {
|
if (!text.includes("|")) {
|
||||||
return text;
|
return text;
|
||||||
@ -587,6 +674,11 @@ export function setLanguage(language) {
|
|||||||
i18next.changeLanguage(language);
|
i18next.changeLanguage(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setTheme(themeKey) {
|
||||||
|
localStorage.setItem("theme", themeKey);
|
||||||
|
dispatchEvent(new Event("themeChange"));
|
||||||
|
}
|
||||||
|
|
||||||
export function getAcceptLanguage() {
|
export function getAcceptLanguage() {
|
||||||
if (i18next.language === null || i18next.language === "") {
|
if (i18next.language === null || i18next.language === "") {
|
||||||
return "en;q=0.9,en;q=0.8";
|
return "en;q=0.9,en;q=0.8";
|
||||||
@ -800,7 +892,7 @@ export function renderLoginLink(application, text) {
|
|||||||
export function redirectToLoginPage(application, history) {
|
export function redirectToLoginPage(application, history) {
|
||||||
const loginLink = getLoginLink(application);
|
const loginLink = getLoginLink(application);
|
||||||
if (loginLink.indexOf("http") === 0 || loginLink.indexOf("https") === 0) {
|
if (loginLink.indexOf("http") === 0 || loginLink.indexOf("https") === 0) {
|
||||||
openLink(loginLink);
|
window.location.replace(loginLink);
|
||||||
}
|
}
|
||||||
history.push(loginLink);
|
history.push(loginLink);
|
||||||
}
|
}
|
||||||
@ -904,6 +996,14 @@ export function getItem(label, key, icon, children, type) {
|
|||||||
type,
|
type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getOption(label, value) {
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function repeat(str, len) {
|
function repeat(str, len) {
|
||||||
while (str.length < len) {
|
while (str.length < len) {
|
||||||
str += str.substr(0, len - str.length);
|
str += str.substr(0, len - str.length);
|
||||||
|
@ -186,6 +186,12 @@ class SignupTable extends React.Component {
|
|||||||
{id: "Normal", name: "Normal"},
|
{id: "Normal", name: "Normal"},
|
||||||
{id: "No verification", name: "No verification"},
|
{id: "No verification", name: "No verification"},
|
||||||
];
|
];
|
||||||
|
} else if (record.name === "Agreement") {
|
||||||
|
options = [
|
||||||
|
{id: "None", name: "None"},
|
||||||
|
{id: "Signin", name: "Signin"},
|
||||||
|
{id: "Signin (Default True)", name: "Signin (Default True)"},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.length === 0) {
|
if (options.length === 0) {
|
||||||
@ -195,11 +201,7 @@ class SignupTable extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<Select virtual={false} style={{width: "100%"}} value={text} onChange={(value => {
|
<Select virtual={false} style={{width: "100%"}} value={text} onChange={(value => {
|
||||||
this.updateField(table, index, "rule", value);
|
this.updateField(table, index, "rule", value);
|
||||||
})}>
|
})} options={options.map(item => Setting.getOption(item.name, item.id))} />
|
||||||
{
|
|
||||||
options.map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -288,6 +288,13 @@ class SyncerListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -253,6 +253,13 @@ class TokenListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -28,11 +28,7 @@ import SamlWidget from "./common/SamlWidget";
|
|||||||
import SelectRegionBox from "./SelectRegionBox";
|
import SelectRegionBox from "./SelectRegionBox";
|
||||||
import WebAuthnCredentialTable from "./WebauthnCredentialTable";
|
import WebAuthnCredentialTable from "./WebauthnCredentialTable";
|
||||||
import ManagedAccountTable from "./ManagedAccountTable";
|
import ManagedAccountTable from "./ManagedAccountTable";
|
||||||
|
import PropertyTable from "./propertyTable";
|
||||||
import {Controlled as CodeMirror} from "react-codemirror2";
|
|
||||||
import "codemirror/lib/codemirror.css";
|
|
||||||
require("codemirror/theme/material-darker.css");
|
|
||||||
require("codemirror/mode/javascript/javascript");
|
|
||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
@ -261,12 +257,9 @@ class UserEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:User type"), i18next.t("general:User type - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:User type"), i18next.t("general:User type - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.user.type} onChange={(value => {this.updateUserField("type", value);})}>
|
<Select virtual={false} style={{width: "100%"}} value={this.state.user.type} onChange={(value => {this.updateUserField("type", value);})}
|
||||||
{
|
options={["normal-user"].map(item => Setting.getOption(item, item))}
|
||||||
["normal-user"]
|
/>
|
||||||
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
@ -288,18 +281,23 @@ class UserEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:Email"), i18next.t("general:Email - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Email"), i18next.t("general:Email - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col style={{paddingRight: "20px"}} span={11} >
|
<Col style={{paddingRight: "20px"}} span={11} >
|
||||||
<Input value={this.state.user.email}
|
{Setting.isLocalAdminUser(this.props.account) ?
|
||||||
disabled={disabled}
|
(<Input value={this.state.user.email}
|
||||||
onChange={e => {
|
disabled={disabled}
|
||||||
this.updateUserField("email", e.target.value);
|
onChange={e => {
|
||||||
}} />
|
this.updateUserField("email", e.target.value);
|
||||||
|
}} />) :
|
||||||
|
(<Select virtual={false} value={this.state.user.email}
|
||||||
|
options={[Setting.getItem(this.state.user.email, this.state.user.email)]}
|
||||||
|
disabled={disabled}
|
||||||
|
onChange={e => {
|
||||||
|
this.updateUserField("email", e.target.value);
|
||||||
|
}} />)
|
||||||
|
}
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={11} >
|
<Col span={11} >
|
||||||
{
|
{/* backend auto get the current user, so admin can not edit. Just self can reset*/}
|
||||||
!this.isSelf() ? null : (
|
{this.isSelf() ? <ResetModal application={this.state.application} disabled={disabled} buttonText={i18next.t("user:Reset Email...")} destType={"email"} /> : null}
|
||||||
<ResetModal application={this.state.application} disabled={disabled} buttonText={i18next.t("user:Reset Email...")} destType={"email"} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
@ -310,14 +308,21 @@ class UserEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:Phone"), i18next.t("general:Phone - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Phone"), i18next.t("general:Phone - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col style={{paddingRight: "20px"}} span={11} >
|
<Col style={{paddingRight: "20px"}} span={11} >
|
||||||
<Input value={this.state.user.phone} addonBefore={`+${this.state.application?.organizationObj.phonePrefix}`}
|
{Setting.isLocalAdminUser(this.props.account) ?
|
||||||
disabled={disabled}
|
<Input value={this.state.user.phone} addonBefore={`+${this.state.application?.organizationObj.phonePrefix}`}
|
||||||
onChange={e => {
|
disabled={disabled}
|
||||||
this.updateUserField("phone", e.target.value);
|
onChange={e => {
|
||||||
}} />
|
this.updateUserField("phone", e.target.value);
|
||||||
|
}} /> :
|
||||||
|
(<Select virtual={false} value={`+${this.state.application?.organizationObj.phonePrefix} ${this.state.user.phone}`}
|
||||||
|
options={[Setting.getItem(`+${this.state.application?.organizationObj.phonePrefix} ${this.state.user.phone}`, this.state.user.phone)]}
|
||||||
|
disabled={disabled}
|
||||||
|
onChange={e => {
|
||||||
|
this.updateUserField("phone", e.target.value);
|
||||||
|
}} />)}
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={11} >
|
<Col span={11} >
|
||||||
{this.state.user.id === this.props.account?.id ? (<ResetModal application={this.state.application} disabled={disabled} buttonText={i18next.t("user:Reset Phone...")} destType={"phone"} />) : null}
|
{this.isSelf() ? (<ResetModal application={this.state.application} disabled={disabled} buttonText={i18next.t("user:Reset Phone...")} destType={"phone"} />) : null}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
@ -401,16 +406,14 @@ class UserEditPage extends React.Component {
|
|||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
{
|
{
|
||||||
this.state.application?.organizationObj.tags?.length > 0 ? (
|
this.state.application?.organizationObj.tags?.length > 0 ? (
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.state.user.tag} onChange={(value => {this.updateUserField("tag", value);})}>
|
<Select virtual={false} style={{width: "100%"}} value={this.state.user.tag}
|
||||||
{
|
onChange={(value => {this.updateUserField("tag", value);})}
|
||||||
this.state.application.organizationObj.tags?.map((tag, index) => {
|
options={this.state.application.organizationObj.tags?.map((tag) => {
|
||||||
const tokens = tag.split("|");
|
const tokens = tag.split("|");
|
||||||
const value = tokens[0];
|
const value = tokens[0];
|
||||||
const displayValue = Setting.getLanguage() !== "zh" ? tokens[0] : tokens[1];
|
const displayValue = Setting.getLanguage() !== "zh" ? tokens[0] : tokens[1];
|
||||||
return <Option key={index} value={value}>{displayValue}</Option>;
|
return Setting.getOption(displayValue, value);
|
||||||
})
|
})} />
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
) : (
|
) : (
|
||||||
<Input value={this.state.user.tag} onChange={e => {
|
<Input value={this.state.user.tag} onChange={e => {
|
||||||
this.updateUserField("tag", e.target.value);
|
this.updateUserField("tag", e.target.value);
|
||||||
@ -427,11 +430,10 @@ class UserEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("general:Signup application"), i18next.t("general:Signup application - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:Signup application"), i18next.t("general:Signup application - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Select virtual={false} style={{width: "100%"}} disabled={disabled} value={this.state.user.signupApplication} onChange={(value => {this.updateUserField("signupApplication", value);})}>
|
<Select virtual={false} style={{width: "100%"}} disabled={disabled} value={this.state.user.signupApplication}
|
||||||
{
|
onChange={(value => {this.updateUserField("signupApplication", value);})}
|
||||||
this.state.applications.map((application, index) => <Option key={index} value={application.name}>{application.name}</Option>)
|
options={this.state.applications.map((application) => Setting.getOption(application.name, application.name))
|
||||||
}
|
} />
|
||||||
</Select>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
@ -472,7 +474,7 @@ class UserEditPage extends React.Component {
|
|||||||
<div style={{marginBottom: 20}}>
|
<div style={{marginBottom: 20}}>
|
||||||
{
|
{
|
||||||
(this.state.application === null || this.state.user === null) ? null : (
|
(this.state.application === null || this.state.user === null) ? null : (
|
||||||
this.state.application?.providers.filter(providerItem => Setting.isProviderVisible(providerItem)).map((providerItem, index) =>
|
this.state.application?.providers.filter(providerItem => Setting.isProviderVisible(providerItem)).map((providerItem) =>
|
||||||
(providerItem.provider.category === "OAuth") ? (
|
(providerItem.provider.category === "OAuth") ? (
|
||||||
<OAuthWidget key={providerItem.name} labelSpan={(Setting.isMobile()) ? 10 : 3} user={this.state.user} application={this.state.application} providerItem={providerItem} account={this.props.account} onUnlinked={() => {return this.unlinked();}} />
|
<OAuthWidget key={providerItem.name} labelSpan={(Setting.isMobile()) ? 10 : 3} user={this.state.user} application={this.state.application} providerItem={providerItem} account={this.props.account} onUnlinked={() => {return this.unlinked();}} />
|
||||||
) : (
|
) : (
|
||||||
@ -490,13 +492,10 @@ class UserEditPage extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{i18next.t("user:Properties")}:
|
{Setting.getLabel(i18next.t("user:Properties"), i18next.t("user:Properties - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<CodeMirror
|
<PropertyTable properties={this.state.user.properties} onUpdateTable={(value) => {this.updateUserField("properties", value);}} />
|
||||||
value={JSON.stringify(this.state.user.properties, null, 4)}
|
|
||||||
options={{mode: "javascript", theme: "material-darker"}}
|
|
||||||
/>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
@ -507,7 +506,7 @@ class UserEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("user:Is admin"), i18next.t("user:Is admin - Tooltip"))} :
|
{Setting.getLabel(i18next.t("user:Is admin"), i18next.t("user:Is admin - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={(Setting.isMobile()) ? 22 : 2} >
|
<Col span={(Setting.isMobile()) ? 22 : 2} >
|
||||||
<Switch disabled={this.state.user.owner === "built-in"} checked={this.state.user.isAdmin} onChange={checked => {
|
<Switch disabled={disabled} checked={this.state.user.isAdmin} onChange={checked => {
|
||||||
this.updateUserField("isAdmin", checked);
|
this.updateUserField("isAdmin", checked);
|
||||||
}} />
|
}} />
|
||||||
</Col>
|
</Col>
|
||||||
@ -520,7 +519,7 @@ class UserEditPage extends React.Component {
|
|||||||
{Setting.getLabel(i18next.t("user:Is global admin"), i18next.t("user:Is global admin - Tooltip"))} :
|
{Setting.getLabel(i18next.t("user:Is global admin"), i18next.t("user:Is global admin - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={(Setting.isMobile()) ? 22 : 2} >
|
<Col span={(Setting.isMobile()) ? 22 : 2} >
|
||||||
<Switch disabled={this.state.user.owner === "built-in"} checked={this.state.user.isGlobalAdmin} onChange={checked => {
|
<Switch disabled={disabled} checked={this.state.user.isGlobalAdmin} onChange={checked => {
|
||||||
this.updateUserField("isGlobalAdmin", checked);
|
this.updateUserField("isGlobalAdmin", checked);
|
||||||
}} />
|
}} />
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Button, Popconfirm, Switch, Table, Upload} from "antd";
|
import {Button, Popconfirm, Result, Switch, Table, Upload} from "antd";
|
||||||
import {UploadOutlined} from "@ant-design/icons";
|
import {UploadOutlined} from "@ant-design/icons";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||||
@ -38,6 +38,7 @@ class UserListPage extends BaseListPage {
|
|||||||
loading: false,
|
loading: false,
|
||||||
searchText: "",
|
searchText: "",
|
||||||
searchedColumn: "",
|
searchedColumn: "",
|
||||||
|
isAuthorized: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,6 +354,7 @@ class UserListPage extends BaseListPage {
|
|||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={`Sure to delete user: ${record.name} ?`}
|
title={`Sure to delete user: ${record.name} ?`}
|
||||||
onConfirm={() => this.deleteUser(index)}
|
onConfirm={() => this.deleteUser(index)}
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
<Button disabled={disabled} style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
<Button disabled={disabled} style={{marginBottom: "10px"}} type="primary" danger>{i18next.t("general:Delete")}</Button>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
@ -369,6 +371,17 @@ class UserListPage extends BaseListPage {
|
|||||||
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!this.state.isAuthorized) {
|
||||||
|
return (
|
||||||
|
<Result
|
||||||
|
status="403"
|
||||||
|
title="403 Unauthorized"
|
||||||
|
subTitle={i18next.t("general:Sorry, you do not have permission to access this page or logged in status invalid.")}
|
||||||
|
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={users} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
|
<Table scroll={{x: "max-content"}} columns={columns} dataSource={users} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
|
||||||
@ -411,6 +424,13 @@ class UserListPage extends BaseListPage {
|
|||||||
if (users.length > 0) {
|
if (users.length > 0) {
|
||||||
this.getOrganization(users[0].owner);
|
this.getOrganization(users[0].owner);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -432,6 +452,13 @@ class UserListPage extends BaseListPage {
|
|||||||
if (users.length > 0) {
|
if (users.length > 0) {
|
||||||
this.getOrganization(users[0].owner);
|
this.getOrganization(users[0].owner);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -253,6 +253,13 @@ class WebhookListPage extends BaseListPage {
|
|||||||
searchText: params.searchText,
|
searchText: params.searchText,
|
||||||
searchedColumn: params.searchedColumn,
|
searchedColumn: params.searchedColumn,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (res.msg.includes("Unauthorized")) {
|
||||||
|
this.setState({
|
||||||
|
loading: false,
|
||||||
|
isAuthorized: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,7 @@ import * as Util from "./Util";
|
|||||||
import {authConfig} from "./Auth";
|
import {authConfig} from "./Auth";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import RedirectForm from "../common/RedirectForm";
|
||||||
|
|
||||||
class AuthCallback extends React.Component {
|
class AuthCallback extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -27,6 +28,9 @@ class AuthCallback extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
classes: props,
|
classes: props,
|
||||||
msg: null,
|
msg: null,
|
||||||
|
samlResponse: "",
|
||||||
|
relayState: "",
|
||||||
|
redirectUrl: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,9 +168,17 @@ class AuthCallback extends React.Component {
|
|||||||
const from = innerParams.get("from");
|
const from = innerParams.get("from");
|
||||||
Setting.goToLinkSoft(this, from);
|
Setting.goToLinkSoft(this, from);
|
||||||
} else if (responseType === "saml") {
|
} else if (responseType === "saml") {
|
||||||
const SAMLResponse = res.data;
|
if (res.data2.method === "POST") {
|
||||||
const redirectUri = res.data2;
|
this.setState({
|
||||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
samlResponse: res.data,
|
||||||
|
redirectUrl: res.data2.redirectUrl,
|
||||||
|
relayState: oAuthParams.relayState,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const SAMLResponse = res.data;
|
||||||
|
const redirectUri = res.data2.redirectUrl;
|
||||||
|
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -177,6 +189,10 @@ class AuthCallback extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (this.state.samlResponse !== "") {
|
||||||
|
return <RedirectForm samlResponse={this.state.samlResponse} redirectUrl={this.state.redirectUrl} relayState={this.state.relayState} />;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{display: "flex", justifyContent: "center", alignItems: "center"}}>
|
<div style={{display: "flex", justifyContent: "center", alignItems: "center"}}>
|
||||||
{
|
{
|
||||||
|
@ -40,6 +40,7 @@ class CasLogout extends React.Component {
|
|||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", "Logged out successfully");
|
Setting.showMessage("success", "Logged out successfully");
|
||||||
this.props.onUpdateAccount(null);
|
this.props.onUpdateAccount(null);
|
||||||
|
this.onUpdateApplication(null);
|
||||||
const redirectUri = res.data2;
|
const redirectUri = res.data2;
|
||||||
if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") {
|
if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") {
|
||||||
Setting.goToLink(redirectUri);
|
Setting.goToLink(redirectUri);
|
||||||
@ -49,6 +50,7 @@ class CasLogout extends React.Component {
|
|||||||
Setting.goToLinkSoft(this, `/cas/${this.state.owner}/${this.state.applicationName}/login`);
|
Setting.goToLinkSoft(this, `/cas/${this.state.owner}/${this.state.applicationName}/login`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
this.onUpdateApplication(null);
|
||||||
Setting.showMessage("error", `Failed to log out: ${res.msg}`);
|
Setting.showMessage("error", `Failed to log out: ${res.msg}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -320,9 +320,9 @@ class ForgetPage extends React.Component {
|
|||||||
>
|
>
|
||||||
{
|
{
|
||||||
this.state.isFixed ? <Input disabled /> :
|
this.state.isFixed ? <Input disabled /> :
|
||||||
<Select
|
<Select virtual={false}
|
||||||
key={this.state.verifyType}
|
key={this.state.verifyType}
|
||||||
virtual={false} style={{textAlign: "left"}}
|
style={{textAlign: "left"}}
|
||||||
defaultValue={this.state.verifyType}
|
defaultValue={this.state.verifyType}
|
||||||
disabled={this.state.username === ""}
|
disabled={this.state.username === ""}
|
||||||
placeholder={i18next.t("forget:Choose email or phone")}
|
placeholder={i18next.t("forget:Choose email or phone")}
|
||||||
|
@ -53,12 +53,16 @@ class LoginPage extends React.Component {
|
|||||||
samlResponse: "",
|
samlResponse: "",
|
||||||
relayState: "",
|
relayState: "",
|
||||||
redirectUrl: "",
|
redirectUrl: "",
|
||||||
|
isTermsOfUseVisible: false,
|
||||||
|
termsOfUseContent: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
|
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
|
||||||
this.state.owner = props.match?.params.owner;
|
this.state.owner = props.match?.params.owner;
|
||||||
this.state.applicationName = props.match?.params.casApplicationName;
|
this.state.applicationName = props.match?.params.casApplicationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.form = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -102,6 +106,7 @@ class LoginPage extends React.Component {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Setting.showMessage("error", res.msg);
|
// Setting.showMessage("error", res.msg);
|
||||||
|
this.onUpdateApplication(null);
|
||||||
this.setState({
|
this.setState({
|
||||||
application: res.data,
|
application: res.data,
|
||||||
msg: res.msg,
|
msg: res.msg,
|
||||||
@ -121,7 +126,9 @@ class LoginPage extends React.Component {
|
|||||||
this.onUpdateApplication(application);
|
this.onUpdateApplication(application);
|
||||||
this.setState({
|
this.setState({
|
||||||
application: application,
|
application: application,
|
||||||
});
|
}, () => Setting.getTermsOfUseContent(this.state.application.termsOfUse, res => {
|
||||||
|
this.setState({termsOfUseContent: res});
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
OrganizationBackend.getDefaultApplication("admin", this.state.owner)
|
OrganizationBackend.getDefaultApplication("admin", this.state.owner)
|
||||||
@ -131,8 +138,11 @@ class LoginPage extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
application: res.data,
|
application: res.data,
|
||||||
applicationName: res.data.name,
|
applicationName: res.data.name,
|
||||||
});
|
}, () => Setting.getTermsOfUseContent(this.state.application.termsOfUse, res => {
|
||||||
|
this.setState({termsOfUseContent: res});
|
||||||
|
}));
|
||||||
} else {
|
} else {
|
||||||
|
this.onUpdateApplication(null);
|
||||||
Setting.showMessage("error", res.msg);
|
Setting.showMessage("error", res.msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -318,15 +328,15 @@ class LoginPage extends React.Component {
|
|||||||
const accessToken = res.data;
|
const accessToken = res.data;
|
||||||
Setting.goToLink(`${oAuthParams.redirectUri}#${responseType}=${accessToken}?state=${oAuthParams.state}&token_type=bearer`);
|
Setting.goToLink(`${oAuthParams.redirectUri}#${responseType}=${accessToken}?state=${oAuthParams.state}&token_type=bearer`);
|
||||||
} else if (responseType === "saml") {
|
} else if (responseType === "saml") {
|
||||||
const SAMLResponse = res.data;
|
if (res.data2.method === "POST") {
|
||||||
const redirectUri = res.data2;
|
|
||||||
if (this.state.application.assertionConsumerUrl !== "") {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
samlResponse: res.data,
|
samlResponse: res.data,
|
||||||
redirectUrl: res.data2,
|
redirectUrl: res.data2.redirectUrl,
|
||||||
relayState: oAuthParams.relayState,
|
relayState: oAuthParams.relayState,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
const SAMLResponse = res.data;
|
||||||
|
const redirectUri = res.data2.redirectUrl;
|
||||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,6 +391,7 @@ class LoginPage extends React.Component {
|
|||||||
onFinish={(values) => {this.onFinish(values);}}
|
onFinish={(values) => {this.onFinish(values);}}
|
||||||
style={{width: "300px"}}
|
style={{width: "300px"}}
|
||||||
size="large"
|
size="large"
|
||||||
|
ref={this.form}
|
||||||
>
|
>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
hidden={true}
|
hidden={true}
|
||||||
@ -454,11 +465,20 @@ class LoginPage extends React.Component {
|
|||||||
}
|
}
|
||||||
</Row>
|
</Row>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
|
{
|
||||||
<Checkbox style={{float: "left"}} disabled={!application.enablePassword}>
|
Setting.isAgreementRequired(application) ?
|
||||||
{i18next.t("login:Auto sign in")}
|
Setting.renderAgreement(true, () => {
|
||||||
</Checkbox>
|
this.setState({
|
||||||
</Form.Item>
|
isTermsOfUseVisible: true,
|
||||||
|
});
|
||||||
|
}, true, {}, Setting.isDefaultTrue(application)) : (
|
||||||
|
<Form.Item name="autoSignin" valuePropName="checked" noStyle>
|
||||||
|
<Checkbox style={{float: "left"}} disabled={!application.enablePassword}>
|
||||||
|
{i18next.t("login:Auto sign in")}
|
||||||
|
</Checkbox>
|
||||||
|
</Form.Item>
|
||||||
|
)
|
||||||
|
}
|
||||||
{
|
{
|
||||||
Setting.renderForgetLink(application, i18next.t("login:Forgot password?"))
|
Setting.renderForgetLink(application, i18next.t("login:Forgot password?"))
|
||||||
}
|
}
|
||||||
@ -614,13 +634,13 @@ class LoginPage extends React.Component {
|
|||||||
this.sendSilentSigninData("signing-in");
|
this.sendSilentSigninData("signing-in");
|
||||||
|
|
||||||
const values = {};
|
const values = {};
|
||||||
values["application"] = this.state.application.name;
|
values["application"] = application.name;
|
||||||
this.onFinish(values);
|
this.onFinish(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (application.enableAutoSignin) {
|
if (application.enableAutoSignin) {
|
||||||
const values = {};
|
const values = {};
|
||||||
values["application"] = this.state.application.name;
|
values["application"] = application.name;
|
||||||
this.onFinish(values);
|
this.onFinish(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,7 +655,7 @@ class LoginPage extends React.Component {
|
|||||||
<br />
|
<br />
|
||||||
<SelfLoginButton account={this.props.account} onClick={() => {
|
<SelfLoginButton account={this.props.account} onClick={() => {
|
||||||
const values = {};
|
const values = {};
|
||||||
values["application"] = this.state.application.name;
|
values["application"] = application.name;
|
||||||
this.onFinish(values);
|
this.onFinish(values);
|
||||||
}} />
|
}} />
|
||||||
<br />
|
<br />
|
||||||
@ -800,7 +820,7 @@ class LoginPage extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<CustomGithubCorner />
|
<CustomGithubCorner />
|
||||||
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
|
<div className="login-content" style={{margin: this.props.preview ?? this.parseOffset(application.formOffset)}}>
|
||||||
{Setting.inIframe() || Setting.isMobile() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
{Setting.inIframe() || Setting.isMobile() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
||||||
<div className="login-panel">
|
<div className="login-panel">
|
||||||
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
||||||
@ -825,6 +845,19 @@ class LoginPage extends React.Component {
|
|||||||
{
|
{
|
||||||
this.renderForm(application)
|
this.renderForm(application)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
Setting.renderModal(this.state.isTermsOfUseVisible, () => {
|
||||||
|
this.form.current.setFieldsValue({agreement: true});
|
||||||
|
this.setState({
|
||||||
|
isTermsOfUseVisible: false,
|
||||||
|
});
|
||||||
|
}, () => {
|
||||||
|
this.form.current.setFieldsValue({agreement: false});
|
||||||
|
this.setState({
|
||||||
|
isTermsOfUseVisible: false,
|
||||||
|
});
|
||||||
|
}, this.state.termsOfUseContent)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,8 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
import {Button, Form, Input, Result} from "antd";
|
||||||
import {Button, Checkbox, Form, Input, Modal, Result} from "antd";
|
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
import * as AuthBackend from "./AuthBackend";
|
import * as AuthBackend from "./AuthBackend";
|
||||||
import * as ProviderButton from "./ProviderButton";
|
import * as ProviderButton from "./ProviderButton";
|
||||||
@ -113,7 +112,9 @@ class SignupPage extends React.Component {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (application !== null && application !== undefined) {
|
if (application !== null && application !== undefined) {
|
||||||
this.getTermsofuseContent(application.termsOfUse);
|
Setting.getTermsOfUseContent(application.termsOfUse, res => {
|
||||||
|
this.setState({termsOfUseContent: res});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -134,16 +135,6 @@ class SignupPage extends React.Component {
|
|||||||
return this.props.application ?? this.state.application;
|
return this.props.application ?? this.state.application;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTermsofuseContent(url) {
|
|
||||||
fetch(url, {
|
|
||||||
method: "GET",
|
|
||||||
}).then(r => {
|
|
||||||
r.text().then(res => {
|
|
||||||
this.setState({termsOfUseContent: res});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onUpdateAccount(account) {
|
onUpdateAccount(account) {
|
||||||
this.props.onUpdateAccount(account);
|
this.props.onUpdateAccount(account);
|
||||||
}
|
}
|
||||||
@ -484,58 +475,28 @@ class SignupPage extends React.Component {
|
|||||||
);
|
);
|
||||||
} else if (signupItem.name === "Agreement") {
|
} else if (signupItem.name === "Agreement") {
|
||||||
return (
|
return (
|
||||||
<Form.Item
|
Setting.renderAgreement(Setting.isAgreementRequired(application), () => {
|
||||||
name="agreement"
|
this.setState({
|
||||||
key="agreement"
|
isTermsOfUseVisible: true,
|
||||||
valuePropName="checked"
|
});
|
||||||
rules={[
|
}, false, tailFormItemLayout, Setting.isDefaultTrue(application))
|
||||||
{
|
|
||||||
required: required,
|
|
||||||
message: i18next.t("signup:Please accept the agreement!"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
{...tailFormItemLayout}
|
|
||||||
>
|
|
||||||
<Checkbox>
|
|
||||||
{i18next.t("signup:Accept")}
|
|
||||||
<Link onClick={() => {
|
|
||||||
this.setState({
|
|
||||||
isTermsOfUseVisible: true,
|
|
||||||
});
|
|
||||||
}}>
|
|
||||||
{i18next.t("signup:Terms of Use")}
|
|
||||||
</Link>
|
|
||||||
</Checkbox>
|
|
||||||
</Form.Item>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderModal() {
|
renderModal() {
|
||||||
return (
|
return (
|
||||||
<Modal
|
Setting.renderModal(this.state.isTermsOfUseVisible, () => {
|
||||||
title={i18next.t("signup:Terms of Use")}
|
this.form.current.setFieldsValue({agreement: true});
|
||||||
open={this.state.isTermsOfUseVisible}
|
this.setState({
|
||||||
width={"55vw"}
|
isTermsOfUseVisible: false,
|
||||||
closable={false}
|
});
|
||||||
okText={i18next.t("signup:Accept")}
|
}, () => {
|
||||||
cancelText={i18next.t("signup:Decline")}
|
this.form.current.setFieldsValue({agreement: false});
|
||||||
onOk={() => {
|
this.setState({
|
||||||
this.form.current.setFieldsValue({agreement: true});
|
isTermsOfUseVisible: false,
|
||||||
this.setState({
|
});
|
||||||
isTermsOfUseVisible: false,
|
}, this.state.termsOfUseContent)
|
||||||
});
|
|
||||||
}}
|
|
||||||
onCancel={() => {
|
|
||||||
this.form.current.setFieldsValue({agreement: false});
|
|
||||||
this.setState({
|
|
||||||
isTermsOfUseVisible: false,
|
|
||||||
});
|
|
||||||
this.props.history.goBack();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<iframe title={"terms"} style={{border: 0, width: "100%", height: "60vh"}} srcDoc={this.state.termsOfUseContent} />
|
|
||||||
</Modal>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,7 +598,7 @@ class SignupPage extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<CustomGithubCorner />
|
<CustomGithubCorner />
|
||||||
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
|
<div className="login-content" style={{margin: this.props.preview ?? this.parseOffset(application.formOffset)}}>
|
||||||
{Setting.inIframe() || Setting.isMobile() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
{Setting.inIframe() || Setting.isMobile() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
||||||
<div className="login-panel" >
|
<div className="login-panel" >
|
||||||
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
||||||
|
36
web/src/backend/SessionBackend.js
Normal file
36
web/src/backend/SessionBackend.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
import * as Setting from "../Setting";
|
||||||
|
|
||||||
|
export function getSessions(owner, page = "", pageSize = "", field = "", value = "", sortField = "", sortOrder = "") {
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/get-sessions?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteSession(session) {
|
||||||
|
return fetch(`${Setting.ServerUrl}/api/delete-session`, {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(session),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
@ -18,8 +18,6 @@ import i18next from "i18next";
|
|||||||
import * as UserBackend from "../backend/UserBackend";
|
import * as UserBackend from "../backend/UserBackend";
|
||||||
import * as Setting from "../Setting";
|
import * as Setting from "../Setting";
|
||||||
|
|
||||||
const {Option} = Select;
|
|
||||||
|
|
||||||
class AffiliationSelect extends React.Component {
|
class AffiliationSelect extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -99,20 +97,16 @@ class AffiliationSelect extends React.Component {
|
|||||||
this.updateUserField("affiliation", e.target.value);
|
this.updateUserField("affiliation", e.target.value);
|
||||||
}} />
|
}} />
|
||||||
) : (
|
) : (
|
||||||
<Select virtual={false} style={{width: "100%"}} value={this.props.user.affiliation} onChange={(value => {
|
<Select virtual={false} style={{width: "100%"}} value={this.props.user.affiliation}
|
||||||
const name = value;
|
onChange={(value => {
|
||||||
const affiliationOption = Setting.getArrayItem(this.state.affiliationOptions, "name", name);
|
const name = value;
|
||||||
const id = affiliationOption.id;
|
const affiliationOption = Setting.getArrayItem(this.state.affiliationOptions, "name", name);
|
||||||
this.updateUserField("affiliation", name);
|
const id = affiliationOption.id;
|
||||||
this.updateUserField("score", id);
|
this.updateUserField("affiliation", name);
|
||||||
})}>
|
this.updateUserField("score", id);
|
||||||
{
|
})}
|
||||||
<Option key={0} value={""}>(empty)</Option>
|
options={[Setting.getOption("(empty)", "")].concat(this.state.affiliationOptions.map((affiliationOption) => Setting.getOption(affiliationOption.name, affiliationOption.name))
|
||||||
}
|
)} />
|
||||||
{
|
|
||||||
this.state.affiliationOptions.map((affiliationOption, index) => <Option key={affiliationOption.id} value={affiliationOption.name}>{affiliationOption.name}</Option>)
|
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -28,7 +28,7 @@ code {
|
|||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
background: url("https://cdn.casbin.org/img/casdoor-logo_1185x256.png");
|
background: url("https://cdn.casbin.org/img/casdoor-logo_1185x256.png");
|
||||||
background-size: 130px, 27px;
|
background-size: 130px, 27px !important;
|
||||||
width: 130px;
|
width: 130px;
|
||||||
height: 27px;
|
height: 27px;
|
||||||
margin: 17px 0 16px 15px;
|
margin: 17px 0 16px 15px;
|
||||||
@ -45,7 +45,3 @@ code {
|
|||||||
.ant-list-sm .ant-list-item {
|
.ant-list-sm .ant-list-item {
|
||||||
padding: 2px !important;
|
padding: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-layout-header {
|
|
||||||
background-color: white !important;
|
|
||||||
}
|
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "Code-Anmeldung aktivieren",
|
"Enable code signin": "Code-Anmeldung aktivieren",
|
||||||
"Enable code signin - Tooltip": "Aktiviere Codeanmeldung - Tooltip",
|
"Enable code signin - Tooltip": "Aktiviere Codeanmeldung - Tooltip",
|
||||||
|
"Enable link accounts that with the same email": "Enable link accounts that with the same email",
|
||||||
|
"Enable link accounts that with the same email - Tooltip": "Enable link accounts that with the same email - Tooltip",
|
||||||
"Enable side panel": "Enable side panel",
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
|
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
|
||||||
"Enable signup": "Anmeldung aktivieren",
|
"Enable signup": "Anmeldung aktivieren",
|
||||||
@ -156,7 +158,10 @@
|
|||||||
"Click to Upload": "Click to Upload",
|
"Click to Upload": "Click to Upload",
|
||||||
"Client IP": "Client-IP",
|
"Client IP": "Client-IP",
|
||||||
"Close": "Close",
|
"Close": "Close",
|
||||||
|
"Compact": "Compact",
|
||||||
"Created time": "Erstellte Zeit",
|
"Created time": "Erstellte Zeit",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Default application",
|
"Default application": "Default application",
|
||||||
"Default application - Tooltip": "Default application - Tooltip",
|
"Default application - Tooltip": "Default application - Tooltip",
|
||||||
"Default avatar": "Standard Avatar",
|
"Default avatar": "Standard Avatar",
|
||||||
@ -233,6 +238,8 @@
|
|||||||
"Roles - Tooltip": "Roles - Tooltip",
|
"Roles - Tooltip": "Roles - Tooltip",
|
||||||
"Save": "Speichern",
|
"Save": "Speichern",
|
||||||
"Save & Exit": "Speichern & Beenden",
|
"Save & Exit": "Speichern & Beenden",
|
||||||
|
"Session ID": "Session ID",
|
||||||
|
"Sessions": "Sessions",
|
||||||
"Signin URL": "Anmelde-URL",
|
"Signin URL": "Anmelde-URL",
|
||||||
"Signin URL - Tooltip": "sign in url",
|
"Signin URL - Tooltip": "sign in url",
|
||||||
"Signup URL": "Registrierungs-URL",
|
"Signup URL": "Registrierungs-URL",
|
||||||
@ -241,7 +248,7 @@
|
|||||||
"Signup application - Tooltip": "Signup application - Tooltip",
|
"Signup application - Tooltip": "Signup application - Tooltip",
|
||||||
"Sorry, the page you visited does not exist.": "Die von Ihnen besuchte Seite existiert leider nicht.",
|
"Sorry, the page you visited does not exist.": "Die von Ihnen besuchte Seite existiert leider nicht.",
|
||||||
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
|
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
|
||||||
"Sorry, you do not have permission to access this page.": "Sorry, you do not have permission to access this page.",
|
"Sorry, you do not have permission to access this page or logged in status invalid.": "Sorry, you do not have permission to access this page or logged in status invalid.",
|
||||||
"State": "State",
|
"State": "State",
|
||||||
"State - Tooltip": "State - Tooltip",
|
"State - Tooltip": "State - Tooltip",
|
||||||
"Successfully added": "Successfully added",
|
"Successfully added": "Successfully added",
|
||||||
@ -709,6 +716,7 @@
|
|||||||
"Country/Region": "Land/Region",
|
"Country/Region": "Land/Region",
|
||||||
"Country/Region - Tooltip": "Country/Region",
|
"Country/Region - Tooltip": "Country/Region",
|
||||||
"Edit User": "Benutzer bearbeiten",
|
"Edit User": "Benutzer bearbeiten",
|
||||||
|
"Email cannot be empty": "Email cannot be empty",
|
||||||
"Empty input!": "Empty input!",
|
"Empty input!": "Empty input!",
|
||||||
"Homepage": "Homepage",
|
"Homepage": "Homepage",
|
||||||
"Homepage - Tooltip": "Startseite - Tooltip",
|
"Homepage - Tooltip": "Startseite - Tooltip",
|
||||||
@ -723,6 +731,7 @@
|
|||||||
"Is forbidden - Tooltip": "Whether the account is disabled",
|
"Is forbidden - Tooltip": "Whether the account is disabled",
|
||||||
"Is global admin": "Ist globaler Admin",
|
"Is global admin": "Ist globaler Admin",
|
||||||
"Is global admin - Tooltip": "Is the application global administrator",
|
"Is global admin - Tooltip": "Is the application global administrator",
|
||||||
|
"Keys": "Keys",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Standort",
|
"Location": "Standort",
|
||||||
"Location - Tooltip": "Standort - Tooltip",
|
"Location - Tooltip": "Standort - Tooltip",
|
||||||
@ -736,8 +745,10 @@
|
|||||||
"Old Password": "Altes Passwort",
|
"Old Password": "Altes Passwort",
|
||||||
"Password": "Passwort",
|
"Password": "Passwort",
|
||||||
"Password Set": "Passwort setzen",
|
"Password Set": "Passwort setzen",
|
||||||
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Please select avatar from resources": "Please select avatar from resources",
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Eigenschaften",
|
"Properties": "Eigenschaften",
|
||||||
|
"Properties - Tooltip": "Properties - Tooltip",
|
||||||
"Re-enter New": "Neu erneut eingeben",
|
"Re-enter New": "Neu erneut eingeben",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
"Reset Phone...": "Telefon zurücksetzen...",
|
"Reset Phone...": "Telefon zurücksetzen...",
|
||||||
@ -753,6 +764,7 @@
|
|||||||
"Unlink": "Link aufheben",
|
"Unlink": "Link aufheben",
|
||||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||||
"Upload a photo": "Foto hochladen",
|
"Upload a photo": "Foto hochladen",
|
||||||
|
"Values": "Values",
|
||||||
"WebAuthn credentials": "WebAuthn credentials",
|
"WebAuthn credentials": "WebAuthn credentials",
|
||||||
"input password": "Passwort eingeben"
|
"input password": "Passwort eingeben"
|
||||||
},
|
},
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "Enable code signin",
|
"Enable code signin": "Enable code signin",
|
||||||
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
||||||
|
"Enable link accounts that with the same email": "Enable link accounts that with the same email",
|
||||||
|
"Enable link accounts that with the same email - Tooltip": "Enable link accounts that with the same email - Tooltip",
|
||||||
"Enable side panel": "Enable side panel",
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
"Enable signup": "Enable signup",
|
"Enable signup": "Enable signup",
|
||||||
@ -156,7 +158,10 @@
|
|||||||
"Click to Upload": "Click to Upload",
|
"Click to Upload": "Click to Upload",
|
||||||
"Client IP": "Client IP",
|
"Client IP": "Client IP",
|
||||||
"Close": "Close",
|
"Close": "Close",
|
||||||
|
"Compact": "Compact",
|
||||||
"Created time": "Created time",
|
"Created time": "Created time",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Default": "Default",
|
||||||
"Default application": "Default application",
|
"Default application": "Default application",
|
||||||
"Default application - Tooltip": "Default application - Tooltip",
|
"Default application - Tooltip": "Default application - Tooltip",
|
||||||
"Default avatar": "Default avatar",
|
"Default avatar": "Default avatar",
|
||||||
@ -233,6 +238,8 @@
|
|||||||
"Roles - Tooltip": "Roles - Tooltip",
|
"Roles - Tooltip": "Roles - Tooltip",
|
||||||
"Save": "Save",
|
"Save": "Save",
|
||||||
"Save & Exit": "Save & Exit",
|
"Save & Exit": "Save & Exit",
|
||||||
|
"Session ID": "Session ID",
|
||||||
|
"Sessions": "Sessions",
|
||||||
"Signin URL": "Signin URL",
|
"Signin URL": "Signin URL",
|
||||||
"Signin URL - Tooltip": "Signin URL - Tooltip",
|
"Signin URL - Tooltip": "Signin URL - Tooltip",
|
||||||
"Signup URL": "Signup URL",
|
"Signup URL": "Signup URL",
|
||||||
@ -241,7 +248,7 @@
|
|||||||
"Signup application - Tooltip": "Signup application - Tooltip",
|
"Signup application - Tooltip": "Signup application - Tooltip",
|
||||||
"Sorry, the page you visited does not exist.": "Sorry, the page you visited does not exist.",
|
"Sorry, the page you visited does not exist.": "Sorry, the page you visited does not exist.",
|
||||||
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
|
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Sorry, the user you visited does not exist or you are not authorized to access this user.",
|
||||||
"Sorry, you do not have permission to access this page.": "Sorry, you do not have permission to access this page.",
|
"Sorry, you do not have permission to access this page or logged in status invalid.": "Sorry, you do not have permission to access this page or logged in status invalid.",
|
||||||
"State": "State",
|
"State": "State",
|
||||||
"State - Tooltip": "State - Tooltip",
|
"State - Tooltip": "State - Tooltip",
|
||||||
"Successfully added": "Successfully added",
|
"Successfully added": "Successfully added",
|
||||||
@ -709,6 +716,7 @@
|
|||||||
"Country/Region": "Country/Region",
|
"Country/Region": "Country/Region",
|
||||||
"Country/Region - Tooltip": "Country/Region - Tooltip",
|
"Country/Region - Tooltip": "Country/Region - Tooltip",
|
||||||
"Edit User": "Edit User",
|
"Edit User": "Edit User",
|
||||||
|
"Email cannot be empty": "Email cannot be empty",
|
||||||
"Empty input!": "Empty input!",
|
"Empty input!": "Empty input!",
|
||||||
"Homepage": "Homepage",
|
"Homepage": "Homepage",
|
||||||
"Homepage - Tooltip": "Homepage - Tooltip",
|
"Homepage - Tooltip": "Homepage - Tooltip",
|
||||||
@ -723,6 +731,7 @@
|
|||||||
"Is forbidden - Tooltip": "Is forbidden - Tooltip",
|
"Is forbidden - Tooltip": "Is forbidden - Tooltip",
|
||||||
"Is global admin": "Is global admin",
|
"Is global admin": "Is global admin",
|
||||||
"Is global admin - Tooltip": "Is global admin - Tooltip",
|
"Is global admin - Tooltip": "Is global admin - Tooltip",
|
||||||
|
"Keys": "Keys",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"Location - Tooltip": "Location - Tooltip",
|
"Location - Tooltip": "Location - Tooltip",
|
||||||
@ -736,8 +745,10 @@
|
|||||||
"Old Password": "Old Password",
|
"Old Password": "Old Password",
|
||||||
"Password": "Password",
|
"Password": "Password",
|
||||||
"Password Set": "Password Set",
|
"Password Set": "Password Set",
|
||||||
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
"Please select avatar from resources": "Please select avatar from resources",
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Properties",
|
"Properties": "Properties",
|
||||||
|
"Properties - Tooltip": "Properties - Tooltip",
|
||||||
"Re-enter New": "Re-enter New",
|
"Re-enter New": "Re-enter New",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
"Reset Phone...": "Reset Phone...",
|
"Reset Phone...": "Reset Phone...",
|
||||||
@ -753,6 +764,7 @@
|
|||||||
"Unlink": "Unlink",
|
"Unlink": "Unlink",
|
||||||
"Upload (.xlsx)": "Upload (.xlsx)",
|
"Upload (.xlsx)": "Upload (.xlsx)",
|
||||||
"Upload a photo": "Upload a photo",
|
"Upload a photo": "Upload a photo",
|
||||||
|
"Values": "Values",
|
||||||
"WebAuthn credentials": "WebAuthn credentials",
|
"WebAuthn credentials": "WebAuthn credentials",
|
||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
|
@ -5,7 +5,23 @@
|
|||||||
"My Account": "Mi cuenta",
|
"My Account": "Mi cuenta",
|
||||||
"Sign Up": "Registrarme"
|
"Sign Up": "Registrarme"
|
||||||
},
|
},
|
||||||
|
"adapter": {
|
||||||
|
"Edit Adapter": "Edit Adapter",
|
||||||
|
"Failed to sync policies": "Failed to sync policies",
|
||||||
|
"New Adapter": "New Adapter",
|
||||||
|
"Policies": "Policies",
|
||||||
|
"Policies - Tooltip": "Policies - Tooltip",
|
||||||
|
"Repeated policy rules": "Repeated policy rules",
|
||||||
|
"Sync": "Sync",
|
||||||
|
"Sync policies successfully": "Sync policies successfully"
|
||||||
|
},
|
||||||
"application": {
|
"application": {
|
||||||
|
"Always": "Always",
|
||||||
|
"Auto signin": "Auto signin",
|
||||||
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
|
"Background URL": "Background URL",
|
||||||
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copiar SAML metadata URL",
|
"Copy SAML metadata URL": "Copiar SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copiar URL de inicio de sesión",
|
"Copy signin page URL": "Copiar URL de inicio de sesión",
|
||||||
@ -17,39 +33,59 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Habilitar inicio de sesión de WebAuthn - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Habilitar inicio de sesión de WebAuthn - Tooltip",
|
||||||
"Enable code signin": "Habilitar inicio de sesión por código",
|
"Enable code signin": "Habilitar inicio de sesión por código",
|
||||||
"Enable code signin - Tooltip": "Habilitar inicio de sesión por código - Tooltip",
|
"Enable code signin - Tooltip": "Habilitar inicio de sesión por código - Tooltip",
|
||||||
|
"Enable link accounts that with the same email": "Enable link accounts that with the same email",
|
||||||
|
"Enable link accounts that with the same email - Tooltip": "Enable link accounts that with the same email - Tooltip",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
"Enable signup": "Habilitar nuevos registros",
|
"Enable signup": "Habilitar nuevos registros",
|
||||||
"Enable signup - Tooltip": "Habilitar nuevos registros - Tooltip",
|
"Enable signup - Tooltip": "Habilitar nuevos registros - Tooltip",
|
||||||
|
"Failed to sign in": "Failed to sign in",
|
||||||
"File uploaded successfully": "El archivo ha sido subido con éxito",
|
"File uploaded successfully": "El archivo ha sido subido con éxito",
|
||||||
|
"Form CSS": "Form CSS",
|
||||||
|
"Form CSS - Edit": "Form CSS - Edit",
|
||||||
|
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
||||||
|
"Form position": "Form position",
|
||||||
|
"Form position - Tooltip": "Form position - Tooltip",
|
||||||
"Grant types": "Grant types",
|
"Grant types": "Grant types",
|
||||||
"Grant types - Tooltip": "Grant types - Tooltip",
|
"Grant types - Tooltip": "Grant types - Tooltip",
|
||||||
|
"Left": "Left",
|
||||||
|
"Logged in successfully": "Logged in successfully",
|
||||||
|
"Logged out successfully": "Logged out successfully",
|
||||||
"New Application": "Nueva Aplicación",
|
"New Application": "Nueva Aplicación",
|
||||||
|
"None": "None",
|
||||||
"Password ON": "Constraseña ON",
|
"Password ON": "Constraseña ON",
|
||||||
"Password ON - Tooltip": "Constraseña ON - Tooltip",
|
"Password ON - Tooltip": "Constraseña ON - Tooltip",
|
||||||
|
"Please input your application!": "Please input your application!",
|
||||||
|
"Please input your organization!": "Please input your organization!",
|
||||||
"Please select a HTML file": "Seleccione un archivo HTML",
|
"Please select a HTML file": "Seleccione un archivo HTML",
|
||||||
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Prompt page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
"Redirect URL": "URL de redirección",
|
"Redirect URL": "URL de redirección",
|
||||||
|
"Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip": "Redirect URL (Assertion Consumer Service POST Binding URL) - Tooltip",
|
||||||
"Redirect URLs": "URLs de redirección",
|
"Redirect URLs": "URLs de redirección",
|
||||||
"Redirect URLs - Tooltip": "URL de redirección - Tooltip",
|
"Redirect URLs - Tooltip": "URL de redirección - Tooltip",
|
||||||
"Refresh token expire": "Expiración del Refresh Token",
|
"Refresh token expire": "Expiración del Refresh Token",
|
||||||
"Refresh token expire - Tooltip": "Expiración del Refresh Token - Tooltip",
|
"Refresh token expire - Tooltip": "Expiración del Refresh Token - Tooltip",
|
||||||
|
"Right": "Right",
|
||||||
|
"Rule": "Rule",
|
||||||
|
"SAML Reply URL": "SAML Reply URL",
|
||||||
"SAML metadata": "SAML metadata",
|
"SAML metadata": "SAML metadata",
|
||||||
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
"SAML metadata - Tooltip": "SAML metadata - Tooltip",
|
||||||
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copiado al portapapeles con éxito",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copiado al portapapeles con éxito",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
|
"Sign Up Error": "Sign Up Error",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
"Signin session": "Signin session",
|
"Signin session": "Signin session",
|
||||||
"Sign Up Error": "Sign Up Error",
|
|
||||||
"Signup items": "Signup items",
|
"Signup items": "Signup items",
|
||||||
"Signup items - Tooltip": "Signup items - Tooltip",
|
"Signup items - Tooltip": "Signup items - Tooltip",
|
||||||
"Signup page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signup page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
"Signup page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "Signup page URL copied to clipboard successfully, please paste it into the incognito window or another browser",
|
||||||
|
"The application does not allow to sign up new account": "The application does not allow to sign up new account",
|
||||||
"Token expire": "Expiración del Token",
|
"Token expire": "Expiración del Token",
|
||||||
"Token expire - Tooltip": "Expiración del Token - Tooltip",
|
"Token expire - Tooltip": "Expiración del Token - Tooltip",
|
||||||
"Token format": "Formato del Token",
|
"Token format": "Formato del Token",
|
||||||
"Token format - Tooltip": "Formato del Token - Tooltip",
|
"Token format - Tooltip": "Formato del Token - Tooltip",
|
||||||
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page",
|
"You are unexpected to see this prompt page": "You are unexpected to see this prompt page"
|
||||||
"Rule": "Rule",
|
|
||||||
"None": "None",
|
|
||||||
"Always": "Always"
|
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "Tamaño del Bit",
|
"Bit size": "Tamaño del Bit",
|
||||||
@ -97,13 +133,14 @@
|
|||||||
"Please input your username!": "Por favor ingrese su nombre de usuario!",
|
"Please input your username!": "Por favor ingrese su nombre de usuario!",
|
||||||
"Reset": "Reiniciar",
|
"Reset": "Reiniciar",
|
||||||
"Retrieve password": "Recuperar Contraseña",
|
"Retrieve password": "Recuperar Contraseña",
|
||||||
"Unknown forget type": "Tipo de olvido desconocido",
|
"Unknown forget type: ": "Unknown forget type: ",
|
||||||
"Verify": "Verificar"
|
"Verify": "Verificar"
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"Action": "Acción",
|
"Action": "Acción",
|
||||||
"Adapter": "Adaptador",
|
"Adapter": "Adaptador",
|
||||||
"Adapter - Tooltip": "Adaptador - Tooltip",
|
"Adapter - Tooltip": "Adaptador - Tooltip",
|
||||||
|
"Adapters": "Adapters",
|
||||||
"Add": "Agregar",
|
"Add": "Agregar",
|
||||||
"Affiliation URL": "URL de Afiliación",
|
"Affiliation URL": "URL de Afiliación",
|
||||||
"Affiliation URL - Tooltip": "URL de Afiliación - Tooltip",
|
"Affiliation URL - Tooltip": "URL de Afiliación - Tooltip",
|
||||||
@ -120,7 +157,13 @@
|
|||||||
"Certs": "Certificados",
|
"Certs": "Certificados",
|
||||||
"Click to Upload": "Click para subir archivo",
|
"Click to Upload": "Click para subir archivo",
|
||||||
"Client IP": "IP del Cliente",
|
"Client IP": "IP del Cliente",
|
||||||
|
"Close": "Close",
|
||||||
|
"Compact": "Compact",
|
||||||
"Created time": "Fecha de creación",
|
"Created time": "Fecha de creación",
|
||||||
|
"Dark": "Dark",
|
||||||
|
"Default": "Default",
|
||||||
|
"Default application": "Default application",
|
||||||
|
"Default application - Tooltip": "Default application - Tooltip",
|
||||||
"Default avatar": "Avatar por defecto",
|
"Default avatar": "Avatar por defecto",
|
||||||
"Default avatar - Tooltip": "Avatar por defecto - Tooltip",
|
"Default avatar - Tooltip": "Avatar por defecto - Tooltip",
|
||||||
"Delete": "Eliminar",
|
"Delete": "Eliminar",
|
||||||
@ -132,6 +175,10 @@
|
|||||||
"Edit": "Editar",
|
"Edit": "Editar",
|
||||||
"Email": "Email",
|
"Email": "Email",
|
||||||
"Email - Tooltip": "Email - Tooltip",
|
"Email - Tooltip": "Email - Tooltip",
|
||||||
|
"Failed to add": "Failed to add",
|
||||||
|
"Failed to connect to server": "Failed to connect to server",
|
||||||
|
"Failed to delete": "Failed to delete",
|
||||||
|
"Failed to save": "Failed to save",
|
||||||
"Favicon": "Favicon",
|
"Favicon": "Favicon",
|
||||||
"Favicon - Tooltip": "Favicon - Tooltip",
|
"Favicon - Tooltip": "Favicon - Tooltip",
|
||||||
"First name": "Nombre",
|
"First name": "Nombre",
|
||||||
@ -145,11 +192,14 @@
|
|||||||
"Is enabled - Tooltip": "Está habilitado - Tooltip",
|
"Is enabled - Tooltip": "Está habilitado - Tooltip",
|
||||||
"LDAPs": "LDAPs",
|
"LDAPs": "LDAPs",
|
||||||
"LDAPs - Tooltip": "LDAPs - Tooltip",
|
"LDAPs - Tooltip": "LDAPs - Tooltip",
|
||||||
|
"Languages": "Languages",
|
||||||
|
"Languages - Tooltip": "Languages - Tooltip",
|
||||||
"Last name": "Apellido",
|
"Last name": "Apellido",
|
||||||
"Logo": "Logo",
|
"Logo": "Logo",
|
||||||
"Logo - Tooltip": "Logo - Tooltip",
|
"Logo - Tooltip": "Logo - Tooltip",
|
||||||
"Master password": "Contraseña maestra",
|
"Master password": "Contraseña maestra",
|
||||||
"Master password - Tooltip": "Contraseña maestra - Tooltip",
|
"Master password - Tooltip": "Contraseña maestra - Tooltip",
|
||||||
|
"Menu": "Menu",
|
||||||
"Method": "Metodo",
|
"Method": "Metodo",
|
||||||
"Model": "Modelo",
|
"Model": "Modelo",
|
||||||
"Model - Tooltip": "Modelo - Tooltip",
|
"Model - Tooltip": "Modelo - Tooltip",
|
||||||
@ -188,6 +238,8 @@
|
|||||||
"Roles - Tooltip": "Roles - Tooltip",
|
"Roles - Tooltip": "Roles - Tooltip",
|
||||||
"Save": "Guardar",
|
"Save": "Guardar",
|
||||||
"Save & Exit": "Guardar & Volver",
|
"Save & Exit": "Guardar & Volver",
|
||||||
|
"Session ID": "Session ID",
|
||||||
|
"Sessions": "Sessions",
|
||||||
"Signin URL": "URL de inicio de sesión",
|
"Signin URL": "URL de inicio de sesión",
|
||||||
"Signin URL - Tooltip": "URL de inicio de sesión - Tooltip",
|
"Signin URL - Tooltip": "URL de inicio de sesión - Tooltip",
|
||||||
"Signup URL": "URL de registro",
|
"Signup URL": "URL de registro",
|
||||||
@ -196,12 +248,16 @@
|
|||||||
"Signup application - Tooltip": "Aplicación de inicio de sesión - Tooltip",
|
"Signup application - Tooltip": "Aplicación de inicio de sesión - Tooltip",
|
||||||
"Sorry, the page you visited does not exist.": "Lo sentimos, la página que visitaste no existe.",
|
"Sorry, the page you visited does not exist.": "Lo sentimos, la página que visitaste no existe.",
|
||||||
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Lo sentimos, el usuario que visitaste no existe o no estás autorizado para acceder.",
|
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "Lo sentimos, el usuario que visitaste no existe o no estás autorizado para acceder.",
|
||||||
"Sorry, you do not have permission to access this page.": "Lo sentimos, no tienes permiso para acceder a esta página.",
|
"Sorry, you do not have permission to access this page or logged in status invalid.": "Sorry, you do not have permission to access this page or logged in status invalid.",
|
||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"State - Tooltip": "Estado - Tooltip",
|
"State - Tooltip": "Estado - Tooltip",
|
||||||
|
"Successfully added": "Successfully added",
|
||||||
|
"Successfully deleted": "Successfully deleted",
|
||||||
|
"Successfully saved": "Successfully saved",
|
||||||
"Swagger": "Swagger",
|
"Swagger": "Swagger",
|
||||||
"Sync": "Sincronizador",
|
"Sync": "Sincronizador",
|
||||||
"Syncers": "Sincronizadores",
|
"Syncers": "Sincronizadores",
|
||||||
|
"SysInfo": "SysInfo",
|
||||||
"Timestamp": "Timestamp",
|
"Timestamp": "Timestamp",
|
||||||
"Tokens": "Tokens",
|
"Tokens": "Tokens",
|
||||||
"URL": "URL",
|
"URL": "URL",
|
||||||
@ -250,6 +306,7 @@
|
|||||||
"Continue with": "Continuar con",
|
"Continue with": "Continuar con",
|
||||||
"Email or phone": "Email o teléfono",
|
"Email or phone": "Email o teléfono",
|
||||||
"Forgot password?": "¿Olvidó su contraseña?",
|
"Forgot password?": "¿Olvidó su contraseña?",
|
||||||
|
"Loading": "Loading",
|
||||||
"Logging out...": "Cerrando su sesión...",
|
"Logging out...": "Cerrando su sesión...",
|
||||||
"No account?": "¿No estás registrado?",
|
"No account?": "¿No estás registrado?",
|
||||||
"Or sign in with another account": "O inicia sesión con otra cuenta",
|
"Or sign in with another account": "O inicia sesión con otra cuenta",
|
||||||
@ -259,14 +316,16 @@
|
|||||||
"Please input your password!": "¡Por favor ingrese su contraseña!",
|
"Please input your password!": "¡Por favor ingrese su contraseña!",
|
||||||
"Please input your password, at least 6 characters!": "Su contraseña debe contener al menos 6 caracteres.",
|
"Please input your password, at least 6 characters!": "Su contraseña debe contener al menos 6 caracteres.",
|
||||||
"Please input your username, Email or phone!": "¡Ingrese su nombre de usuario, correo electrónico o teléfono!",
|
"Please input your username, Email or phone!": "¡Ingrese su nombre de usuario, correo electrónico o teléfono!",
|
||||||
|
"Redirecting, please wait.": "Redirecting, please wait.",
|
||||||
"Sign In": "Iniciar de sesión",
|
"Sign In": "Iniciar de sesión",
|
||||||
"Sign in with WebAuthn": "Iniciar de sesión con WebAuthn",
|
"Sign in with WebAuthn": "Iniciar de sesión con WebAuthn",
|
||||||
"Sign in with code": "Iniciar de sesión con código",
|
|
||||||
"Sign in with password": "Iniciar de sesión con contraseña",
|
|
||||||
"Sign in with {type}": "Iniciar de sesión con {type}",
|
"Sign in with {type}": "Iniciar de sesión con {type}",
|
||||||
"Signing in...": "Iniciando de sesión...",
|
"Signing in...": "Iniciando de sesión...",
|
||||||
|
"Successfully logged in with webauthn credentials": "Successfully logged in with webauthn credentials",
|
||||||
"The input is not valid Email or Phone!": "El valor ingresado no es un Email o Teléfono válido!",
|
"The input is not valid Email or Phone!": "El valor ingresado no es un Email o Teléfono válido!",
|
||||||
"To access": "Para ingresar",
|
"To access": "Para ingresar",
|
||||||
|
"Verification Code": "Verification Code",
|
||||||
|
"WebAuthn": "WebAuthn",
|
||||||
"sign up now": "Regístrate ahora",
|
"sign up now": "Regístrate ahora",
|
||||||
"username, Email or phone": "nombre de usuario, correo electrónico o teléfono"
|
"username, Email or phone": "nombre de usuario, correo electrónico o teléfono"
|
||||||
},
|
},
|
||||||
@ -282,17 +341,20 @@
|
|||||||
"Default avatar": "Avatar por defecto",
|
"Default avatar": "Avatar por defecto",
|
||||||
"Edit Organization": "Editar Organización",
|
"Edit Organization": "Editar Organización",
|
||||||
"Favicon": "Favicon",
|
"Favicon": "Favicon",
|
||||||
|
"InitScore": "InitScore",
|
||||||
"Is profile public": "Es el perfil publico",
|
"Is profile public": "Es el perfil publico",
|
||||||
"Is profile public - Tooltip": "Es el perfil publico - Tooltip",
|
"Is profile public - Tooltip": "Es el perfil publico - Tooltip",
|
||||||
|
"Modify rule": "Modify rule",
|
||||||
"New Organization": "Nueva Organización",
|
"New Organization": "Nueva Organización",
|
||||||
"Soft deletion": "Eliminación Soft",
|
"Soft deletion": "Eliminación Soft",
|
||||||
"Soft deletion - Tooltip": "Eliminación Soft - Tooltip",
|
"Soft deletion - Tooltip": "Eliminación Soft - Tooltip",
|
||||||
"Tags": "Etiquetas",
|
"Tags": "Etiquetas",
|
||||||
"Tags - Tooltip": "Etiquetas - Tooltip",
|
"Tags - Tooltip": "Etiquetas - Tooltip",
|
||||||
|
"The user's initScore - Tooltip": "The user's initScore - Tooltip",
|
||||||
|
"View rule": "View rule",
|
||||||
|
"Visible": "Visible",
|
||||||
"Website URL": "URL del sitio web",
|
"Website URL": "URL del sitio web",
|
||||||
"Website URL - Tooltip": "URL del sitio web - Tooltip",
|
"Website URL - Tooltip": "URL del sitio web - Tooltip"
|
||||||
"modifyRule": "modifyRule",
|
|
||||||
"viewRule": "viewRule"
|
|
||||||
},
|
},
|
||||||
"payment": {
|
"payment": {
|
||||||
"Confirm your invoice information": "Confirma la información de tu factura",
|
"Confirm your invoice information": "Confirma la información de tu factura",
|
||||||
@ -349,14 +411,20 @@
|
|||||||
"permission": {
|
"permission": {
|
||||||
"Actions": "Acciones",
|
"Actions": "Acciones",
|
||||||
"Actions - Tooltip": "Acciones - Tooltip",
|
"Actions - Tooltip": "Acciones - Tooltip",
|
||||||
|
"Admin": "Admin",
|
||||||
|
"Allow": "Allow",
|
||||||
"Approve time": "Fecha de aprobación",
|
"Approve time": "Fecha de aprobación",
|
||||||
"Approve time - Tooltip": "Fecha de aprobación - Tooltip",
|
"Approve time - Tooltip": "Fecha de aprobación - Tooltip",
|
||||||
|
"Approved": "Approved",
|
||||||
"Approver": "Aprobador",
|
"Approver": "Aprobador",
|
||||||
"Approver - Tooltip": "Aprobador - Tooltip",
|
"Approver - Tooltip": "Aprobador - Tooltip",
|
||||||
|
"Deny": "Deny",
|
||||||
"Edit Permission": "Editar Permiso",
|
"Edit Permission": "Editar Permiso",
|
||||||
"Effect": "Effect",
|
"Effect": "Effect",
|
||||||
"Effect - Tooltip": "Effect - Tooltip",
|
"Effect - Tooltip": "Effect - Tooltip",
|
||||||
"New Permission": "Nuevo Permiso",
|
"New Permission": "Nuevo Permiso",
|
||||||
|
"Pending": "Pending",
|
||||||
|
"Read": "Read",
|
||||||
"Resource type": "Tipo de recurso",
|
"Resource type": "Tipo de recurso",
|
||||||
"Resource type - Tooltip": "Tipo de recurso - Tooltip",
|
"Resource type - Tooltip": "Tipo de recurso - Tooltip",
|
||||||
"Resources": "Recursos",
|
"Resources": "Recursos",
|
||||||
@ -364,7 +432,9 @@
|
|||||||
"State": "Estado",
|
"State": "Estado",
|
||||||
"State - Tooltip": "Estado - Tooltip",
|
"State - Tooltip": "Estado - Tooltip",
|
||||||
"Submitter": "Submitter",
|
"Submitter": "Submitter",
|
||||||
"Submitter - Tooltip": "Submitter - Tooltip"
|
"Submitter - Tooltip": "Submitter - Tooltip",
|
||||||
|
"TreeNode": "TreeNode",
|
||||||
|
"Write": "Write"
|
||||||
},
|
},
|
||||||
"product": {
|
"product": {
|
||||||
"Alipay": "Alipay",
|
"Alipay": "Alipay",
|
||||||
@ -373,9 +443,12 @@
|
|||||||
"CNY": "CNY",
|
"CNY": "CNY",
|
||||||
"Currency": "Moneda",
|
"Currency": "Moneda",
|
||||||
"Currency - Tooltip": "Moneda - Tooltip",
|
"Currency - Tooltip": "Moneda - Tooltip",
|
||||||
|
"Description": "Description",
|
||||||
|
"Description - Tooltip": "Description - Tooltip",
|
||||||
"Detail": "Detalle",
|
"Detail": "Detalle",
|
||||||
"Detail - Tooltip": "Detalle - Tooltip",
|
"Detail - Tooltip": "Detalle - Tooltip",
|
||||||
"Edit Product": "Editar Producto",
|
"Edit Product": "Editar Producto",
|
||||||
|
"I have completed the payment": "I have completed the payment",
|
||||||
"Image": "Imagen",
|
"Image": "Imagen",
|
||||||
"Image - Tooltip": "Imagen - Tooltip",
|
"Image - Tooltip": "Imagen - Tooltip",
|
||||||
"New Product": "Nuevo producto",
|
"New Product": "Nuevo producto",
|
||||||
@ -384,6 +457,8 @@
|
|||||||
"Payment providers - Tooltip": "Pasarelas de pago - Tooltip",
|
"Payment providers - Tooltip": "Pasarelas de pago - Tooltip",
|
||||||
"Paypal": "Paypal",
|
"Paypal": "Paypal",
|
||||||
"Placing order...": "Creando su pedido...",
|
"Placing order...": "Creando su pedido...",
|
||||||
|
"Please provide your username in the remark": "Please provide your username in the remark",
|
||||||
|
"Please scan the QR code to pay": "Please scan the QR code to pay",
|
||||||
"Price": "Precio",
|
"Price": "Precio",
|
||||||
"Price - Tooltip": "Precio - Tooltip",
|
"Price - Tooltip": "Precio - Tooltip",
|
||||||
"Quantity": "Cantidad",
|
"Quantity": "Cantidad",
|
||||||
@ -417,6 +492,9 @@
|
|||||||
"Bucket": "Bucket",
|
"Bucket": "Bucket",
|
||||||
"Bucket - Tooltip": "Bucket - Tooltip",
|
"Bucket - Tooltip": "Bucket - Tooltip",
|
||||||
"Can not parse Metadata": "Can not parse Metadata",
|
"Can not parse Metadata": "Can not parse Metadata",
|
||||||
|
"Can signin": "Can signin",
|
||||||
|
"Can signup": "Can signup",
|
||||||
|
"Can unlink": "Can unlink",
|
||||||
"Category": "Categoria",
|
"Category": "Categoria",
|
||||||
"Category - Tooltip": "Categoria - Tooltip",
|
"Category - Tooltip": "Categoria - Tooltip",
|
||||||
"Channel No.": "Channel No.",
|
"Channel No.": "Channel No.",
|
||||||
@ -439,6 +517,8 @@
|
|||||||
"Email Content - Tooltip": "Contenido del Email - Tooltip",
|
"Email Content - Tooltip": "Contenido del Email - Tooltip",
|
||||||
"Email Title": "Titulo del Email",
|
"Email Title": "Titulo del Email",
|
||||||
"Email Title - Tooltip": "Titulo del Email - Tooltip",
|
"Email Title - Tooltip": "Titulo del Email - Tooltip",
|
||||||
|
"Enable QR code": "Enable QR code",
|
||||||
|
"Enable QR code - Tooltip": "Enable QR code - Tooltip",
|
||||||
"Endpoint": "Endpoint",
|
"Endpoint": "Endpoint",
|
||||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
@ -456,14 +536,18 @@
|
|||||||
"New Provider": "Nuevo Proveedor",
|
"New Provider": "Nuevo Proveedor",
|
||||||
"Parse": "Parsear",
|
"Parse": "Parsear",
|
||||||
"Parse Metadata successfully": "Metadata parseada con éxito",
|
"Parse Metadata successfully": "Metadata parseada con éxito",
|
||||||
|
"Path prefix": "Path prefix",
|
||||||
|
"Please use WeChat and scan the QR code to sign in": "Please use WeChat and scan the QR code to sign in",
|
||||||
"Port": "Puerto",
|
"Port": "Puerto",
|
||||||
"Port - Tooltip": "Puerto - Tooltip",
|
"Port - Tooltip": "Puerto - Tooltip",
|
||||||
|
"Prompted": "Prompted",
|
||||||
"Provider URL": "URL del Proveedor",
|
"Provider URL": "URL del Proveedor",
|
||||||
"Provider URL - Tooltip": "URL del Proveedor - Tooltip",
|
"Provider URL - Tooltip": "URL del Proveedor - Tooltip",
|
||||||
"Region ID": "Region ID",
|
"Region ID": "Region ID",
|
||||||
"Region ID - Tooltip": "Region ID - Tooltip",
|
"Region ID - Tooltip": "Region ID - Tooltip",
|
||||||
"Region endpoint for Internet": "Region endpoint for Internet",
|
"Region endpoint for Internet": "Region endpoint for Internet",
|
||||||
"Region endpoint for Intranet": "Region endpoint for Intranet",
|
"Region endpoint for Intranet": "Region endpoint for Intranet",
|
||||||
|
"Required": "Required",
|
||||||
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
"SAML 2.0 Endpoint (HTTP)": "SAML 2.0 Endpoint (HTTP)",
|
||||||
"SMS account": "SMS account",
|
"SMS account": "SMS account",
|
||||||
"SMS account - Tooltip": "SMS account - Tooltip",
|
"SMS account - Tooltip": "SMS account - Tooltip",
|
||||||
@ -500,19 +584,16 @@
|
|||||||
"Test Connection": "Probar Conexión",
|
"Test Connection": "Probar Conexión",
|
||||||
"Test Email": "Probar Email",
|
"Test Email": "Probar Email",
|
||||||
"Test Email - Tooltip": "Probar Email - Tooltip",
|
"Test Email - Tooltip": "Probar Email - Tooltip",
|
||||||
|
"The prefix path of the file - Tooltip": "The prefix path of the file - Tooltip",
|
||||||
"Token URL": "Token URL",
|
"Token URL": "Token URL",
|
||||||
"Token URL - Tooltip": "Token URL - Tooltip",
|
"Token URL - Tooltip": "Token URL - Tooltip",
|
||||||
"Type": "Tipo",
|
"Type": "Tipo",
|
||||||
"Type - Tooltip": "Tipo - Tooltip",
|
"Type - Tooltip": "Tipo - Tooltip",
|
||||||
"UserInfo URL": "UserInfo URL",
|
"UserInfo URL": "UserInfo URL",
|
||||||
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
|
"UserInfo URL - Tooltip": "UserInfo URL - Tooltip",
|
||||||
"alertType": "alertType",
|
"Visible": "Visible",
|
||||||
"canSignIn": "canSignIn",
|
"admin (share)": "admin (share)",
|
||||||
"canSignUp": "canSignUp",
|
"alertType": "alertType"
|
||||||
"canUnlink": "canUnlink",
|
|
||||||
"prompted": "prompted",
|
|
||||||
"required": "required",
|
|
||||||
"visible": "visible"
|
|
||||||
},
|
},
|
||||||
"record": {
|
"record": {
|
||||||
"Is Triggered": "Esta activado"
|
"Is Triggered": "Esta activado"
|
||||||
@ -597,6 +678,18 @@
|
|||||||
"Table primary key": "Clave primaria de la tabla",
|
"Table primary key": "Clave primaria de la tabla",
|
||||||
"Table primary key - Tooltip": "Clave primaria de la tabla - Tooltip"
|
"Table primary key - Tooltip": "Clave primaria de la tabla - Tooltip"
|
||||||
},
|
},
|
||||||
|
"system": {
|
||||||
|
"About Casdoor": "About Casdoor",
|
||||||
|
"An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS": "An Identity and Access Management (IAM) / Single-Sign-On (SSO) platform with web UI supporting OAuth 2.0, OIDC, SAML and CAS",
|
||||||
|
"CPU Usage": "CPU Usage",
|
||||||
|
"Community": "Community",
|
||||||
|
"Get CPU Usage Failed": "Get CPU Usage Failed",
|
||||||
|
"Get Memory Usage Failed": "Get Memory Usage Failed",
|
||||||
|
"Memory Usage": "Memory Usage",
|
||||||
|
"Official Website": "Official Website",
|
||||||
|
"Unknown Version": "Unknown Version",
|
||||||
|
"Version": "Version"
|
||||||
|
},
|
||||||
"token": {
|
"token": {
|
||||||
"Access token": "Token de acceso",
|
"Access token": "Token de acceso",
|
||||||
"Authorization code": "Código de autorización",
|
"Authorization code": "Código de autorización",
|
||||||
@ -623,6 +716,7 @@
|
|||||||
"Country/Region": "Pais/Región",
|
"Country/Region": "Pais/Región",
|
||||||
"Country/Region - Tooltip": "Pais/Región - Tooltip",
|
"Country/Region - Tooltip": "Pais/Región - Tooltip",
|
||||||
"Edit User": "Editar usuario",
|
"Edit User": "Editar usuario",
|
||||||
|
"Email cannot be empty": "Email cannot be empty",
|
||||||
"Empty input!": "Campo requerido!",
|
"Empty input!": "Campo requerido!",
|
||||||
"Homepage": "Página de Inicio",
|
"Homepage": "Página de Inicio",
|
||||||
"Homepage - Tooltip": "Página de Inicio - Tooltip",
|
"Homepage - Tooltip": "Página de Inicio - Tooltip",
|
||||||
@ -637,9 +731,11 @@
|
|||||||
"Is forbidden - Tooltip": "Está prohibido - Tooltip",
|
"Is forbidden - Tooltip": "Está prohibido - Tooltip",
|
||||||
"Is global admin": "Es admin global",
|
"Is global admin": "Es admin global",
|
||||||
"Is global admin - Tooltip": "Es admin global - Tooltip",
|
"Is global admin - Tooltip": "Es admin global - Tooltip",
|
||||||
|
"Keys": "Keys",
|
||||||
"Link": "Enlace",
|
"Link": "Enlace",
|
||||||
"Location": "Ubicación",
|
"Location": "Ubicación",
|
||||||
"Location - Tooltip": "Ubicación - Tooltip",
|
"Location - Tooltip": "Ubicación - Tooltip",
|
||||||
|
"Managed accounts": "Managed accounts",
|
||||||
"Modify password...": "Cambiar contraseña...",
|
"Modify password...": "Cambiar contraseña...",
|
||||||
"New Email": "Nuevo Email",
|
"New Email": "Nuevo Email",
|
||||||
"New Password": "Nueva Contraseña",
|
"New Password": "Nueva Contraseña",
|
||||||
@ -649,7 +745,10 @@
|
|||||||
"Old Password": "Contraseña anterior",
|
"Old Password": "Contraseña anterior",
|
||||||
"Password": "Contraseña",
|
"Password": "Contraseña",
|
||||||
"Password Set": "Password Set",
|
"Password Set": "Password Set",
|
||||||
|
"Phone cannot be empty": "Phone cannot be empty",
|
||||||
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Propiedades",
|
"Properties": "Propiedades",
|
||||||
|
"Properties - Tooltip": "Properties - Tooltip",
|
||||||
"Re-enter New": "Reingrese de nuevo",
|
"Re-enter New": "Reingrese de nuevo",
|
||||||
"Reset Email...": "Cambiar Email...",
|
"Reset Email...": "Cambiar Email...",
|
||||||
"Reset Phone...": "Cambiar Phone...",
|
"Reset Phone...": "Cambiar Phone...",
|
||||||
@ -665,6 +764,7 @@
|
|||||||
"Unlink": "Desvincular",
|
"Unlink": "Desvincular",
|
||||||
"Upload (.xlsx)": "Subir archivo (.xlsx)",
|
"Upload (.xlsx)": "Subir archivo (.xlsx)",
|
||||||
"Upload a photo": "Subir foto",
|
"Upload a photo": "Subir foto",
|
||||||
|
"Values": "Values",
|
||||||
"WebAuthn credentials": "WebAuthn credentials",
|
"WebAuthn credentials": "WebAuthn credentials",
|
||||||
"input password": "input password"
|
"input password": "input password"
|
||||||
},
|
},
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user