mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-08 09:01:00 +08:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
a8381e875b | |||
4c81fd7d16 | |||
25ee4226d3 | |||
9d5b019243 | |||
6bb7b545b4 | |||
25d56ee8d5 | |||
7e5952c804 | |||
80bf29d79a | |||
971e53dfd8 | |||
654b903d7a | |||
2f72e6971b | |||
d4b587b93e | |||
ac7a510949 | |||
d86f3c88c7 | |||
7c77519069 | |||
2bdf467e3a | |||
52b692c8ad | |||
304643736b | |||
b0f572c51a |
10
Dockerfile
10
Dockerfile
@ -14,6 +14,9 @@ RUN ./build.sh
|
|||||||
FROM alpine:latest AS STANDARD
|
FROM alpine:latest AS STANDARD
|
||||||
LABEL MAINTAINER="https://casdoor.org/"
|
LABEL MAINTAINER="https://casdoor.org/"
|
||||||
ARG USER=casdoor
|
ARG USER=casdoor
|
||||||
|
ARG TARGETOS
|
||||||
|
ARG TARGETARCH
|
||||||
|
ENV BUILDX_ARCH="${TARGETOS:-linux}_${TARGETARCH:-amd64}"
|
||||||
|
|
||||||
RUN sed -i 's/https/http/' /etc/apk/repositories
|
RUN sed -i 's/https/http/' /etc/apk/repositories
|
||||||
RUN apk add --update sudo
|
RUN apk add --update sudo
|
||||||
@ -28,7 +31,7 @@ RUN adduser -D $USER -u 1000 \
|
|||||||
|
|
||||||
USER 1000
|
USER 1000
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/server ./server
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/server_${BUILDX_ARCH} ./server
|
||||||
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/swagger ./swagger
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/swagger ./swagger
|
||||||
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/conf/app.conf ./conf/app.conf
|
COPY --from=BACK --chown=$USER:$USER /go/src/casdoor/conf/app.conf ./conf/app.conf
|
||||||
COPY --from=FRONT --chown=$USER:$USER /web/build ./web/build
|
COPY --from=FRONT --chown=$USER:$USER /web/build ./web/build
|
||||||
@ -46,12 +49,15 @@ RUN apt update \
|
|||||||
|
|
||||||
FROM db AS ALLINONE
|
FROM db AS ALLINONE
|
||||||
LABEL MAINTAINER="https://casdoor.org/"
|
LABEL MAINTAINER="https://casdoor.org/"
|
||||||
|
ARG TARGETOS
|
||||||
|
ARG TARGETARCH
|
||||||
|
ENV BUILDX_ARCH="${TARGETOS:-linux}_${TARGETARCH:-amd64}"
|
||||||
|
|
||||||
RUN apt update
|
RUN apt update
|
||||||
RUN apt install -y ca-certificates && update-ca-certificates
|
RUN apt install -y ca-certificates && update-ca-certificates
|
||||||
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=BACK /go/src/casdoor/server ./server
|
COPY --from=BACK /go/src/casdoor/server_${BUILDX_ARCH} ./server
|
||||||
COPY --from=BACK /go/src/casdoor/swagger ./swagger
|
COPY --from=BACK /go/src/casdoor/swagger ./swagger
|
||||||
COPY --from=BACK /go/src/casdoor/docker-entrypoint.sh /docker-entrypoint.sh
|
COPY --from=BACK /go/src/casdoor/docker-entrypoint.sh /docker-entrypoint.sh
|
||||||
COPY --from=BACK /go/src/casdoor/conf/app.conf ./conf/app.conf
|
COPY --from=BACK /go/src/casdoor/conf/app.conf ./conf/app.conf
|
||||||
|
3
build.sh
3
build.sh
@ -8,4 +8,5 @@ else
|
|||||||
echo "Google is blocked, Go proxy is enabled: GOPROXY=https://goproxy.cn,direct"
|
echo "Google is blocked, Go proxy is enabled: GOPROXY=https://goproxy.cn,direct"
|
||||||
export GOPROXY="https://goproxy.cn,direct"
|
export GOPROXY="https://goproxy.cn,direct"
|
||||||
fi
|
fi
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o server .
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o server_linux_amd64 .
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-w -s" -o server_linux_arm64 .
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
package captcha
|
package captcha
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
type CaptchaProvider interface {
|
type CaptchaProvider interface {
|
||||||
VerifyCaptcha(token, clientSecret string) (bool, error)
|
VerifyCaptcha(token, clientSecret string) (bool, error)
|
||||||
}
|
}
|
||||||
@ -32,3 +34,12 @@ func GetCaptchaProvider(captchaType string) CaptchaProvider {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func VerifyCaptchaByCaptchaType(captchaType, token, clientSecret string) (bool, error) {
|
||||||
|
provider := GetCaptchaProvider(captchaType)
|
||||||
|
if provider == nil {
|
||||||
|
return false, fmt.Errorf("invalid captcha provider: %s", captchaType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider.VerifyCaptcha(token, clientSecret)
|
||||||
|
}
|
||||||
|
@ -20,3 +20,4 @@ staticBaseUrl = "https://cdn.casbin.org"
|
|||||||
isDemoMode = false
|
isDemoMode = false
|
||||||
batchSize = 100
|
batchSize = 100
|
||||||
ldapServerPort = 389
|
ldapServerPort = 389
|
||||||
|
languages = en,zh,es,fr,de,ja,ko,ru
|
||||||
|
@ -64,6 +64,10 @@ type RequestForm struct {
|
|||||||
RelayState string `json:"relayState"`
|
RelayState string `json:"relayState"`
|
||||||
SamlRequest string `json:"samlRequest"`
|
SamlRequest string `json:"samlRequest"`
|
||||||
SamlResponse string `json:"samlResponse"`
|
SamlResponse string `json:"samlResponse"`
|
||||||
|
|
||||||
|
CaptchaType string `json:"captchaType"`
|
||||||
|
CaptchaToken string `json:"captchaToken"`
|
||||||
|
ClientSecret string `json:"clientSecret"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
@ -98,7 +102,7 @@ type Captcha struct {
|
|||||||
// @router /signup [post]
|
// @router /signup [post]
|
||||||
func (c *ApiController) Signup() {
|
func (c *ApiController) Signup() {
|
||||||
if c.GetSessionUsername() != "" {
|
if c.GetSessionUsername() != "" {
|
||||||
c.ResponseError("Please sign out first before signing up", c.GetSessionUsername())
|
c.ResponseError(c.T("SignUpErr.SignOutFirst"), c.GetSessionUsername())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,21 +115,21 @@ func (c *ApiController) Signup() {
|
|||||||
|
|
||||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||||
if !application.EnableSignUp {
|
if !application.EnableSignUp {
|
||||||
c.ResponseError("The application does not allow to sign up new account")
|
c.ResponseError(c.T("SignUpErr.DoNotAllowSignUp"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", form.Organization))
|
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", form.Organization))
|
||||||
msg := object.CheckUserSignup(application, organization, form.Username, form.Password, form.Name, form.FirstName, form.LastName, form.Email, form.Phone, form.Affiliation)
|
msg := object.CheckUserSignup(application, organization, form.Username, form.Password, form.Name, form.FirstName, form.LastName, form.Email, form.Phone, form.Affiliation, c.GetAcceptLanguage())
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
c.ResponseError(msg)
|
c.ResponseError(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Email") && application.GetSignupItemRule("Email") != "No verification" && form.Email != "" {
|
if application.IsSignupItemVisible("Email") && application.GetSignupItemRule("Email") != "No verification" && form.Email != "" {
|
||||||
checkResult := object.CheckVerificationCode(form.Email, form.EmailCode)
|
checkResult := object.CheckVerificationCode(form.Email, form.EmailCode, c.GetAcceptLanguage())
|
||||||
if len(checkResult) != 0 {
|
if len(checkResult) != 0 {
|
||||||
c.ResponseError(fmt.Sprintf("Email: %s", checkResult))
|
c.ResponseError(c.T("EmailErr.EmailCheckResult"), checkResult)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,9 +137,9 @@ func (c *ApiController) Signup() {
|
|||||||
var checkPhone string
|
var checkPhone string
|
||||||
if application.IsSignupItemVisible("Phone") && form.Phone != "" {
|
if application.IsSignupItemVisible("Phone") && form.Phone != "" {
|
||||||
checkPhone = fmt.Sprintf("+%s%s", form.PhonePrefix, form.Phone)
|
checkPhone = fmt.Sprintf("+%s%s", form.PhonePrefix, form.Phone)
|
||||||
checkResult := object.CheckVerificationCode(checkPhone, form.PhoneCode)
|
checkResult := object.CheckVerificationCode(checkPhone, form.PhoneCode, c.GetAcceptLanguage())
|
||||||
if len(checkResult) != 0 {
|
if len(checkResult) != 0 {
|
||||||
c.ResponseError(fmt.Sprintf("Phone: %s", checkResult))
|
c.ResponseError(c.T("PhoneErr.PhoneCheckResult"), checkResult)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,7 +163,7 @@ func (c *ApiController) Signup() {
|
|||||||
|
|
||||||
initScore, err := getInitScore()
|
initScore, err := getInitScore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(fmt.Errorf("get init score failed, error: %w", err).Error())
|
c.ResponseError(fmt.Errorf(c.T("InitErr.InitScoreFailed"), err).Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +209,7 @@ func (c *ApiController) Signup() {
|
|||||||
|
|
||||||
affected := object.AddUser(user)
|
affected := object.AddUser(user)
|
||||||
if !affected {
|
if !affected {
|
||||||
c.ResponseError(fmt.Sprintf("Failed to create user, user information is invalid: %s", util.StructToJson(user)))
|
c.ResponseError(c.T("UserErr.InvalidInformation"), util.StructToJson(user))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,8 +245,7 @@ func (c *ApiController) Logout() {
|
|||||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||||
|
|
||||||
application := c.GetSessionApplication()
|
application := c.GetSessionApplication()
|
||||||
c.SetSessionUsername("")
|
c.ClearUserSession()
|
||||||
c.SetSessionData(nil)
|
|
||||||
|
|
||||||
if application == nil || application.Name == "app-built-in" || application.HomepageUrl == "" {
|
if application == nil || application.Name == "app-built-in" || application.HomepageUrl == "" {
|
||||||
c.ResponseOk(user)
|
c.ResponseOk(user)
|
||||||
@ -309,7 +312,7 @@ func (c *ApiController) GetCaptcha() {
|
|||||||
applicationId := c.Input().Get("applicationId")
|
applicationId := c.Input().Get("applicationId")
|
||||||
isCurrentProvider := c.Input().Get("isCurrentProvider")
|
isCurrentProvider := c.Input().Get("isCurrentProvider")
|
||||||
|
|
||||||
captchaProvider, err := object.GetCaptchaProviderByApplication(applicationId, isCurrentProvider)
|
captchaProvider, err := object.GetCaptchaProviderByApplication(applicationId, isCurrentProvider, c.GetAcceptLanguage())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
|
@ -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("The user: %s doesn't exist", id))
|
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExist"), id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ func (c *ApiController) GetOrganizationApplications() {
|
|||||||
organization := c.Input().Get("organization")
|
organization := c.Input().Get("organization")
|
||||||
|
|
||||||
if organization == "" {
|
if organization == "" {
|
||||||
c.ResponseError("Parameter organization is missing")
|
c.ResponseError(c.T("ParameterErr.OrgMissingErr"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/captcha"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/idp"
|
"github.com/casdoor/casdoor/idp"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
@ -56,7 +58,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !allowed {
|
if !allowed {
|
||||||
c.ResponseError("Unauthorized operation")
|
c.ResponseError(c.T("AuthErr.Unauthorized"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +77,10 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
|||||||
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("Challenge method should be S256")
|
c.ResponseError(c.T("AuthErr.ChallengeMethodErr"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
code := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state, nonce, codeChallenge, c.Ctx.Request.Host)
|
code := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state, nonce, codeChallenge, c.Ctx.Request.Host, c.GetAcceptLanguage())
|
||||||
resp = codeToResponse(code)
|
resp = codeToResponse(code)
|
||||||
|
|
||||||
if application.EnableSigninSession || application.HasPromptPage() {
|
if application.EnableSigninSession || application.HasPromptPage() {
|
||||||
@ -151,7 +153,7 @@ func (c *ApiController) GetApplicationLogin() {
|
|||||||
scope := c.Input().Get("scope")
|
scope := c.Input().Get("scope")
|
||||||
state := c.Input().Get("state")
|
state := c.Input().Get("state")
|
||||||
|
|
||||||
msg, application := object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state)
|
msg, application := object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, c.GetAcceptLanguage())
|
||||||
application = object.GetMaskedApplication(application, "")
|
application = object.GetMaskedApplication(application, "")
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
c.ResponseError(msg, application)
|
c.ResponseError(msg, application)
|
||||||
@ -196,7 +198,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("Please sign out first before signing in", c.GetSessionUsername())
|
c.ResponseError(c.T("LoginErr.SignOutFirst"), c.GetSessionUsername())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,11 +220,11 @@ func (c *ApiController) Login() {
|
|||||||
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)
|
checkResult = object.CheckVerificationCode(form.Username, form.Code, c.GetAcceptLanguage())
|
||||||
} else {
|
} else {
|
||||||
verificationCodeType = "phone"
|
verificationCodeType = "phone"
|
||||||
if len(form.PhonePrefix) == 0 {
|
if len(form.PhonePrefix) == 0 {
|
||||||
responseText := fmt.Sprintf("%s%s", verificationCodeType, "No phone prefix")
|
responseText := fmt.Sprintf(c.T("PhoneErr.NoPrefix"), verificationCodeType)
|
||||||
c.ResponseError(responseText)
|
c.ResponseError(responseText)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -230,7 +232,7 @@ func (c *ApiController) Login() {
|
|||||||
form.Username = user.Phone
|
form.Username = user.Phone
|
||||||
}
|
}
|
||||||
checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)
|
checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)
|
||||||
checkResult = object.CheckVerificationCode(checkPhone, form.Code)
|
checkResult = object.CheckVerificationCode(checkPhone, 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)
|
||||||
@ -247,12 +249,31 @@ func (c *ApiController) Login() {
|
|||||||
|
|
||||||
user = object.GetUserByFields(form.Organization, form.Username)
|
user = object.GetUserByFields(form.Organization, form.Username)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf("The user: %s/%s doesn't exist", form.Organization, form.Username))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.UserDoNotExist"), form.Organization, form.Username))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||||
|
if application == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf("The application: %s does not exist", form.Application))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if object.CheckToEnableCaptcha(application) {
|
||||||
|
isHuman, err := captcha.VerifyCaptchaByCaptchaType(form.CaptchaType, form.CaptchaToken, form.ClientSecret)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isHuman {
|
||||||
|
c.ResponseError("Turing test failed.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
password := form.Password
|
password := form.Password
|
||||||
user, msg = object.CheckUserPassword(form.Organization, form.Username, password)
|
user, msg = object.CheckUserPassword(form.Organization, form.Username, password, c.GetAcceptLanguage())
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
@ -260,7 +281,7 @@ func (c *ApiController) Login() {
|
|||||||
} 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("The application: %s does not exist", form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppDoNotExist"), form.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +295,7 @@ func (c *ApiController) Login() {
|
|||||||
} else if form.Provider != "" {
|
} else if form.Provider != "" {
|
||||||
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("The application: %s does not exist", form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppDoNotExist"), form.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +303,7 @@ func (c *ApiController) Login() {
|
|||||||
provider := object.GetProvider(fmt.Sprintf("admin/%s", form.Provider))
|
provider := object.GetProvider(fmt.Sprintf("admin/%s", form.Provider))
|
||||||
providerItem := application.GetProviderItem(provider.Name)
|
providerItem := application.GetProviderItem(provider.Name)
|
||||||
if !providerItem.IsProviderVisible() {
|
if !providerItem.IsProviderVisible() {
|
||||||
c.ResponseError(fmt.Sprintf("The provider: %s is not enabled for the application", provider.Name))
|
c.ResponseError(fmt.Sprintf(c.T("ProviderErr.ProviderNotEnabled"), provider.Name))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,14 +327,14 @@ func (c *ApiController) Login() {
|
|||||||
|
|
||||||
idProvider := idp.GetIdProvider(provider.Type, provider.SubType, clientId, clientSecret, provider.AppId, form.RedirectUri, provider.Domain, provider.CustomAuthUrl, provider.CustomTokenUrl, provider.CustomUserInfoUrl)
|
idProvider := idp.GetIdProvider(provider.Type, provider.SubType, clientId, clientSecret, provider.AppId, form.RedirectUri, provider.Domain, provider.CustomAuthUrl, provider.CustomTokenUrl, provider.CustomUserInfoUrl)
|
||||||
if idProvider == nil {
|
if idProvider == nil {
|
||||||
c.ResponseError(fmt.Sprintf("The provider type: %s is not supported", provider.Type))
|
c.ResponseError(fmt.Sprintf(c.T("ProviderErr.ProviderNotSupported"), provider.Type))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setHttpClient(idProvider, provider.Type)
|
setHttpClient(idProvider, provider.Type)
|
||||||
|
|
||||||
if form.State != conf.GetConfigString("authState") && form.State != application.Name {
|
if form.State != conf.GetConfigString("authState") && form.State != application.Name {
|
||||||
c.ResponseError(fmt.Sprintf("state expected: \"%s\", but got: \"%s\"", conf.GetConfigString("authState"), form.State))
|
c.ResponseError(fmt.Sprintf(c.T("AuthErr.AuthStateWrong"), conf.GetConfigString("authState"), form.State))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,13 +346,13 @@ func (c *ApiController) Login() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !token.Valid() {
|
if !token.Valid() {
|
||||||
c.ResponseError("Invalid token")
|
c.ResponseError(c.T("TokenErr.InvalidToken"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userInfo, err = idProvider.GetUserInfo(token)
|
userInfo, err = idProvider.GetUserInfo(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(fmt.Sprintf("Failed to login in: %s", err.Error()))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.LoginFail"), err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,7 +369,7 @@ func (c *ApiController) Login() {
|
|||||||
// Sign in via OAuth (want to sign up but already have account)
|
// Sign in via OAuth (want to sign up but already have account)
|
||||||
|
|
||||||
if user.IsForbidden {
|
if user.IsForbidden {
|
||||||
c.ResponseError("the user is forbidden to sign in, please contact the administrator")
|
c.ResponseError(c.T("LoginErr.UserIsForbidden"))
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = c.HandleLoggedIn(application, user, &form)
|
resp = c.HandleLoggedIn(application, user, &form)
|
||||||
@ -360,12 +381,12 @@ func (c *ApiController) Login() {
|
|||||||
} else if provider.Category == "OAuth" {
|
} else if provider.Category == "OAuth" {
|
||||||
// Sign up via OAuth
|
// Sign up via OAuth
|
||||||
if !application.EnableSignUp {
|
if !application.EnableSignUp {
|
||||||
c.ResponseError(fmt.Sprintf("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", provider.Type, userInfo.Username, userInfo.DisplayName))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppNotEnableSignUp"), provider.Type, userInfo.Username, userInfo.DisplayName))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !providerItem.CanSignUp {
|
if !providerItem.CanSignUp {
|
||||||
c.ResponseError(fmt.Sprintf("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", provider.Type, userInfo.Username, userInfo.DisplayName, provider.Type))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.ProviderCanNotSignUp"), provider.Type, userInfo.Username, userInfo.DisplayName, provider.Type))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +407,7 @@ func (c *ApiController) Login() {
|
|||||||
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
||||||
initScore, err := getInitScore()
|
initScore, err := getInitScore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(fmt.Errorf("get init score failed, error: %w", err).Error())
|
c.ResponseError(fmt.Errorf(c.T("InitErr.InitScoreFailed"), err).Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +434,7 @@ func (c *ApiController) Login() {
|
|||||||
|
|
||||||
affected := object.AddUser(user)
|
affected := object.AddUser(user)
|
||||||
if !affected {
|
if !affected {
|
||||||
c.ResponseError(fmt.Sprintf("Failed to create user, user information is invalid: %s", util.StructToJson(user)))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.InvalidUserInformation"), util.StructToJson(user)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,13 +459,13 @@ func (c *ApiController) Login() {
|
|||||||
} else { // form.Method != "signup"
|
} else { // form.Method != "signup"
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError("The account does not exist", userInfo)
|
c.ResponseError(c.T("LoginErr.AccountDoNotExist"), userInfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
oldUser := object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
oldUser := object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
||||||
if oldUser != nil {
|
if oldUser != nil {
|
||||||
c.ResponseError(fmt.Sprintf("The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)", provider.Type, userInfo.Username, userInfo.DisplayName, oldUser.Name, oldUser.DisplayName))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.OldUser"), provider.Type, userInfo.Username, userInfo.DisplayName, oldUser.Name, oldUser.DisplayName))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +486,7 @@ func (c *ApiController) Login() {
|
|||||||
// user already signed in to Casdoor, so let the user click the avatar button to do the quick sign-in
|
// user already signed in to Casdoor, so let the user click the avatar button to do the quick sign-in
|
||||||
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("The application: %s does not exist", form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppDoNotExist"), form.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +498,7 @@ func (c *ApiController) Login() {
|
|||||||
record.User = user.Name
|
record.User = user.Name
|
||||||
util.SafeGoroutine(func() { object.AddRecord(record) })
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
} else {
|
} else {
|
||||||
c.ResponseError(fmt.Sprintf("unknown authentication type (not password or provider), form = %s", util.StructToJson(form)))
|
c.ResponseError(fmt.Sprintf(c.T("LoginErr.UnknownAuthentication"), util.StructToJson(form)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -489,7 +510,7 @@ func (c *ApiController) Login() {
|
|||||||
func (c *ApiController) GetSamlLogin() {
|
func (c *ApiController) GetSamlLogin() {
|
||||||
providerId := c.Input().Get("id")
|
providerId := c.Input().Get("id")
|
||||||
relayState := c.Input().Get("relayState")
|
relayState := c.Input().Get("relayState")
|
||||||
authURL, method, err := object.GenerateSamlLoginUrl(providerId, relayState)
|
authURL, method, err := object.GenerateSamlLoginUrl(providerId, relayState, c.GetAcceptLanguage())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,7 @@ func (c *ApiController) GetSessionUsername() string {
|
|||||||
if sessionData != nil &&
|
if sessionData != nil &&
|
||||||
sessionData.ExpireTime != 0 &&
|
sessionData.ExpireTime != 0 &&
|
||||||
sessionData.ExpireTime < time.Now().Unix() {
|
sessionData.ExpireTime < time.Now().Unix() {
|
||||||
c.SetSessionUsername("")
|
c.ClearUserSession()
|
||||||
c.SetSessionData(nil)
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,13 +84,17 @@ func (c *ApiController) GetSessionApplication() *object.Application {
|
|||||||
return application
|
return application
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) ClearUserSession() {
|
||||||
|
c.SetSessionUsername("")
|
||||||
|
c.SetSessionData(nil)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *ApiController) GetSessionOidc() (string, string) {
|
func (c *ApiController) GetSessionOidc() (string, string) {
|
||||||
sessionData := c.GetSessionData()
|
sessionData := c.GetSessionData()
|
||||||
if sessionData != nil &&
|
if sessionData != nil &&
|
||||||
sessionData.ExpireTime != 0 &&
|
sessionData.ExpireTime != 0 &&
|
||||||
sessionData.ExpireTime < time.Now().Unix() {
|
sessionData.ExpireTime < time.Now().Unix() {
|
||||||
c.SetSessionUsername("")
|
c.ClearUserSession()
|
||||||
c.SetSessionData(nil)
|
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
scopeValue := c.GetSession("scope")
|
scopeValue := c.GetSession("scope")
|
||||||
|
@ -210,7 +210,7 @@ func (c *RootController) SamlValidate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(target, service) {
|
if !strings.HasPrefix(target, service) {
|
||||||
c.ResponseError(fmt.Sprintf("service %s and %s do not match", target, service))
|
c.ResponseError(fmt.Sprintf(c.T("CasErr.ServiceDoNotMatch"), target, service))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
func (c *ApiController) Enforce() {
|
func (c *ApiController) Enforce() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError("Please sign in first")
|
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ func (c *ApiController) Enforce() {
|
|||||||
func (c *ApiController) BatchEnforce() {
|
func (c *ApiController) BatchEnforce() {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError("Please sign in first")
|
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,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("Please sign in first")
|
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,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("Please sign in first")
|
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,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("Please sign in first")
|
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||||
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("Missing parameter")
|
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||||
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("Missing parameter")
|
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,17 +136,17 @@ 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("Missing parameter")
|
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||||
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("Missing parameter")
|
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if object.CheckLdapExist(&ldap) {
|
if object.CheckLdapExist(&ldap) {
|
||||||
c.ResponseError("Ldap server exist")
|
c.ResponseError(c.T("LdapErr.ServerExisted"))
|
||||||
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("Missing parameter")
|
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ func handleBind(w ldapserver.ResponseWriter, m *ldapserver.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
bindpassword := string(r.AuthenticationSimple())
|
bindpassword := string(r.AuthenticationSimple())
|
||||||
binduser, err := object.CheckUserPassword(bindorg, bindusername, bindpassword)
|
binduser, err := object.CheckUserPassword(bindorg, bindusername, bindpassword, "en")
|
||||||
if err != "" {
|
if err != "" {
|
||||||
log.Printf("Bind failed User=%s, Pass=%#v, ErrMsg=%s", string(r.Name()), r.Authentication(), err)
|
log.Printf("Bind failed User=%s, Pass=%#v, ErrMsg=%s", string(r.Name()), r.Authentication(), err)
|
||||||
res.SetResultCode(ldapserver.LDAPResultInvalidCredentials)
|
res.SetResultCode(ldapserver.LDAPResultInvalidCredentials)
|
||||||
|
@ -47,7 +47,7 @@ func (c *ApiController) Unlink() {
|
|||||||
|
|
||||||
if user.Id != unlinkedUser.Id && !user.IsGlobalAdmin {
|
if user.Id != unlinkedUser.Id && !user.IsGlobalAdmin {
|
||||||
// if the user is not the same as the one we are unlinking, we need to make sure the user is the global admin.
|
// if the user is not the same as the one we are unlinking, we need to make sure the user is the global admin.
|
||||||
c.ResponseError("You are not the global admin, you can't unlink other users")
|
c.ResponseError(c.T("AuthErr.CanNotUnlinkUsers"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,23 +55,23 @@ func (c *ApiController) Unlink() {
|
|||||||
// if the user is unlinking themselves, should check the provider can be unlinked, if not, we should return an error.
|
// if the user is unlinking themselves, should check the provider can be unlinked, if not, we should return an error.
|
||||||
application := object.GetApplicationByUser(user)
|
application := object.GetApplicationByUser(user)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError("You can't unlink yourself, you are not a member of any application")
|
c.ResponseError(c.T("AuthErr.CanNotLinkMySelf"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(application.Providers) == 0 {
|
if len(application.Providers) == 0 {
|
||||||
c.ResponseError("This application has no providers")
|
c.ResponseError(c.T("ApplicationErr.HasNoProviders"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := application.GetProviderItemByType(providerType)
|
provider := application.GetProviderItemByType(providerType)
|
||||||
if provider == nil {
|
if provider == nil {
|
||||||
c.ResponseError("This application has no providers of type " + providerType)
|
c.ResponseError(c.T("ApplicationErr.HasNoProvidersOfType") + providerType)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !provider.CanUnlink {
|
if !provider.CanUnlink {
|
||||||
c.ResponseError("This provider can't be unlinked")
|
c.ResponseError(c.T("ProviderErr.CanNotBeUnlinked"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ func (c *ApiController) Unlink() {
|
|||||||
value := object.GetUserField(&unlinkedUser, providerType)
|
value := object.GetUserField(&unlinkedUser, providerType)
|
||||||
|
|
||||||
if value == "" {
|
if value == "" {
|
||||||
c.ResponseError("Please link first", value)
|
c.ResponseError(c.T("ProviderErr.LinkFirstErr"), value)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,13 +141,13 @@ func (c *ApiController) BuyProduct() {
|
|||||||
|
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError("Please login first")
|
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user := object.GetUser(userId)
|
user := object.GetUser(userId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf("The user: %s doesn't exist", userId))
|
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExist"), userId))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ func (c *ApiController) DeleteResource() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = object.DeleteFile(provider, resource.Name)
|
err = object.DeleteFile(provider, resource.Name, c.GetAcceptLanguage())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -145,7 +145,7 @@ func (c *ApiController) UploadResource() {
|
|||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
if username == "" || fullFilePath == "" {
|
if username == "" || fullFilePath == "" {
|
||||||
c.ResponseError(fmt.Sprintf("username or fullFilePath is empty: username = %s, fullFilePath = %s", username, fullFilePath))
|
c.ResponseError(fmt.Sprintf(c.T("ResourceErr.UsernameOrFilePathEmpty"), username, fullFilePath))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ func (c *ApiController) UploadResource() {
|
|||||||
if user == nil {
|
if user == nil {
|
||||||
user = object.GetUserNoCheck(username)
|
user = object.GetUserNoCheck(username)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError("user is nil for tag: \"avatar\"")
|
c.ResponseError(c.T("ResourceErr.UserIsNil"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ func (c *ApiController) GetSamlMeta() {
|
|||||||
paramApp := c.Input().Get("application")
|
paramApp := c.Input().Get("application")
|
||||||
application := object.GetApplication(paramApp)
|
application := object.GetApplication(paramApp)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf("err: application %s not found", paramApp))
|
c.ResponseError(fmt.Sprintf(c.T("ApplicationErr.AppNotFound"), paramApp))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
metadata, _ := object.GetSamlMeta(application, host)
|
metadata, _ := object.GetSamlMeta(application, host)
|
||||||
|
@ -81,7 +81,7 @@ func (c *ApiController) SendEmail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if util.IsStrsEmpty(emailForm.Title, emailForm.Content, emailForm.Sender) {
|
if util.IsStrsEmpty(emailForm.Title, emailForm.Content, emailForm.Sender) {
|
||||||
c.ResponseError(fmt.Sprintf("Empty parameters for emailForm: %v", emailForm))
|
c.ResponseError(fmt.Sprintf(c.T("EmailErr.EmptyParam"), emailForm))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ func (c *ApiController) SendEmail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(invalidReceivers) != 0 {
|
if len(invalidReceivers) != 0 {
|
||||||
c.ResponseError(fmt.Sprintf("Invalid Email receivers: %s", invalidReceivers))
|
c.ResponseError(fmt.Sprintf(c.T("EmailErr.InvalidReceivers"), invalidReceivers))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ func (c *ApiController) SendSms() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(invalidReceivers) != 0 {
|
if len(invalidReceivers) != 0 {
|
||||||
c.ResponseError(fmt.Sprintf("Invalid phone receivers: %s", invalidReceivers))
|
c.ResponseError(fmt.Sprintf(c.T("PhoneErr.InvalidReceivers"), invalidReceivers))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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("You are not authorized to access this resource")
|
c.ResponseError(c.T("ResourceErr.NotAuthorized"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,12 +150,12 @@ 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("Challenge method should be S256")
|
c.ResponseError(c.T("AuthErr.ChallengeMethodErr"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
host := c.Ctx.Request.Host
|
host := c.Ctx.Request.Host
|
||||||
|
|
||||||
c.Data["json"] = object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state, nonce, codeChallenge, host)
|
c.Data["json"] = object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state, nonce, codeChallenge, host, c.GetAcceptLanguage())
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ func (c *ApiController) GetOAuthToken() {
|
|||||||
}
|
}
|
||||||
host := c.Ctx.Request.Host
|
host := c.Ctx.Request.Host
|
||||||
|
|
||||||
c.Data["json"] = object.GetOAuthToken(grantType, clientId, clientSecret, code, verifier, scope, username, password, host, tag, avatar)
|
c.Data["json"] = object.GetOAuthToken(grantType, clientId, clientSecret, code, verifier, scope, username, password, host, tag, avatar, c.GetAcceptLanguage())
|
||||||
c.SetTokenErrorHttpStatus()
|
c.SetTokenErrorHttpStatus()
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ func (c *ApiController) IntrospectToken() {
|
|||||||
clientId = c.Input().Get("client_id")
|
clientId = c.Input().Get("client_id")
|
||||||
clientSecret = c.Input().Get("client_secret")
|
clientSecret = c.Input().Get("client_secret")
|
||||||
if clientId == "" || clientSecret == "" {
|
if clientId == "" || clientSecret == "" {
|
||||||
c.ResponseError("empty clientId or clientSecret")
|
c.ResponseError(c.T("TokenErr.EmptyClientID"))
|
||||||
c.Data["json"] = &object.TokenError{
|
c.Data["json"] = &object.TokenError{
|
||||||
Error: object.InvalidRequest,
|
Error: object.InvalidRequest,
|
||||||
}
|
}
|
||||||
@ -301,7 +301,7 @@ func (c *ApiController) IntrospectToken() {
|
|||||||
}
|
}
|
||||||
application := object.GetApplicationByClientId(clientId)
|
application := object.GetApplicationByClientId(clientId)
|
||||||
if application == nil || application.ClientSecret != clientSecret {
|
if application == nil || application.ClientSecret != clientSecret {
|
||||||
c.ResponseError("invalid application or wrong clientSecret")
|
c.ResponseError(c.T("TokenErr.InvalidAppOrWrongClientSecret"))
|
||||||
c.Data["json"] = &object.TokenError{
|
c.Data["json"] = &object.TokenError{
|
||||||
Error: object.InvalidClient,
|
Error: object.InvalidClient,
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ func (c *ApiController) GetUser() {
|
|||||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", owner))
|
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", owner))
|
||||||
if !organization.IsProfilePublic {
|
if !organization.IsProfilePublic {
|
||||||
requestUserId := c.GetSessionUsername()
|
requestUserId := c.GetSessionUsername()
|
||||||
hasPermission, err := object.CheckUserPermission(requestUserId, id, owner, false)
|
hasPermission, err := object.CheckUserPermission(requestUserId, id, owner, false, c.GetAcceptLanguage())
|
||||||
if !hasPermission {
|
if !hasPermission {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -149,7 +149,7 @@ func (c *ApiController) UpdateUser() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if user.DisplayName == "" {
|
if user.DisplayName == "" {
|
||||||
c.ResponseError("Display name cannot be empty")
|
c.ResponseError(c.T("UserErr.DisplayNameCanNotBeEmpty"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ func (c *ApiController) AddUser() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := object.CheckUsername(user.Name)
|
msg := object.CheckUsername(user.Name, c.GetAcceptLanguage())
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
c.ResponseError(msg)
|
c.ResponseError(msg)
|
||||||
return
|
return
|
||||||
@ -230,7 +230,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("The user: %s/%s doesn't exist", form.Organization, form.Username))
|
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExistInOrg"), form.Organization, form.Username))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ func (c *ApiController) SetPassword() {
|
|||||||
requestUserId := c.GetSessionUsername()
|
requestUserId := c.GetSessionUsername()
|
||||||
userId := fmt.Sprintf("%s/%s", userOwner, userName)
|
userId := fmt.Sprintf("%s/%s", userOwner, userName)
|
||||||
|
|
||||||
hasPermission, err := object.CheckUserPermission(requestUserId, userId, userOwner, true)
|
hasPermission, err := object.CheckUserPermission(requestUserId, userId, userOwner, true, c.GetAcceptLanguage())
|
||||||
if !hasPermission {
|
if !hasPermission {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -280,7 +280,7 @@ func (c *ApiController) SetPassword() {
|
|||||||
targetUser := object.GetUser(userId)
|
targetUser := object.GetUser(userId)
|
||||||
|
|
||||||
if oldPassword != "" {
|
if oldPassword != "" {
|
||||||
msg := object.CheckPassword(targetUser, oldPassword)
|
msg := object.CheckPassword(targetUser, oldPassword, c.GetAcceptLanguage())
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
c.ResponseError(msg)
|
c.ResponseError(msg)
|
||||||
return
|
return
|
||||||
@ -288,12 +288,12 @@ func (c *ApiController) SetPassword() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(newPassword, " ") {
|
if strings.Contains(newPassword, " ") {
|
||||||
c.ResponseError("New password cannot contain blank space.")
|
c.ResponseError(c.T("SetPasswordErr.CanNotContainBlank"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(newPassword) <= 5 {
|
if len(newPassword) <= 5 {
|
||||||
c.ResponseError("New password must have at least 6 characters")
|
c.ResponseError(c.T("SetPasswordErr.LessThanSixCharacters"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ func (c *ApiController) CheckUserPassword() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, msg := object.CheckUserPassword(user.Owner, user.Name, user.Password)
|
_, msg := object.CheckUserPassword(user.Owner, user.Name, user.Password, c.GetAcceptLanguage())
|
||||||
if msg == "" {
|
if msg == "" {
|
||||||
c.ResponseOk()
|
c.ResponseOk()
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,6 +61,6 @@ func (c *ApiController) UploadUsers() {
|
|||||||
if affected {
|
if affected {
|
||||||
c.ResponseOk()
|
c.ResponseOk()
|
||||||
} else {
|
} else {
|
||||||
c.ResponseError("Failed to import users")
|
c.ResponseError(c.T("UserErr.FailToImportUsers"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
)
|
)
|
||||||
@ -48,6 +49,19 @@ func (c *ApiController) ResponseError(error string, data ...interface{}) {
|
|||||||
c.ResponseJsonData(resp, data...)
|
c.ResponseJsonData(resp, data...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) T(error string) string {
|
||||||
|
return i18n.Translate(c.GetAcceptLanguage(), error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAcceptLanguage ...
|
||||||
|
func (c *ApiController) GetAcceptLanguage() string {
|
||||||
|
lang := c.Ctx.Request.Header.Get("Accept-Language")
|
||||||
|
if lang == "" {
|
||||||
|
lang = "en"
|
||||||
|
}
|
||||||
|
return lang[0:2]
|
||||||
|
}
|
||||||
|
|
||||||
// SetTokenErrorHttpStatus ...
|
// SetTokenErrorHttpStatus ...
|
||||||
func (c *ApiController) SetTokenErrorHttpStatus() {
|
func (c *ApiController) SetTokenErrorHttpStatus() {
|
||||||
_, ok := c.Data["json"].(*object.TokenError)
|
_, ok := c.Data["json"].(*object.TokenError)
|
||||||
@ -69,7 +83,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("Please sign in first")
|
c.ResponseError(c.T("LoginErr.LoginFirst"), "Please login first")
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
return userId, true
|
return userId, true
|
||||||
@ -84,7 +98,8 @@ func (c *ApiController) RequireSignedInUser() (*object.User, bool) {
|
|||||||
|
|
||||||
user := object.GetUser(userId)
|
user := object.GetUser(userId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(fmt.Sprintf("The user: %s doesn't exist", userId))
|
c.ClearUserSession()
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExist"), userId))
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return user, true
|
return user, true
|
||||||
@ -112,7 +127,7 @@ func (c *ApiController) GetProviderFromContext(category string) (*object.Provide
|
|||||||
if providerName != "" {
|
if providerName != "" {
|
||||||
provider := object.GetProvider(util.GetId(providerName))
|
provider := object.GetProvider(util.GetId(providerName))
|
||||||
if provider == nil {
|
if provider == nil {
|
||||||
c.ResponseError(fmt.Sprintf("The provider: %s is not found", providerName))
|
c.ResponseError(c.T("ProviderErr.ProviderNotFound"), providerName)
|
||||||
return nil, nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
return provider, nil, true
|
return provider, nil, true
|
||||||
@ -125,13 +140,13 @@ func (c *ApiController) GetProviderFromContext(category string) (*object.Provide
|
|||||||
|
|
||||||
application, user := object.GetApplicationByUserId(userId)
|
application, user := object.GetApplicationByUserId(userId)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf("No application is found for userId: \"%s\"", userId))
|
c.ResponseError(fmt.Sprintf(c.T("ApplicationErr.AppNotFoundForUserID"), userId))
|
||||||
return nil, nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := application.GetProviderByCategory(category)
|
provider := application.GetProviderByCategory(category)
|
||||||
if provider == nil {
|
if provider == nil {
|
||||||
c.ResponseError(fmt.Sprintf("No provider for category: \"%s\" is found for application: %s", category, application.Name))
|
c.ResponseError(fmt.Sprintf(c.T("ProviderErr.ProviderNotFoundForCategory"), category, application.Name))
|
||||||
return nil, nil, false
|
return nil, nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,23 +50,23 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
|
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
|
||||||
|
|
||||||
if destType == "" {
|
if destType == "" {
|
||||||
c.ResponseError("Missing parameter: type.")
|
c.ResponseError(c.T("ParameterErr.Missing") + ": type.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if dest == "" {
|
if dest == "" {
|
||||||
c.ResponseError("Missing parameter: dest.")
|
c.ResponseError(c.T("ParameterErr.Missing") + ": dest.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if applicationId == "" {
|
if applicationId == "" {
|
||||||
c.ResponseError("Missing parameter: applicationId.")
|
c.ResponseError(c.T("ParameterErr.Missing") + ": applicationId.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.Contains(applicationId, "/") {
|
if !strings.Contains(applicationId, "/") {
|
||||||
c.ResponseError("Wrong parameter: applicationId.")
|
c.ResponseError(c.T("ParameterErr.Wrong") + ": applicationId.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if checkType == "" {
|
if checkType == "" {
|
||||||
c.ResponseError("Missing parameter: checkType.")
|
c.ResponseError(c.T("ParameterErr.Missing") + ": checkType.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
|
|
||||||
if captchaProvider != nil {
|
if captchaProvider != nil {
|
||||||
if checkKey == "" {
|
if checkKey == "" {
|
||||||
c.ResponseError("Missing parameter: checkKey.")
|
c.ResponseError(c.T("ParameterErr.Missing") + ": checkKey.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isHuman, err := captchaProvider.VerifyCaptcha(checkKey, checkId)
|
isHuman, err := captchaProvider.VerifyCaptcha(checkKey, checkId)
|
||||||
@ -84,7 +84,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !isHuman {
|
if !isHuman {
|
||||||
c.ResponseError("Turing test failed.")
|
c.ResponseError(c.T("AuthErr.NotHuman"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", application.Owner, application.Organization))
|
organization := object.GetOrganization(fmt.Sprintf("%s/%s", application.Owner, application.Organization))
|
||||||
|
|
||||||
if checkUser == "true" && user == nil && object.GetUserByFields(organization.Name, dest) == nil {
|
if checkUser == "true" && user == nil && object.GetUserByFields(organization.Name, dest) == nil {
|
||||||
c.ResponseError("Please login first")
|
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
dest = user.Email
|
dest = user.Email
|
||||||
}
|
}
|
||||||
if !util.IsEmailValid(dest) {
|
if !util.IsEmailValid(dest) {
|
||||||
c.ResponseError("Invalid Email address")
|
c.ResponseError(c.T("EmailErr.EmailInvalid"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,11 +121,11 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
dest = user.Phone
|
dest = user.Phone
|
||||||
}
|
}
|
||||||
if !util.IsPhoneCnValid(dest) {
|
if !util.IsPhoneCnValid(dest) {
|
||||||
c.ResponseError("Invalid phone number")
|
c.ResponseError(c.T("PhoneErr.NumberInvalid"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if organization == nil {
|
if organization == nil {
|
||||||
c.ResponseError("The organization doesn't exist.")
|
c.ResponseError(c.T("OrgErr.DoNotExist"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ 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("Missing parameter.")
|
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +166,11 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
if destType == "phone" {
|
if destType == "phone" {
|
||||||
phoneItem := object.GetAccountItemByName("Phone", org)
|
phoneItem := object.GetAccountItemByName("Phone", org)
|
||||||
if phoneItem == nil {
|
if phoneItem == nil {
|
||||||
c.ResponseError("Unable to get the phone modify rule.")
|
c.ResponseError(c.T("PhoneErr.UnableGetModifyRule"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pass, errMsg := object.CheckAccountItemModifyRule(phoneItem, user); !pass {
|
if pass, errMsg := object.CheckAccountItemModifyRule(phoneItem, user, c.GetAcceptLanguage()); !pass {
|
||||||
c.ResponseError(errMsg)
|
c.ResponseError(errMsg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -183,16 +183,16 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
} else if destType == "email" {
|
} else if destType == "email" {
|
||||||
emailItem := object.GetAccountItemByName("Email", org)
|
emailItem := object.GetAccountItemByName("Email", org)
|
||||||
if emailItem == nil {
|
if emailItem == nil {
|
||||||
c.ResponseError("Unable to get the email modify rule.")
|
c.ResponseError(c.T("EmailErr.UnableGetModifyRule"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pass, errMsg := object.CheckAccountItemModifyRule(emailItem, user); !pass {
|
if pass, errMsg := object.CheckAccountItemModifyRule(emailItem, user, c.GetAcceptLanguage()); !pass {
|
||||||
c.ResponseError(errMsg)
|
c.ResponseError(errMsg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ret := object.CheckVerificationCode(checkDest, code); len(ret) != 0 {
|
if ret := object.CheckVerificationCode(checkDest, code, c.GetAcceptLanguage()); len(ret) != 0 {
|
||||||
c.ResponseError(ret)
|
c.ResponseError(ret)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -205,7 +205,7 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
user.Phone = dest
|
user.Phone = dest
|
||||||
object.SetUserField(user, "phone", user.Phone)
|
object.SetUserField(user, "phone", user.Phone)
|
||||||
default:
|
default:
|
||||||
c.ResponseError("Unknown type.")
|
c.ResponseError(c.T("ParameterErr.UnknownType"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,17 +224,17 @@ 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("Missing parameter: captchaToken.")
|
c.ResponseError(c.T("ParameterErr.Missing") + ": captchaToken.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if clientSecret == "" {
|
if clientSecret == "" {
|
||||||
c.ResponseError("Missing parameter: clientSecret.")
|
c.ResponseError(c.T("ParameterErr.Missing") + ": clientSecret.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := captcha.GetCaptchaProvider(captchaType)
|
provider := captcha.GetCaptchaProvider(captchaType)
|
||||||
if provider == nil {
|
if provider == nil {
|
||||||
c.ResponseError("Invalid captcha provider.")
|
c.ResponseError(c.T("ProviderErr.InvalidProvider"))
|
||||||
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("Please login first.")
|
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,13 +66,13 @@ 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("Please login first.")
|
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sessionObj := c.GetSession("registration")
|
sessionObj := c.GetSession("registration")
|
||||||
sessionData, ok := sessionObj.(webauthn.SessionData)
|
sessionData, ok := sessionObj.(webauthn.SessionData)
|
||||||
if !ok {
|
if !ok {
|
||||||
c.ResponseError("Please call WebAuthnSignupBegin first")
|
c.ResponseError(c.T("AuthErr.CallWebAuthnSigninBegin"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||||
@ -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("The user: %s/%s doesn't exist", userOwner, userName))
|
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExistInOrg"), userOwner, userName))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
options, sessionData, err := webauthnObj.BeginLogin(user)
|
options, sessionData, err := webauthnObj.BeginLogin(user)
|
||||||
@ -127,7 +127,7 @@ func (c *ApiController) WebAuthnSigninFinish() {
|
|||||||
sessionObj := c.GetSession("authentication")
|
sessionObj := c.GetSession("authentication")
|
||||||
sessionData, ok := sessionObj.(webauthn.SessionData)
|
sessionData, ok := sessionObj.(webauthn.SessionData)
|
||||||
if !ok {
|
if !ok {
|
||||||
c.ResponseError("Please call WebAuthnSigninBegin first")
|
c.ResponseError(c.T("AuthErr.CallWebAuthnSigninBegin"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||||
|
3
go.mod
3
go.mod
@ -4,6 +4,7 @@ go 1.16
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b
|
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b
|
||||||
|
github.com/Unknwon/goconfig v1.0.0
|
||||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
|
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
|
||||||
github.com/aws/aws-sdk-go v1.44.4
|
github.com/aws/aws-sdk-go v1.44.4
|
||||||
github.com/beego/beego v1.12.11
|
github.com/beego/beego v1.12.11
|
||||||
@ -47,7 +48,7 @@ require (
|
|||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
gopkg.in/ini.v1 v1.67.0
|
||||||
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
|
||||||
xorm.io/core v0.7.2
|
xorm.io/core v0.7.2
|
||||||
|
6
go.sum
6
go.sum
@ -61,6 +61,8 @@ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go
|
|||||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b h1:EgJ6N2S0h1WfFIjU5/VVHWbMSVYXAluop97Qxpr/lfQ=
|
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b h1:EgJ6N2S0h1WfFIjU5/VVHWbMSVYXAluop97Qxpr/lfQ=
|
||||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b/go.mod h1:3SAoF0F5EbcOuBD5WT9nYkbIJieBS84cUQXADbXeBsU=
|
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b/go.mod h1:3SAoF0F5EbcOuBD5WT9nYkbIJieBS84cUQXADbXeBsU=
|
||||||
|
github.com/Unknwon/goconfig v1.0.0 h1:9IAu/BYbSLQi8puFjUQApZTxIHqSwrj5d8vpP8vTq4A=
|
||||||
|
github.com/Unknwon/goconfig v1.0.0/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
@ -757,8 +759,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
|
|||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
|
122
i18n/generate_backend.go
Normal file
122
i18n/generate_backend.go
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
// 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 (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Unknwon/goconfig"
|
||||||
|
"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.Split(match[1], ",")
|
||||||
|
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]bool {
|
||||||
|
ErrName := make(map[string]bool)
|
||||||
|
for i := 0; i < len(paths); i++ {
|
||||||
|
content := util.ReadStringFromPath(paths[i])
|
||||||
|
words := GetAllI18nStrings(content, paths[i])
|
||||||
|
for i := 0; i < len(words); i++ {
|
||||||
|
ErrName[words[i]] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ErrName
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeToAllLanguageFiles(errName map[string]bool) {
|
||||||
|
languages := "en,zh,es,fr,de,ja,ko,ru"
|
||||||
|
languageArr := strings.Split(languages, ",")
|
||||||
|
var c [10]*goconfig.ConfigFile
|
||||||
|
for i := 0; i < len(languageArr); i++ {
|
||||||
|
var err error
|
||||||
|
c[i], err = goconfig.LoadConfigFile("../i18n/languages/" + "locale_" + languageArr[i] + ".ini")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
for j := range errName {
|
||||||
|
parts := strings.Split(j, ".")
|
||||||
|
_, err := c[i].GetValue(parts[0], parts[1])
|
||||||
|
if err != nil {
|
||||||
|
c[i].SetValue(parts[0], parts[1], parts[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c[i].SetPrettyFormat(true)
|
||||||
|
err = goconfig.SaveConfigFile(c[i], "../i18n/languages/"+"locale_"+languageArr[i]+".ini")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,10 @@
|
|||||||
|
|
||||||
package i18n
|
package i18n
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func applyToOtherLanguage(dataEn *I18nData, lang string) {
|
func applyToOtherLanguage(dataEn *I18nData, lang string) {
|
||||||
dataOther := readI18nFile(lang)
|
dataOther := readI18nFile(lang)
|
||||||
@ -24,7 +27,7 @@ func applyToOtherLanguage(dataEn *I18nData, lang string) {
|
|||||||
writeI18nFile(lang, dataEn)
|
writeI18nFile(lang, dataEn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateI18nStrings(t *testing.T) {
|
func TestGenerateI18nStringsForFrontend(t *testing.T) {
|
||||||
dataEn := parseToData()
|
dataEn := parseToData()
|
||||||
writeI18nFile("en", dataEn)
|
writeI18nFile("en", dataEn)
|
||||||
|
|
||||||
@ -35,3 +38,17 @@ func TestGenerateI18nStrings(t *testing.T) {
|
|||||||
applyToOtherLanguage(dataEn, "ru")
|
applyToOtherLanguage(dataEn, "ru")
|
||||||
applyToOtherLanguage(dataEn, "zh")
|
applyToOtherLanguage(dataEn, "zh")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGenerateI18nStringsForBackend(t *testing.T) {
|
||||||
|
paths := getAllGoFilePaths()
|
||||||
|
|
||||||
|
errName := getErrName(paths)
|
||||||
|
|
||||||
|
writeToAllLanguageFiles(errName)
|
||||||
|
|
||||||
|
fmt.Println("Total Err Words:", len(errName))
|
||||||
|
|
||||||
|
for i := range errName {
|
||||||
|
fmt.Println(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
137
i18n/languages/locale_de.ini
Normal file
137
i18n/languages/locale_de.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = Application %s not found
|
||||||
|
AppNotFoundForUserID = No application is found for userId: %s
|
||||||
|
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||||
|
HasNoProviders = This application has no providers
|
||||||
|
HasNoProvidersOfType = This application has no providers of type
|
||||||
|
InvalidID = Invalid application id
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = State expected: %s, but got: %s
|
||||||
|
ChallengeMethodErr = Challenge method should be S256
|
||||||
|
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||||
|
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||||
|
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||||
|
NotHuman = Turing test failed.
|
||||||
|
Unauthorized = Unauthorized operation
|
||||||
|
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = Service %s and %s do not match
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = Email already exists
|
||||||
|
EmptyErr = Email cannot be empty
|
||||||
|
EmailInvalid = Email is invalid
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = Empty parameters for emailForm: %v
|
||||||
|
InvalidReceivers = Invalid Email receivers: %s
|
||||||
|
UnableGetModifyRule = Unable to get the email modify rule.
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = Please sign in first
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = Get init score failed, error: %%w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||||
|
PasswordWrong = Ldap user name or password incorrect
|
||||||
|
ServerExisted = Ldap server exist
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = The application: %s does not exist
|
||||||
|
AppNotEnableSignUp = 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
|
||||||
|
AccountDoNotExist = The account does not exist
|
||||||
|
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||||
|
LoginFirst = Please login first
|
||||||
|
LoginFail = Failed to login in: %s
|
||||||
|
NoPermission = You don't have the permission to do this
|
||||||
|
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 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
|
||||||
|
SessionOutdated = Session outdated, please login again
|
||||||
|
SignOutFirst = Please sign out first before signing in
|
||||||
|
UserDoNotExist = The user: %s/%s doesn't exist
|
||||||
|
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||||
|
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||||
|
UnsupportedPasswordType = unsupported password type: %s
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = Organization does not exist
|
||||||
|
Immutable = The %s is immutable.
|
||||||
|
OnlyAdmin = Only admin can modify the %s.
|
||||||
|
UnknownModifyRule = Unknown modify rule %s.
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
OrgMissingErr = Parameter organization is missing
|
||||||
|
Missing = Missing parameter
|
||||||
|
UnknownType = Unknown type
|
||||||
|
Wrong = Wrong parameter
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = Code has not been sent yet!
|
||||||
|
CodeTimeOut = You should verify your code in %d min!
|
||||||
|
ExistedErr = Phone already exists
|
||||||
|
EmptyErr = Phone cannot be empty
|
||||||
|
InvalidReceivers = Invalid phone receivers: %s
|
||||||
|
NumberInvalid = Phone number is invalid
|
||||||
|
NoPrefix = %s No phone prefix
|
||||||
|
PhoneCheckResult = Phone: %s
|
||||||
|
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = This provider can't be unlinked
|
||||||
|
CategoryNotSAML = provider %s's category is not SAML
|
||||||
|
DoNotExist = the provider: %s does not exist
|
||||||
|
InvalidProvider = Invalid captcha provider.
|
||||||
|
LinkFirstErr = Please link first
|
||||||
|
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||||
|
ProviderNotSupported = The provider type: %s is not supported
|
||||||
|
ProviderNotFound = The provider: %s is not found
|
||||||
|
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = You are not authorized to access this resource
|
||||||
|
UserIsNil = User is nil for tag: /"avatar/"
|
||||||
|
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = New password cannot contain blank space.
|
||||||
|
LessThanSixCharacters = New password must have at least 6 characters
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||||
|
SignOutFirst = Please sign out first before signing up
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = Empty clientId or clientSecret
|
||||||
|
InvalidToken = Invalid token
|
||||||
|
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||||
|
InvalidClientId = Invalid client_id
|
||||||
|
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = Affiliation cannot be blank
|
||||||
|
DisplayNameBlankErr = DisplayName cannot be blank
|
||||||
|
DisplayNameInvalid = DisplayName is not valid real name
|
||||||
|
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||||
|
DoNotExist = The user: %s doesn't exist
|
||||||
|
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||||
|
DoNotExistSignUp = the user does not exist, please sign up first
|
||||||
|
FirstNameBlankErr = FirstName cannot be blank
|
||||||
|
FailToImportUsers = Failed to import users
|
||||||
|
LastNameBlankErr = LastName cannot be blank
|
||||||
|
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||||
|
NameStartWithADigitErr = Username cannot start with a digit
|
||||||
|
NameIsEmailErr = Username cannot be an email address
|
||||||
|
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||||
|
NameExistedErr = Username already exists
|
||||||
|
NameEmptyErr = Empty username.
|
||||||
|
NameTooLang = Username is too long (maximum is 39 characters).
|
||||||
|
NameFormatErr = 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.
|
||||||
|
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||||
|
InvalidInformation = Invalid information
|
||||||
|
|
137
i18n/languages/locale_en.ini
Normal file
137
i18n/languages/locale_en.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = Application %s not found
|
||||||
|
AppNotFoundForUserID = No application is found for userId: %s
|
||||||
|
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||||
|
HasNoProviders = This application has no providers
|
||||||
|
HasNoProvidersOfType = This application has no providers of type
|
||||||
|
InvalidID = Invalid application id
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = State expected: %s, but got: %s
|
||||||
|
ChallengeMethodErr = Challenge method should be S256
|
||||||
|
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||||
|
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||||
|
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||||
|
NotHuman = Turing test failed.
|
||||||
|
WrongPasswordManyTimes = You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again
|
||||||
|
Unauthorized = Unauthorized operation
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = Service %s and %s do not match
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = Email already exists
|
||||||
|
EmptyErr = Email cannot be empty
|
||||||
|
EmailInvalid = Email is invalid
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = Empty parameters for emailForm: %v
|
||||||
|
InvalidReceivers = Invalid Email receivers: %s
|
||||||
|
UnableGetModifyRule = Unable to get the email modify rule.
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = Please sign in first
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = Get init score failed, error: %%w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||||
|
PasswordWrong = Ldap user name or password incorrect
|
||||||
|
ServerExisted = Ldap server exist
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = The application: %s does not exist
|
||||||
|
AppNotEnableSignUp = 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
|
||||||
|
AccountDoNotExist = The account does not exist
|
||||||
|
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||||
|
LoginFirst = Please login first
|
||||||
|
LoginFail = Failed to login in: %s
|
||||||
|
NoPermission = You don't have the permission to do this
|
||||||
|
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 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
|
||||||
|
SessionOutdated = Session outdated, please login again
|
||||||
|
SignOutFirst = Please sign out first before signing in
|
||||||
|
UserDoNotExist = The user: %s/%s doesn't exist
|
||||||
|
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||||
|
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||||
|
UnsupportedPasswordType = unsupported password type: %s
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = Organization does not exist
|
||||||
|
Immutable = The %s is immutable.
|
||||||
|
OnlyAdmin = Only admin can modify the %s.
|
||||||
|
UnknownModifyRule = Unknown modify rule %s.
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
OrgMissingErr = Parameter organization is missing
|
||||||
|
Missing = Missing parameter
|
||||||
|
UnknownType = Unknown type
|
||||||
|
Wrong = Wrong parameter
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = Code has not been sent yet!
|
||||||
|
CodeTimeOut = You should verify your code in %d min!
|
||||||
|
ExistedErr = Phone already exists
|
||||||
|
EmptyErr = Phone cannot be empty
|
||||||
|
InvalidReceivers = Invalid phone receivers: %s
|
||||||
|
NumberInvalid = Phone number is invalid
|
||||||
|
NoPrefix = %s No phone prefix
|
||||||
|
PhoneCheckResult = Phone: %s
|
||||||
|
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = This provider can't be unlinked
|
||||||
|
CategoryNotSAML = provider %s's category is not SAML
|
||||||
|
DoNotExist = the provider: %s does not exist
|
||||||
|
InvalidProvider = Invalid captcha provider.
|
||||||
|
LinkFirstErr = Please link first
|
||||||
|
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||||
|
ProviderNotSupported = The provider type: %s is not supported
|
||||||
|
ProviderNotFound = The provider: %s is not found
|
||||||
|
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = You are not authorized to access this resource
|
||||||
|
UserIsNil = User is nil for tag: /"avatar/"
|
||||||
|
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = New password cannot contain blank space.
|
||||||
|
LessThanSixCharacters = New password must have at least 6 characters
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||||
|
SignOutFirst = Please sign out first before signing up
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = Empty clientId or clientSecret
|
||||||
|
InvalidToken = Invalid token
|
||||||
|
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||||
|
InvalidClientId = Invalid client_id
|
||||||
|
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = Affiliation cannot be blank
|
||||||
|
DisplayNameBlankErr = DisplayName cannot be blank
|
||||||
|
DisplayNameInvalid = DisplayName is not valid real name
|
||||||
|
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||||
|
DoNotExist = The user: %s doesn't exist
|
||||||
|
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||||
|
DoNotExistSignUp = the user does not exist, please sign up first
|
||||||
|
FirstNameBlankErr = FirstName cannot be blank
|
||||||
|
FailToImportUsers = Failed to import users
|
||||||
|
LastNameBlankErr = LastName cannot be blank
|
||||||
|
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||||
|
NameStartWithADigitErr = Username cannot start with a digit
|
||||||
|
NameIsEmailErr = Username cannot be an email address
|
||||||
|
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||||
|
NameExistedErr = Username already exists
|
||||||
|
NameEmptyErr = Empty username.
|
||||||
|
NameTooLang = Username is too long (maximum is 39 characters).
|
||||||
|
NameFormatErr = 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.
|
||||||
|
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||||
|
InvalidInformation = Invalid information
|
||||||
|
|
137
i18n/languages/locale_es.ini
Normal file
137
i18n/languages/locale_es.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = Application %s not found
|
||||||
|
AppNotFoundForUserID = No application is found for userId: %s
|
||||||
|
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||||
|
HasNoProviders = This application has no providers
|
||||||
|
HasNoProvidersOfType = This application has no providers of type
|
||||||
|
InvalidID = Invalid application id
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = State expected: %s, but got: %s
|
||||||
|
ChallengeMethodErr = Challenge method should be S256
|
||||||
|
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||||
|
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||||
|
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||||
|
NotHuman = Turing test failed.
|
||||||
|
Unauthorized = Unauthorized operation
|
||||||
|
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = Service %s and %s do not match
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = Email already exists
|
||||||
|
EmptyErr = Email cannot be empty
|
||||||
|
EmailInvalid = Email is invalid
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = Empty parameters for emailForm: %v
|
||||||
|
InvalidReceivers = Invalid Email receivers: %s
|
||||||
|
UnableGetModifyRule = Unable to get the email modify rule.
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = Please sign in first
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = Get init score failed, error: %%w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||||
|
PasswordWrong = Ldap user name or password incorrect
|
||||||
|
ServerExisted = Ldap server exist
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = The application: %s does not exist
|
||||||
|
AppNotEnableSignUp = 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
|
||||||
|
AccountDoNotExist = The account does not exist
|
||||||
|
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||||
|
LoginFirst = Please login first
|
||||||
|
LoginFail = Failed to login in: %s
|
||||||
|
NoPermission = You don't have the permission to do this
|
||||||
|
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 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
|
||||||
|
SessionOutdated = Session outdated, please login again
|
||||||
|
SignOutFirst = Please sign out first before signing in
|
||||||
|
UserDoNotExist = The user: %s/%s doesn't exist
|
||||||
|
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||||
|
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||||
|
UnsupportedPasswordType = unsupported password type: %s
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = Organization does not exist
|
||||||
|
Immutable = The %s is immutable.
|
||||||
|
OnlyAdmin = Only admin can modify the %s.
|
||||||
|
UnknownModifyRule = Unknown modify rule %s.
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
OrgMissingErr = Parameter organization is missing
|
||||||
|
Missing = Missing parameter
|
||||||
|
UnknownType = Unknown type
|
||||||
|
Wrong = Wrong parameter
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = Code has not been sent yet!
|
||||||
|
CodeTimeOut = You should verify your code in %d min!
|
||||||
|
ExistedErr = Phone already exists
|
||||||
|
EmptyErr = Phone cannot be empty
|
||||||
|
InvalidReceivers = Invalid phone receivers: %s
|
||||||
|
NumberInvalid = Phone number is invalid
|
||||||
|
NoPrefix = %s No phone prefix
|
||||||
|
PhoneCheckResult = Phone: %s
|
||||||
|
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = This provider can't be unlinked
|
||||||
|
CategoryNotSAML = provider %s's category is not SAML
|
||||||
|
DoNotExist = the provider: %s does not exist
|
||||||
|
InvalidProvider = Invalid captcha provider.
|
||||||
|
LinkFirstErr = Please link first
|
||||||
|
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||||
|
ProviderNotSupported = The provider type: %s is not supported
|
||||||
|
ProviderNotFound = The provider: %s is not found
|
||||||
|
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = You are not authorized to access this resource
|
||||||
|
UserIsNil = User is nil for tag: /"avatar/"
|
||||||
|
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = New password cannot contain blank space.
|
||||||
|
LessThanSixCharacters = New password must have at least 6 characters
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||||
|
SignOutFirst = Please sign out first before signing up
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = Empty clientId or clientSecret
|
||||||
|
InvalidToken = Invalid token
|
||||||
|
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||||
|
InvalidClientId = Invalid client_id
|
||||||
|
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = Affiliation cannot be blank
|
||||||
|
DisplayNameBlankErr = DisplayName cannot be blank
|
||||||
|
DisplayNameInvalid = DisplayName is not valid real name
|
||||||
|
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||||
|
DoNotExist = The user: %s doesn't exist
|
||||||
|
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||||
|
DoNotExistSignUp = the user does not exist, please sign up first
|
||||||
|
FirstNameBlankErr = FirstName cannot be blank
|
||||||
|
FailToImportUsers = Failed to import users
|
||||||
|
LastNameBlankErr = LastName cannot be blank
|
||||||
|
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||||
|
NameStartWithADigitErr = Username cannot start with a digit
|
||||||
|
NameIsEmailErr = Username cannot be an email address
|
||||||
|
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||||
|
NameExistedErr = Username already exists
|
||||||
|
NameEmptyErr = Empty username.
|
||||||
|
NameTooLang = Username is too long (maximum is 39 characters).
|
||||||
|
NameFormatErr = 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.
|
||||||
|
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||||
|
InvalidInformation = Invalid information
|
||||||
|
|
137
i18n/languages/locale_fr.ini
Normal file
137
i18n/languages/locale_fr.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = Application %s not found
|
||||||
|
AppNotFoundForUserID = No application is found for userId: %s
|
||||||
|
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||||
|
HasNoProviders = This application has no providers
|
||||||
|
HasNoProvidersOfType = This application has no providers of type
|
||||||
|
InvalidID = Invalid application id
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = State expected: %s, but got: %s
|
||||||
|
ChallengeMethodErr = Challenge method should be S256
|
||||||
|
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||||
|
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||||
|
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||||
|
NotHuman = Turing test failed.
|
||||||
|
Unauthorized = Unauthorized operation
|
||||||
|
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = Service %s and %s do not match
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = Email already exists
|
||||||
|
EmptyErr = Email cannot be empty
|
||||||
|
EmailInvalid = Email is invalid
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = Empty parameters for emailForm: %v
|
||||||
|
InvalidReceivers = Invalid Email receivers: %s
|
||||||
|
UnableGetModifyRule = Unable to get the email modify rule.
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = Please sign in first
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = Get init score failed, error: %%w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||||
|
PasswordWrong = Ldap user name or password incorrect
|
||||||
|
ServerExisted = Ldap server exist
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = The application: %s does not exist
|
||||||
|
AppNotEnableSignUp = 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
|
||||||
|
AccountDoNotExist = The account does not exist
|
||||||
|
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||||
|
LoginFirst = Please login first
|
||||||
|
LoginFail = Failed to login in: %s
|
||||||
|
NoPermission = You don't have the permission to do this
|
||||||
|
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 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
|
||||||
|
SessionOutdated = Session outdated, please login again
|
||||||
|
SignOutFirst = Please sign out first before signing in
|
||||||
|
UserDoNotExist = The user: %s/%s doesn't exist
|
||||||
|
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||||
|
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||||
|
UnsupportedPasswordType = unsupported password type: %s
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = Organization does not exist
|
||||||
|
Immutable = The %s is immutable.
|
||||||
|
OnlyAdmin = Only admin can modify the %s.
|
||||||
|
UnknownModifyRule = Unknown modify rule %s.
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
OrgMissingErr = Parameter organization is missing
|
||||||
|
Missing = Missing parameter
|
||||||
|
UnknownType = Unknown type
|
||||||
|
Wrong = Wrong parameter
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = Code has not been sent yet!
|
||||||
|
CodeTimeOut = You should verify your code in %d min!
|
||||||
|
ExistedErr = Phone already exists
|
||||||
|
EmptyErr = Phone cannot be empty
|
||||||
|
InvalidReceivers = Invalid phone receivers: %s
|
||||||
|
NumberInvalid = Phone number is invalid
|
||||||
|
NoPrefix = %s No phone prefix
|
||||||
|
PhoneCheckResult = Phone: %s
|
||||||
|
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = This provider can't be unlinked
|
||||||
|
CategoryNotSAML = provider %s's category is not SAML
|
||||||
|
DoNotExist = the provider: %s does not exist
|
||||||
|
InvalidProvider = Invalid captcha provider.
|
||||||
|
LinkFirstErr = Please link first
|
||||||
|
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||||
|
ProviderNotSupported = The provider type: %s is not supported
|
||||||
|
ProviderNotFound = The provider: %s is not found
|
||||||
|
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = You are not authorized to access this resource
|
||||||
|
UserIsNil = User is nil for tag: /"avatar/"
|
||||||
|
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = New password cannot contain blank space.
|
||||||
|
LessThanSixCharacters = New password must have at least 6 characters
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||||
|
SignOutFirst = Please sign out first before signing up
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = Empty clientId or clientSecret
|
||||||
|
InvalidToken = Invalid token
|
||||||
|
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||||
|
InvalidClientId = Invalid client_id
|
||||||
|
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = Affiliation cannot be blank
|
||||||
|
DisplayNameBlankErr = DisplayName cannot be blank
|
||||||
|
DisplayNameInvalid = DisplayName is not valid real name
|
||||||
|
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||||
|
DoNotExist = The user: %s doesn't exist
|
||||||
|
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||||
|
DoNotExistSignUp = the user does not exist, please sign up first
|
||||||
|
FirstNameBlankErr = FirstName cannot be blank
|
||||||
|
FailToImportUsers = Failed to import users
|
||||||
|
LastNameBlankErr = LastName cannot be blank
|
||||||
|
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||||
|
NameStartWithADigitErr = Username cannot start with a digit
|
||||||
|
NameIsEmailErr = Username cannot be an email address
|
||||||
|
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||||
|
NameExistedErr = Username already exists
|
||||||
|
NameEmptyErr = Empty username.
|
||||||
|
NameTooLang = Username is too long (maximum is 39 characters).
|
||||||
|
NameFormatErr = 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.
|
||||||
|
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||||
|
InvalidInformation = Invalid information
|
||||||
|
|
137
i18n/languages/locale_ja.ini
Normal file
137
i18n/languages/locale_ja.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = Application %s not found
|
||||||
|
AppNotFoundForUserID = No application is found for userId: %s
|
||||||
|
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||||
|
HasNoProviders = This application has no providers
|
||||||
|
HasNoProvidersOfType = This application has no providers of type
|
||||||
|
InvalidID = Invalid application id
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = State expected: %s, but got: %s
|
||||||
|
ChallengeMethodErr = Challenge method should be S256
|
||||||
|
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||||
|
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||||
|
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||||
|
NotHuman = Turing test failed.
|
||||||
|
Unauthorized = Unauthorized operation
|
||||||
|
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = Service %s and %s do not match
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = Email already exists
|
||||||
|
EmptyErr = Email cannot be empty
|
||||||
|
EmailInvalid = Email is invalid
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = Empty parameters for emailForm: %v
|
||||||
|
InvalidReceivers = Invalid Email receivers: %s
|
||||||
|
UnableGetModifyRule = Unable to get the email modify rule.
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = Please sign in first
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = Get init score failed, error: %%w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||||
|
PasswordWrong = Ldap user name or password incorrect
|
||||||
|
ServerExisted = Ldap server exist
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = The application: %s does not exist
|
||||||
|
AppNotEnableSignUp = 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
|
||||||
|
AccountDoNotExist = The account does not exist
|
||||||
|
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||||
|
LoginFirst = Please login first
|
||||||
|
LoginFail = Failed to login in: %s
|
||||||
|
NoPermission = You don't have the permission to do this
|
||||||
|
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 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
|
||||||
|
SessionOutdated = Session outdated, please login again
|
||||||
|
SignOutFirst = Please sign out first before signing in
|
||||||
|
UserDoNotExist = The user: %s/%s doesn't exist
|
||||||
|
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||||
|
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||||
|
UnsupportedPasswordType = unsupported password type: %s
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = Organization does not exist
|
||||||
|
Immutable = The %s is immutable.
|
||||||
|
OnlyAdmin = Only admin can modify the %s.
|
||||||
|
UnknownModifyRule = Unknown modify rule %s.
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
OrgMissingErr = Parameter organization is missing
|
||||||
|
Missing = Missing parameter
|
||||||
|
UnknownType = Unknown type
|
||||||
|
Wrong = Wrong parameter
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = Code has not been sent yet!
|
||||||
|
CodeTimeOut = You should verify your code in %d min!
|
||||||
|
ExistedErr = Phone already exists
|
||||||
|
EmptyErr = Phone cannot be empty
|
||||||
|
InvalidReceivers = Invalid phone receivers: %s
|
||||||
|
NumberInvalid = Phone number is invalid
|
||||||
|
NoPrefix = %s No phone prefix
|
||||||
|
PhoneCheckResult = Phone: %s
|
||||||
|
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = This provider can't be unlinked
|
||||||
|
CategoryNotSAML = provider %s's category is not SAML
|
||||||
|
DoNotExist = the provider: %s does not exist
|
||||||
|
InvalidProvider = Invalid captcha provider.
|
||||||
|
LinkFirstErr = Please link first
|
||||||
|
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||||
|
ProviderNotSupported = The provider type: %s is not supported
|
||||||
|
ProviderNotFound = The provider: %s is not found
|
||||||
|
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = You are not authorized to access this resource
|
||||||
|
UserIsNil = User is nil for tag: /"avatar/"
|
||||||
|
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = New password cannot contain blank space.
|
||||||
|
LessThanSixCharacters = New password must have at least 6 characters
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||||
|
SignOutFirst = Please sign out first before signing up
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = Empty clientId or clientSecret
|
||||||
|
InvalidToken = Invalid token
|
||||||
|
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||||
|
InvalidClientId = Invalid client_id
|
||||||
|
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = Affiliation cannot be blank
|
||||||
|
DisplayNameBlankErr = DisplayName cannot be blank
|
||||||
|
DisplayNameInvalid = DisplayName is not valid real name
|
||||||
|
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||||
|
DoNotExist = The user: %s doesn't exist
|
||||||
|
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||||
|
DoNotExistSignUp = the user does not exist, please sign up first
|
||||||
|
FirstNameBlankErr = FirstName cannot be blank
|
||||||
|
FailToImportUsers = Failed to import users
|
||||||
|
LastNameBlankErr = LastName cannot be blank
|
||||||
|
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||||
|
NameStartWithADigitErr = Username cannot start with a digit
|
||||||
|
NameIsEmailErr = Username cannot be an email address
|
||||||
|
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||||
|
NameExistedErr = Username already exists
|
||||||
|
NameEmptyErr = Empty username.
|
||||||
|
NameTooLang = Username is too long (maximum is 39 characters).
|
||||||
|
NameFormatErr = 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.
|
||||||
|
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||||
|
InvalidInformation = Invalid information
|
||||||
|
|
137
i18n/languages/locale_ko.ini
Normal file
137
i18n/languages/locale_ko.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = Application %s not found
|
||||||
|
AppNotFoundForUserID = No application is found for userId: %s
|
||||||
|
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||||
|
HasNoProviders = This application has no providers
|
||||||
|
HasNoProvidersOfType = This application has no providers of type
|
||||||
|
InvalidID = Invalid application id
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = State expected: %s, but got: %s
|
||||||
|
ChallengeMethodErr = Challenge method should be S256
|
||||||
|
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||||
|
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||||
|
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||||
|
NotHuman = Turing test failed.
|
||||||
|
Unauthorized = Unauthorized operation
|
||||||
|
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = Service %s and %s do not match
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = Email already exists
|
||||||
|
EmptyErr = Email cannot be empty
|
||||||
|
EmailInvalid = Email is invalid
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = Empty parameters for emailForm: %v
|
||||||
|
InvalidReceivers = Invalid Email receivers: %s
|
||||||
|
UnableGetModifyRule = Unable to get the email modify rule.
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = Please sign in first
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = Get init score failed, error: %%w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||||
|
PasswordWrong = Ldap user name or password incorrect
|
||||||
|
ServerExisted = Ldap server exist
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = The application: %s does not exist
|
||||||
|
AppNotEnableSignUp = 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
|
||||||
|
AccountDoNotExist = The account does not exist
|
||||||
|
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||||
|
LoginFirst = Please login first
|
||||||
|
LoginFail = Failed to login in: %s
|
||||||
|
NoPermission = You don't have the permission to do this
|
||||||
|
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 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
|
||||||
|
SessionOutdated = Session outdated, please login again
|
||||||
|
SignOutFirst = Please sign out first before signing in
|
||||||
|
UserDoNotExist = The user: %s/%s doesn't exist
|
||||||
|
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||||
|
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||||
|
UnsupportedPasswordType = unsupported password type: %s
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = Organization does not exist
|
||||||
|
Immutable = The %s is immutable.
|
||||||
|
OnlyAdmin = Only admin can modify the %s.
|
||||||
|
UnknownModifyRule = Unknown modify rule %s.
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
OrgMissingErr = Parameter organization is missing
|
||||||
|
Missing = Missing parameter
|
||||||
|
UnknownType = Unknown type
|
||||||
|
Wrong = Wrong parameter
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = Code has not been sent yet!
|
||||||
|
CodeTimeOut = You should verify your code in %d min!
|
||||||
|
ExistedErr = Phone already exists
|
||||||
|
EmptyErr = Phone cannot be empty
|
||||||
|
InvalidReceivers = Invalid phone receivers: %s
|
||||||
|
NumberInvalid = Phone number is invalid
|
||||||
|
NoPrefix = %s No phone prefix
|
||||||
|
PhoneCheckResult = Phone: %s
|
||||||
|
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = This provider can't be unlinked
|
||||||
|
CategoryNotSAML = provider %s's category is not SAML
|
||||||
|
DoNotExist = the provider: %s does not exist
|
||||||
|
InvalidProvider = Invalid captcha provider.
|
||||||
|
LinkFirstErr = Please link first
|
||||||
|
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||||
|
ProviderNotSupported = The provider type: %s is not supported
|
||||||
|
ProviderNotFound = The provider: %s is not found
|
||||||
|
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = You are not authorized to access this resource
|
||||||
|
UserIsNil = User is nil for tag: /"avatar/"
|
||||||
|
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = New password cannot contain blank space.
|
||||||
|
LessThanSixCharacters = New password must have at least 6 characters
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||||
|
SignOutFirst = Please sign out first before signing up
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = Empty clientId or clientSecret
|
||||||
|
InvalidToken = Invalid token
|
||||||
|
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||||
|
InvalidClientId = Invalid client_id
|
||||||
|
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = Affiliation cannot be blank
|
||||||
|
DisplayNameBlankErr = DisplayName cannot be blank
|
||||||
|
DisplayNameInvalid = DisplayName is not valid real name
|
||||||
|
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||||
|
DoNotExist = The user: %s doesn't exist
|
||||||
|
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||||
|
DoNotExistSignUp = the user does not exist, please sign up first
|
||||||
|
FirstNameBlankErr = FirstName cannot be blank
|
||||||
|
FailToImportUsers = Failed to import users
|
||||||
|
LastNameBlankErr = LastName cannot be blank
|
||||||
|
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||||
|
NameStartWithADigitErr = Username cannot start with a digit
|
||||||
|
NameIsEmailErr = Username cannot be an email address
|
||||||
|
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||||
|
NameExistedErr = Username already exists
|
||||||
|
NameEmptyErr = Empty username.
|
||||||
|
NameTooLang = Username is too long (maximum is 39 characters).
|
||||||
|
NameFormatErr = 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.
|
||||||
|
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||||
|
InvalidInformation = Invalid information
|
||||||
|
|
137
i18n/languages/locale_ru.ini
Normal file
137
i18n/languages/locale_ru.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = Application %s not found
|
||||||
|
AppNotFoundForUserID = No application is found for userId: %s
|
||||||
|
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||||
|
HasNoProviders = This application has no providers
|
||||||
|
HasNoProvidersOfType = This application has no providers of type
|
||||||
|
InvalidID = Invalid application id
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = State expected: %s, but got: %s
|
||||||
|
ChallengeMethodErr = Challenge method should be S256
|
||||||
|
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||||
|
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||||
|
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||||
|
NotHuman = Turing test failed.
|
||||||
|
Unauthorized = Unauthorized operation
|
||||||
|
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = Service %s and %s do not match
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = Email already exists
|
||||||
|
EmptyErr = Email cannot be empty
|
||||||
|
EmailInvalid = Email is invalid
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = Empty parameters for emailForm: %v
|
||||||
|
InvalidReceivers = Invalid Email receivers: %s
|
||||||
|
UnableGetModifyRule = Unable to get the email modify rule.
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = Please sign in first
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = Get init score failed, error: %%w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||||
|
PasswordWrong = Ldap user name or password incorrect
|
||||||
|
ServerExisted = Ldap server exist
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = The application: %s does not exist
|
||||||
|
AppNotEnableSignUp = 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
|
||||||
|
AccountDoNotExist = The account does not exist
|
||||||
|
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||||
|
LoginFirst = Please login first
|
||||||
|
LoginFail = Failed to login in: %s
|
||||||
|
NoPermission = You don't have the permission to do this
|
||||||
|
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 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
|
||||||
|
SessionOutdated = Session outdated, please login again
|
||||||
|
SignOutFirst = Please sign out first before signing in
|
||||||
|
UserDoNotExist = The user: %s/%s doesn't exist
|
||||||
|
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||||
|
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||||
|
UnsupportedPasswordType = unsupported password type: %s
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = Organization does not exist
|
||||||
|
Immutable = The %s is immutable.
|
||||||
|
OnlyAdmin = Only admin can modify the %s.
|
||||||
|
UnknownModifyRule = Unknown modify rule %s.
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
OrgMissingErr = Parameter organization is missing
|
||||||
|
Missing = Missing parameter
|
||||||
|
UnknownType = Unknown type
|
||||||
|
Wrong = Wrong parameter
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = Code has not been sent yet!
|
||||||
|
CodeTimeOut = You should verify your code in %d min!
|
||||||
|
ExistedErr = Phone already exists
|
||||||
|
EmptyErr = Phone cannot be empty
|
||||||
|
InvalidReceivers = Invalid phone receivers: %s
|
||||||
|
NumberInvalid = Phone number is invalid
|
||||||
|
NoPrefix = %s No phone prefix
|
||||||
|
PhoneCheckResult = Phone: %s
|
||||||
|
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = This provider can't be unlinked
|
||||||
|
CategoryNotSAML = provider %s's category is not SAML
|
||||||
|
DoNotExist = the provider: %s does not exist
|
||||||
|
InvalidProvider = Invalid captcha provider.
|
||||||
|
LinkFirstErr = Please link first
|
||||||
|
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||||
|
ProviderNotSupported = The provider type: %s is not supported
|
||||||
|
ProviderNotFound = The provider: %s is not found
|
||||||
|
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = You are not authorized to access this resource
|
||||||
|
UserIsNil = User is nil for tag: /"avatar/"
|
||||||
|
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = New password cannot contain blank space.
|
||||||
|
LessThanSixCharacters = New password must have at least 6 characters
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||||
|
SignOutFirst = Please sign out first before signing up
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = Empty clientId or clientSecret
|
||||||
|
InvalidToken = Invalid token
|
||||||
|
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||||
|
InvalidClientId = Invalid client_id
|
||||||
|
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = Affiliation cannot be blank
|
||||||
|
DisplayNameBlankErr = DisplayName cannot be blank
|
||||||
|
DisplayNameInvalid = DisplayName is not valid real name
|
||||||
|
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||||
|
DoNotExist = The user: %s doesn't exist
|
||||||
|
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||||
|
DoNotExistSignUp = the user does not exist, please sign up first
|
||||||
|
FirstNameBlankErr = FirstName cannot be blank
|
||||||
|
FailToImportUsers = Failed to import users
|
||||||
|
LastNameBlankErr = LastName cannot be blank
|
||||||
|
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||||
|
NameStartWithADigitErr = Username cannot start with a digit
|
||||||
|
NameIsEmailErr = Username cannot be an email address
|
||||||
|
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||||
|
NameExistedErr = Username already exists
|
||||||
|
NameEmptyErr = Empty username.
|
||||||
|
NameTooLang = Username is too long (maximum is 39 characters).
|
||||||
|
NameFormatErr = 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.
|
||||||
|
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||||
|
InvalidInformation = Invalid information
|
||||||
|
|
137
i18n/languages/locale_zh.ini
Normal file
137
i18n/languages/locale_zh.ini
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
[ApplicationErr]
|
||||||
|
AppNotFound = 应用 %%s 未找到
|
||||||
|
AppNotFoundForUserID = 找不到该用户的应用程序 %s
|
||||||
|
GrantTypeNotSupport = 此应用中不支持此授权类型
|
||||||
|
HasNoProviders = 该应用无提供商
|
||||||
|
HasNoProvidersOfType = 应用没有该类型的提供商
|
||||||
|
InvalidID = 无效的Application ID
|
||||||
|
|
||||||
|
[AuthErr]
|
||||||
|
AuthStateWrong = 期望状态位: %s, 实际状态为: %s
|
||||||
|
ChallengeMethodErr = Challenge 方法应该为 S256
|
||||||
|
CanNotUnlinkUsers = 您不是全局管理员,无法取消链接其他用户
|
||||||
|
CanNotLinkMySelf = 您无法取消链接,您不是任何应用程序的成员
|
||||||
|
CallWebAuthnSigninBegin = 请先调用WebAuthnSigninBegin
|
||||||
|
NotHuman = 真人验证失败
|
||||||
|
Unauthorized = 未授权的操作
|
||||||
|
WrongPasswordManyTimes = 输入密码错误次数已达上限,请在 %d 分 %d 秒后重试
|
||||||
|
|
||||||
|
[CasErr]
|
||||||
|
ServiceDoNotMatch = 服务 %s 与 %s 不匹配
|
||||||
|
|
||||||
|
[EmailErr]
|
||||||
|
ExistedErr = 该邮箱已存在
|
||||||
|
EmptyErr = 邮箱不可为空
|
||||||
|
EmailInvalid = 无效邮箱
|
||||||
|
EmailCheckResult = Email: %s
|
||||||
|
EmptyParam = 邮件参数为空: %v
|
||||||
|
InvalidReceivers = 无效的邮箱接收者: %%s
|
||||||
|
UnableGetModifyRule = 无法得到Email修改规则
|
||||||
|
|
||||||
|
[EnforcerErr]
|
||||||
|
SignInFirst = 请先登录
|
||||||
|
|
||||||
|
[InitErr]
|
||||||
|
InitScoreFailed = 初始化分数失败: %w
|
||||||
|
|
||||||
|
[LdapErr]
|
||||||
|
MultipleAccounts = 多个帐户具有相同的uid,请检查您的 ldap 服务器
|
||||||
|
PasswordWrong = Ldap密码错误
|
||||||
|
ServerExisted = Ldap服务器已存在
|
||||||
|
|
||||||
|
[LoginErr]
|
||||||
|
AppDoNotExist = 应用不存在: %s
|
||||||
|
AppNotEnableSignUp = 提供商账户: %s 与用户名: %s (%s) 不存在且 不允许注册新账户, 请联系IT支持
|
||||||
|
AccountDoNotExist = 账户不存在
|
||||||
|
InvalidUserInformation = 创建用户失败,用户信息无效: %%s
|
||||||
|
LoginFirst = 请先登录
|
||||||
|
LoginFail = 无法登录: %s
|
||||||
|
NoPermission = 您没有权限执行此操作
|
||||||
|
OldUser = 提供商账户: %s 与用户名: %s (%s) 已经与其他账户绑定: %s (%s)
|
||||||
|
ProviderCanNotSignUp = 提供商账户: %s 与用户名: %s (%s) 不存在且 不允许通过 %s 注册新账户, 请使用其他方式注册
|
||||||
|
SignOutFirst = 请在登录前登出
|
||||||
|
SessionOutdated = Session已过期,请重新登陆
|
||||||
|
UserDoNotExist = 用户不存在: %s/%s
|
||||||
|
UserIsForbidden = 该用户被禁止登陆,请联系管理员
|
||||||
|
UnknownAuthentication = 未知的认证类型 (非密码或提供商认证), form = %s
|
||||||
|
UnsupportedPasswordType = 不支持此密码类型
|
||||||
|
|
||||||
|
[OrgErr]
|
||||||
|
DoNotExist = 组织不存在
|
||||||
|
Immutable = %s是不可变的
|
||||||
|
OnlyAdmin = 只有管理员用户有此权限
|
||||||
|
UnknownModifyRule = 未知的修改规则
|
||||||
|
|
||||||
|
[ParameterErr]
|
||||||
|
Missing = 参数丢失
|
||||||
|
OrgMissingErr = Organization参数丢失
|
||||||
|
UnknownType = 未知类型
|
||||||
|
Wrong = 参数错误
|
||||||
|
|
||||||
|
[PhoneErr]
|
||||||
|
CodeNotSent = 验证码还未发送
|
||||||
|
CodeTimeOut = 验证码过期
|
||||||
|
ExistedErr = 该电话已存在
|
||||||
|
EmptyErr = 电话不可为空
|
||||||
|
InvalidReceivers = 无效的电话接收者: %s
|
||||||
|
NumberInvalid = 无效电话
|
||||||
|
PhoneCheckResult = 电话: %s
|
||||||
|
UnableGetModifyRule = 无法得到电话修改规则
|
||||||
|
NoPrefix = %s 无此电话前缀
|
||||||
|
|
||||||
|
[ProviderErr]
|
||||||
|
CanNotBeUnlinked = 该提供商不可被链接
|
||||||
|
InvalidProvider = 无效的验证码提供商
|
||||||
|
LinkFirstErr = 请先绑定
|
||||||
|
ProviderNotEnabled = 提供商: %s 未被启用
|
||||||
|
ProviderNotSupported = 不支持该类型的提供商: %s
|
||||||
|
ProviderNotFound = 该提供商未找到: %s
|
||||||
|
ProviderNotFoundForCategory = 该类型的提供商: %s 在应用中未找到: %s
|
||||||
|
DoNotExist = 提供商: %s 不存在
|
||||||
|
CategoryNotSAML = 提供商 %s类型不是SAML
|
||||||
|
|
||||||
|
[ResourceErr]
|
||||||
|
NotAuthorized = 您无权获取此资源
|
||||||
|
UserIsNil = 用户头像标签为空
|
||||||
|
UsernameOrFilePathEmpty = username或FilePath为空: username = %s, fullFilePath = %s
|
||||||
|
|
||||||
|
[SetPasswordErr]
|
||||||
|
CanNotContainBlank = 新密码不可以包含空客
|
||||||
|
LessThanSixCharacters = 新密码至少为6位
|
||||||
|
|
||||||
|
[SignUpErr]
|
||||||
|
DoNotAllowSignUp = 该应用不允许注册新账户
|
||||||
|
SignOutFirst = 请在登陆前登出
|
||||||
|
|
||||||
|
[TokenErr]
|
||||||
|
EmptyClientID = clientId或clientSecret为空
|
||||||
|
InvalidAppOrWrongClientSecret = 无效应用或错误的clientSecret
|
||||||
|
InvalidToken = 无效token
|
||||||
|
InvalidClientId = 无效的ClientId
|
||||||
|
RedirectURIDoNotExist = 重定向 URI:%s 在可列表中未找到
|
||||||
|
|
||||||
|
[UserErr]
|
||||||
|
AffiliationBlankErr = 联系方式不可为空
|
||||||
|
DisplayNameBlankErr = 展示名称不可为空
|
||||||
|
DisplayNameInvalid = 展示名称无效
|
||||||
|
DisplayNameCanNotBeEmpty = 展示名称不可为空
|
||||||
|
DoNotExist = 用户不存在: %s
|
||||||
|
DoNotExistInOrg = 用户不存在: %s/%s
|
||||||
|
FirstNameBlankErr = 名不可以为空
|
||||||
|
FailToImportUsers = 导入用户失败
|
||||||
|
LastNameBlankErr = 姓不可以为空
|
||||||
|
NameLessThanTwoCharacters = 用户名至少要有2个字符
|
||||||
|
NameStartWithADigitErr = 用户名禁止使用数字作为第一个字符
|
||||||
|
NameIsEmailErr = 用户名不可以是邮箱地址
|
||||||
|
NameCantainWhitSpaceErr = 用户名不可以包含空格
|
||||||
|
NameExistedErr = 用户名已存在
|
||||||
|
NameEmptyErr = 用户名不可为空
|
||||||
|
NameTooLang = 用户名过长(最大长度为39个字符)
|
||||||
|
NameFormatErr = 用户名只能包含字母数字字符、下划线或连字符,不能有连续的连字符或下划线,也不能以连字符或下划线开头或结尾
|
||||||
|
PasswordLessThanSixCharacters = 密码至少为6字符
|
||||||
|
DoNotExistSignUp = 用户不存在,请先注册
|
||||||
|
InvalidInformation = 无效信息
|
||||||
|
|
||||||
|
[StorageErr]
|
||||||
|
ObjectKeyNotAllowed = object key :%s 不被允许
|
||||||
|
|
28
i18n/util.go
28
i18n/util.go
@ -15,10 +15,21 @@
|
|||||||
package i18n
|
package i18n
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
"gopkg.in/ini.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed languages/*.ini
|
||||||
|
var f embed.FS
|
||||||
|
|
||||||
|
var (
|
||||||
|
langMapConfig = make(map[string]*ini.File)
|
||||||
|
isNotFirstLoad = make(map[string]bool)
|
||||||
)
|
)
|
||||||
|
|
||||||
func getI18nFilePath(language string) string {
|
func getI18nFilePath(language string) string {
|
||||||
@ -62,3 +73,20 @@ func applyData(data1 *I18nData, data2 *I18nData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Translate(lang string, error string) string {
|
||||||
|
parts := strings.Split(error, ".")
|
||||||
|
if !strings.Contains(error, ".") || len(parts) != 2 {
|
||||||
|
log.Println("Invalid Error Name")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if isNotFirstLoad[lang] {
|
||||||
|
return langMapConfig[lang].Section(parts[0]).Key(parts[1]).String()
|
||||||
|
} else {
|
||||||
|
file, _ := f.ReadFile("languages/locale_" + lang + ".ini")
|
||||||
|
langMapConfig[lang], _ = ini.Load(file)
|
||||||
|
isNotFirstLoad[lang] = true
|
||||||
|
return langMapConfig[lang].Section(parts[0]).Key(parts[1]).String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,9 +15,12 @@
|
|||||||
package idp
|
package idp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -167,7 +170,10 @@ func (idp *DingTalkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
|||||||
Email: dtUserInfo.Email,
|
Email: dtUserInfo.Email,
|
||||||
AvatarUrl: dtUserInfo.AvatarUrl,
|
AvatarUrl: dtUserInfo.AvatarUrl,
|
||||||
}
|
}
|
||||||
|
isUserInOrg, err := idp.isUserInOrg(userInfo.UnionId)
|
||||||
|
if !isUserInOrg {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &userInfo, nil
|
return &userInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,3 +200,62 @@ func (idp *DingTalkIdProvider) postWithBody(body interface{}, url string) ([]byt
|
|||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (idp *DingTalkIdProvider) getInnerAppAccessToken() string {
|
||||||
|
appKey := idp.Config.ClientID
|
||||||
|
appSecret := idp.Config.ClientSecret
|
||||||
|
body := make(map[string]string)
|
||||||
|
body["appKey"] = appKey
|
||||||
|
body["appSecret"] = appSecret
|
||||||
|
bodyData, err := json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
reader := bytes.NewReader(bodyData)
|
||||||
|
request, err := http.NewRequest("POST", "https://api.dingtalk.com/v1.0/oauth2/accessToken", reader)
|
||||||
|
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
|
||||||
|
resp, err := idp.Client.Do(request)
|
||||||
|
respBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
var data struct {
|
||||||
|
ExpireIn int `json:"expireIn"`
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(respBytes, &data)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
return data.AccessToken
|
||||||
|
}
|
||||||
|
|
||||||
|
func (idp *DingTalkIdProvider) isUserInOrg(unionId string) (bool, error) {
|
||||||
|
body := make(map[string]string)
|
||||||
|
body["unionid"] = unionId
|
||||||
|
bodyData, err := json.Marshal(body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
reader := bytes.NewReader(bodyData)
|
||||||
|
accessToken := idp.getInnerAppAccessToken()
|
||||||
|
request, _ := http.NewRequest("POST", "https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token="+accessToken, reader)
|
||||||
|
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
|
||||||
|
resp, err := idp.Client.Do(request)
|
||||||
|
respBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
var data struct {
|
||||||
|
ErrCode int `json:"errcode"`
|
||||||
|
ErrMessage string `json:"errmsg"`
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(respBytes, &data)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
if data.ErrCode == 60121 {
|
||||||
|
return false, fmt.Errorf("the user is not found in the organization where clientId and clientSecret belong")
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
@ -70,6 +70,7 @@ type Application struct {
|
|||||||
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
|
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
|
||||||
FormCss string `xorm:"text" json:"formCss"`
|
FormCss string `xorm:"text" json:"formCss"`
|
||||||
FormOffset int `json:"formOffset"`
|
FormOffset int `json:"formOffset"`
|
||||||
|
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
|
||||||
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
|
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +270,13 @@ func UpdateApplication(id string, application *Application) bool {
|
|||||||
application.Name = name
|
application.Name = name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != application.Name {
|
||||||
|
err := applicationChangeTrigger(name, application.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, providerItem := range application.Providers {
|
for _, providerItem := range application.Providers {
|
||||||
providerItem.Provider = nil
|
providerItem.Provider = nil
|
||||||
}
|
}
|
||||||
@ -399,3 +407,55 @@ func ExtendManagedAccountsWithUser(user *User) *User {
|
|||||||
|
|
||||||
return user
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applicationChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
organization := new(Organization)
|
||||||
|
organization.DefaultApplication = newName
|
||||||
|
_, err = session.Where("default_application=?", oldName).Update(organization)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
user := new(User)
|
||||||
|
user.SignupApplication = newName
|
||||||
|
_, err = session.Where("signup_application=?", oldName).Update(user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resource := new(Resource)
|
||||||
|
resource.Application = newName
|
||||||
|
_, err = session.Where("application=?", oldName).Update(resource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var permissions []*Permission
|
||||||
|
err = adapter.Engine.Find(&permissions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i := 0; i < len(permissions); i++ {
|
||||||
|
permissionResoureces := permissions[i].Resources
|
||||||
|
for j := 0; j < len(permissionResoureces); j++ {
|
||||||
|
if permissionResoureces[j] == oldName {
|
||||||
|
permissionResoureces[j] = newName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
permissions[i].Resources = permissionResoureces
|
||||||
|
_, err = session.Where("name=?", permissions[i].Name).Update(permissions[i])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
@ -22,7 +22,6 @@ import (
|
|||||||
"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/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
|
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -114,6 +114,12 @@ func UpdateCert(id string, cert *Cert) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != cert.Name {
|
||||||
|
err := certChangeTrigger(name, cert.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(cert)
|
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -161,3 +167,22 @@ func getCertByApplication(application *Application) *Cert {
|
|||||||
func GetDefaultCert() *Cert {
|
func GetDefaultCert() *Cert {
|
||||||
return getCert("admin", "cert-built-in")
|
return getCert("admin", "cert-built-in")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func certChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
application := new(Application)
|
||||||
|
application.Cert = newName
|
||||||
|
_, err = session.Where("cert=?", oldName).Update(application)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
108
object/check.go
108
object/check.go
@ -22,6 +22,7 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/cred"
|
"github.com/casdoor/casdoor/cred"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
goldap "github.com/go-ldap/ldap/v3"
|
goldap "github.com/go-ldap/ldap/v3"
|
||||||
)
|
)
|
||||||
@ -41,89 +42,89 @@ func init() {
|
|||||||
reFieldWhiteList, _ = regexp.Compile(`^[A-Za-z0-9]+$`)
|
reFieldWhiteList, _ = regexp.Compile(`^[A-Za-z0-9]+$`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, firstName string, lastName string, email string, phone string, affiliation string) string {
|
func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, firstName string, lastName string, email string, phone string, affiliation string, lang string) string {
|
||||||
if organization == nil {
|
if organization == nil {
|
||||||
return "organization does not exist"
|
return i18n.Translate(lang, "OrgErr.DoNotExist")
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Username") {
|
if application.IsSignupItemVisible("Username") {
|
||||||
if len(username) <= 1 {
|
if len(username) <= 1 {
|
||||||
return "username must have at least 2 characters"
|
return i18n.Translate(lang, "UserErr.NameLessThanTwoCharacters")
|
||||||
}
|
}
|
||||||
if unicode.IsDigit(rune(username[0])) {
|
if unicode.IsDigit(rune(username[0])) {
|
||||||
return "username cannot start with a digit"
|
return i18n.Translate(lang, "UserErr.NameStartWithADigitErr")
|
||||||
}
|
}
|
||||||
if util.IsEmailValid(username) {
|
if util.IsEmailValid(username) {
|
||||||
return "username cannot be an email address"
|
return i18n.Translate(lang, "UserErr.NameIsEmailErr")
|
||||||
}
|
}
|
||||||
if reWhiteSpace.MatchString(username) {
|
if reWhiteSpace.MatchString(username) {
|
||||||
return "username cannot contain white spaces"
|
return i18n.Translate(lang, "UserErr.NameCantainWhitSpaceErr")
|
||||||
}
|
}
|
||||||
msg := CheckUsername(username)
|
msg := CheckUsername(username, lang)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
if HasUserByField(organization.Name, "name", username) {
|
if HasUserByField(organization.Name, "name", username) {
|
||||||
return "username already exists"
|
return i18n.Translate(lang, "UserErr.NameExistedErr")
|
||||||
}
|
}
|
||||||
if HasUserByField(organization.Name, "email", email) {
|
if HasUserByField(organization.Name, "email", email) {
|
||||||
return "email already exists"
|
return i18n.Translate(lang, "EmailErr.ExistedErr")
|
||||||
}
|
}
|
||||||
if HasUserByField(organization.Name, "phone", phone) {
|
if HasUserByField(organization.Name, "phone", phone) {
|
||||||
return "phone already exists"
|
return i18n.Translate(lang, "PhoneErr.ExistedErr")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(password) <= 5 {
|
if len(password) <= 5 {
|
||||||
return "password must have at least 6 characters"
|
return i18n.Translate(lang, "UserErr.PasswordLessThanSixCharacters")
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Email") {
|
if application.IsSignupItemVisible("Email") {
|
||||||
if email == "" {
|
if email == "" {
|
||||||
if application.IsSignupItemRequired("Email") {
|
if application.IsSignupItemRequired("Email") {
|
||||||
return "email cannot be empty"
|
return i18n.Translate(lang, "EmailErr.EmptyErr")
|
||||||
} else {
|
} else {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if HasUserByField(organization.Name, "email", email) {
|
if HasUserByField(organization.Name, "email", email) {
|
||||||
return "email already exists"
|
return i18n.Translate(lang, "EmailErr.ExistedErr")
|
||||||
} else if !util.IsEmailValid(email) {
|
} else if !util.IsEmailValid(email) {
|
||||||
return "email is invalid"
|
return i18n.Translate(lang, "EmailErr.EmailInvalid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Phone") {
|
if application.IsSignupItemVisible("Phone") {
|
||||||
if phone == "" {
|
if phone == "" {
|
||||||
if application.IsSignupItemRequired("Phone") {
|
if application.IsSignupItemRequired("Phone") {
|
||||||
return "phone cannot be empty"
|
return i18n.Translate(lang, "PhoneErr.EmptyErr")
|
||||||
} else {
|
} else {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if HasUserByField(organization.Name, "phone", phone) {
|
if HasUserByField(organization.Name, "phone", phone) {
|
||||||
return "phone already exists"
|
return i18n.Translate(lang, "PhoneErr.ExistedErr")
|
||||||
} else if organization.PhonePrefix == "86" && !util.IsPhoneCnValid(phone) {
|
} else if organization.PhonePrefix == "86" && !util.IsPhoneCnValid(phone) {
|
||||||
return "phone number is invalid"
|
return i18n.Translate(lang, "PhoneErr.NumberInvalid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Display name") {
|
if application.IsSignupItemVisible("Display name") {
|
||||||
if application.GetSignupItemRule("Display name") == "First, last" && (firstName != "" || lastName != "") {
|
if application.GetSignupItemRule("Display name") == "First, last" && (firstName != "" || lastName != "") {
|
||||||
if firstName == "" {
|
if firstName == "" {
|
||||||
return "firstName cannot be blank"
|
return i18n.Translate(lang, "UserErr.FirstNameBlankErr")
|
||||||
} else if lastName == "" {
|
} else if lastName == "" {
|
||||||
return "lastName cannot be blank"
|
return i18n.Translate(lang, "UserErr.LastNameBlankErr")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if displayName == "" {
|
if displayName == "" {
|
||||||
return "displayName cannot be blank"
|
return i18n.Translate(lang, "UserErr.DisplayNameBlankErr")
|
||||||
} else if application.GetSignupItemRule("Display name") == "Real name" {
|
} else if application.GetSignupItemRule("Display name") == "Real name" {
|
||||||
if !isValidRealName(displayName) {
|
if !isValidRealName(displayName) {
|
||||||
return "displayName is not valid real name"
|
return i18n.Translate(lang, "UserErr.DisplayNameInvalid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,14 +132,14 @@ func CheckUserSignup(application *Application, organization *Organization, usern
|
|||||||
|
|
||||||
if application.IsSignupItemVisible("Affiliation") {
|
if application.IsSignupItemVisible("Affiliation") {
|
||||||
if affiliation == "" {
|
if affiliation == "" {
|
||||||
return "affiliation cannot be blank"
|
return i18n.Translate(lang, "UserErr.AffiliationBlankErr")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkSigninErrorTimes(user *User) string {
|
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)
|
||||||
@ -146,7 +147,7 @@ func checkSigninErrorTimes(user *User) string {
|
|||||||
|
|
||||||
// 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 seconds > 0 {
|
||||||
return fmt.Sprintf("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, "AuthErr.WrongPasswordManyTimes"), seconds/60, seconds%60)
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the error times
|
// reset the error times
|
||||||
@ -158,15 +159,15 @@ func checkSigninErrorTimes(user *User) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckPassword(user *User, password string) string {
|
func CheckPassword(user *User, password string, lang string) string {
|
||||||
// check the login error times
|
// check the login error times
|
||||||
if msg := checkSigninErrorTimes(user); msg != "" {
|
if msg := checkSigninErrorTimes(user, lang); msg != "" {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
organization := GetOrganizationByUser(user)
|
organization := GetOrganizationByUser(user)
|
||||||
if organization == nil {
|
if organization == nil {
|
||||||
return "organization does not exist"
|
return i18n.Translate(lang, "OrgErr.DoNotExist")
|
||||||
}
|
}
|
||||||
|
|
||||||
credManager := cred.GetCredManager(organization.PasswordType)
|
credManager := cred.GetCredManager(organization.PasswordType)
|
||||||
@ -185,11 +186,11 @@ func CheckPassword(user *User, password string) string {
|
|||||||
|
|
||||||
return recordSigninErrorInfo(user)
|
return recordSigninErrorInfo(user)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Sprintf("unsupported password type: %s", organization.PasswordType)
|
return fmt.Sprintf(i18n.Translate(lang, "LoginErr.UnsupportedPasswordType"), organization.PasswordType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkLdapUserPassword(user *User, password string) (*User, string) {
|
func checkLdapUserPassword(user *User, password string, lang string) (*User, string) {
|
||||||
ldaps := GetLdaps(user.Owner)
|
ldaps := GetLdaps(user.Owner)
|
||||||
ldapLoginSuccess := false
|
ldapLoginSuccess := false
|
||||||
for _, ldapServer := range ldaps {
|
for _, ldapServer := range ldaps {
|
||||||
@ -209,7 +210,7 @@ func checkLdapUserPassword(user *User, password string) (*User, string) {
|
|||||||
if len(searchResult.Entries) == 0 {
|
if len(searchResult.Entries) == 0 {
|
||||||
continue
|
continue
|
||||||
} else if len(searchResult.Entries) > 1 {
|
} else if len(searchResult.Entries) > 1 {
|
||||||
return nil, "Error: multiple accounts with same uid, please check your ldap server"
|
return nil, i18n.Translate(lang, "LdapErr.MultipleAccounts")
|
||||||
}
|
}
|
||||||
|
|
||||||
dn := searchResult.Entries[0].DN
|
dn := searchResult.Entries[0].DN
|
||||||
@ -220,26 +221,26 @@ func checkLdapUserPassword(user *User, password string) (*User, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !ldapLoginSuccess {
|
if !ldapLoginSuccess {
|
||||||
return nil, "ldap user name or password incorrect"
|
return nil, i18n.Translate(lang, "LdapErr.PasswordWrong")
|
||||||
}
|
}
|
||||||
return user, ""
|
return user, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckUserPassword(organization string, username string, password 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, "the user does not exist, please sign up first"
|
return nil, i18n.Translate(lang, "UserErr.DoNotExistSignUp")
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.IsForbidden {
|
if user.IsForbidden {
|
||||||
return nil, "the user is forbidden to sign in, please contact the administrator"
|
return nil, i18n.Translate(lang, "LoginErr.UserIsForbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.Ldap != "" {
|
if user.Ldap != "" {
|
||||||
// ONLY for ldap users
|
// ONLY for ldap users
|
||||||
return checkLdapUserPassword(user, password)
|
return checkLdapUserPassword(user, password, lang)
|
||||||
} else {
|
} else {
|
||||||
msg := CheckPassword(user, password)
|
msg := CheckPassword(user, password, lang)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
return nil, msg
|
return nil, msg
|
||||||
}
|
}
|
||||||
@ -251,15 +252,15 @@ func filterField(field string) bool {
|
|||||||
return reFieldWhiteList.MatchString(field)
|
return reFieldWhiteList.MatchString(field)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckUserPermission(requestUserId, userId, userOwner string, strict bool) (bool, error) {
|
func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, lang string) (bool, error) {
|
||||||
if requestUserId == "" {
|
if requestUserId == "" {
|
||||||
return false, fmt.Errorf("please login first")
|
return false, fmt.Errorf(i18n.Translate(lang, "LoginErr.LoginFirst"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if userId != "" {
|
if userId != "" {
|
||||||
targetUser := GetUser(userId)
|
targetUser := GetUser(userId)
|
||||||
if targetUser == nil {
|
if targetUser == nil {
|
||||||
return false, fmt.Errorf("the user: %s doesn't exist", userId)
|
return false, fmt.Errorf(i18n.Translate(lang, "UserErr.DoNotExist"), userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
userOwner = targetUser.Owner
|
userOwner = targetUser.Owner
|
||||||
@ -271,7 +272,7 @@ func CheckUserPermission(requestUserId, userId, userOwner string, strict bool) (
|
|||||||
} else {
|
} else {
|
||||||
requestUser := GetUser(requestUserId)
|
requestUser := GetUser(requestUserId)
|
||||||
if requestUser == nil {
|
if requestUser == nil {
|
||||||
return false, fmt.Errorf("session outdated, please login again")
|
return false, fmt.Errorf(i18n.Translate(lang, "LoginErr.SessionOutdated"))
|
||||||
}
|
}
|
||||||
if requestUser.IsGlobalAdmin {
|
if requestUser.IsGlobalAdmin {
|
||||||
hasPermission = true
|
hasPermission = true
|
||||||
@ -286,7 +287,7 @@ func CheckUserPermission(requestUserId, userId, userOwner string, strict bool) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasPermission, fmt.Errorf("you don't have the permission to do this")
|
return hasPermission, fmt.Errorf(i18n.Translate(lang, "LoginErr.NoPermission"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAccessPermission(userId string, application *Application) (bool, error) {
|
func CheckAccessPermission(userId string, application *Application) (bool, error) {
|
||||||
@ -319,11 +320,11 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
|||||||
return allowed, err
|
return allowed, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckUsername(username string) string {
|
func CheckUsername(username string, lang string) string {
|
||||||
if username == "" {
|
if username == "" {
|
||||||
return "Empty username."
|
return i18n.Translate(lang, "UserErr.NameEmptyErr")
|
||||||
} else if len(username) > 39 {
|
} else if len(username) > 39 {
|
||||||
return "Username is too long (maximum is 39 characters)."
|
return i18n.Translate(lang, "UserErr.NameTooLang")
|
||||||
}
|
}
|
||||||
|
|
||||||
exclude, _ := regexp.Compile("^[\u0021-\u007E]+$")
|
exclude, _ := regexp.Compile("^[\u0021-\u007E]+$")
|
||||||
@ -334,8 +335,25 @@ func CheckUsername(username string) string {
|
|||||||
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex
|
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex
|
||||||
re, _ := regexp.Compile("^[a-zA-Z0-9]+((?:-[a-zA-Z0-9]+)|(?:_[a-zA-Z0-9]+))*$")
|
re, _ := regexp.Compile("^[a-zA-Z0-9]+((?:-[a-zA-Z0-9]+)|(?:_[a-zA-Z0-9]+))*$")
|
||||||
if !re.MatchString(username) {
|
if !re.MatchString(username) {
|
||||||
return "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."
|
return i18n.Translate(lang, "UserErr.NameFormatErr")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckToEnableCaptcha(application *Application) bool {
|
||||||
|
if len(application.Providers) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, providerItem := range application.Providers {
|
||||||
|
if providerItem.Provider == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if providerItem.Provider.Category == "Captcha" && providerItem.Provider.Type == "Default" {
|
||||||
|
return providerItem.Rule == "Always"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -143,7 +143,7 @@ func initBuiltInApplication() {
|
|||||||
EnablePassword: true,
|
EnablePassword: true,
|
||||||
EnableSignUp: true,
|
EnableSignUp: true,
|
||||||
Providers: []*ProviderItem{
|
Providers: []*ProviderItem{
|
||||||
{Name: "provider_captcha_default", CanSignUp: false, CanSignIn: false, CanUnlink: false, Prompted: false, AlertType: "None", Provider: nil},
|
{Name: "provider_captcha_default", CanSignUp: false, CanSignIn: false, CanUnlink: false, Prompted: false, AlertType: "None", Rule: "None", Provider: nil},
|
||||||
},
|
},
|
||||||
SignupItems: []*SignupItem{
|
SignupItems: []*SignupItem{
|
||||||
{Name: "ID", Visible: false, Required: true, Prompted: false, Rule: "Random"},
|
{Name: "ID", Visible: false, Required: true, Prompted: false, Rule: "Random"},
|
||||||
|
@ -56,12 +56,40 @@ func readInitDataFromFile(filePath string) *InitData {
|
|||||||
|
|
||||||
s := util.ReadStringFromPath(filePath)
|
s := util.ReadStringFromPath(filePath)
|
||||||
|
|
||||||
data := &InitData{}
|
data := &InitData{
|
||||||
|
Organizations: []*Organization{},
|
||||||
|
Applications: []*Application{},
|
||||||
|
Users: []*User{},
|
||||||
|
Certs: []*Cert{},
|
||||||
|
Providers: []*Provider{},
|
||||||
|
Ldaps: []*Ldap{},
|
||||||
|
}
|
||||||
err := util.JsonToStruct(s, data)
|
err := util.JsonToStruct(s, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// transform nil slice to empty slice
|
||||||
|
for _, organization := range data.Organizations {
|
||||||
|
if organization.Tags == nil {
|
||||||
|
organization.Tags = []string{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, application := range data.Applications {
|
||||||
|
if application.Providers == nil {
|
||||||
|
application.Providers = []*ProviderItem{}
|
||||||
|
}
|
||||||
|
if application.SignupItems == nil {
|
||||||
|
application.SignupItems = []*SignupItem{}
|
||||||
|
}
|
||||||
|
if application.GrantTypes == nil {
|
||||||
|
application.GrantTypes = []string{}
|
||||||
|
}
|
||||||
|
if application.RedirectUris == nil {
|
||||||
|
application.RedirectUris = []string{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ func GetFilteredUsers(m *ldapserver.Message, name, org string) ([]*User, int) {
|
|||||||
return nil, ldapserver.LDAPResultInsufficientAccessRights
|
return nil, ldapserver.LDAPResultInsufficientAccessRights
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hasPermission, err := CheckUserPermission(fmt.Sprintf("%s/%s", m.Client.OrgName, m.Client.UserName), fmt.Sprintf("%s/%s", org, name), org, true)
|
hasPermission, err := CheckUserPermission(fmt.Sprintf("%s/%s", m.Client.OrgName, m.Client.UserName), fmt.Sprintf("%s/%s", org, name), org, true, "en")
|
||||||
if !hasPermission {
|
if !hasPermission {
|
||||||
log.Printf("ErrMsg = %v", err.Error())
|
log.Printf("ErrMsg = %v", err.Error())
|
||||||
return nil, ldapserver.LDAPResultInsufficientAccessRights
|
return nil, ldapserver.LDAPResultInsufficientAccessRights
|
||||||
|
@ -92,6 +92,12 @@ func UpdateModel(id string, modelObj *Model) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != modelObj.Name {
|
||||||
|
err := modelChangeTrigger(name, modelObj.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
// check model grammar
|
// check model grammar
|
||||||
_, err := model.NewModelFromString(modelObj.ModelText)
|
_, err := model.NewModelFromString(modelObj.ModelText)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -127,3 +133,22 @@ func DeleteModel(model *Model) bool {
|
|||||||
func (model *Model) GetId() string {
|
func (model *Model) GetId() string {
|
||||||
return fmt.Sprintf("%s/%s", model.Owner, model.Name)
|
return fmt.Sprintf("%s/%s", model.Owner, model.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func modelChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
permission := new(Permission)
|
||||||
|
permission.Model = newName
|
||||||
|
_, err = session.Where("model=?", oldName).Update(permission)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
@ -16,8 +16,10 @@ package object
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/cred"
|
"github.com/casdoor/casdoor/cred"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
@ -133,15 +135,10 @@ func UpdateOrganization(id string, organization *Organization) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if name != organization.Name {
|
if name != organization.Name {
|
||||||
go func() {
|
err := organizationChangeTrigger(name, organization.Name)
|
||||||
application := new(Application)
|
if err != nil {
|
||||||
application.Organization = organization.Name
|
return false
|
||||||
_, _ = adapter.Engine.Where("organization=?", name).Update(application)
|
}
|
||||||
|
|
||||||
user := new(User)
|
|
||||||
user.Owner = organization.Name
|
|
||||||
_, _ = adapter.Engine.Where("owner=?", name).Update(user)
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if organization.MasterPassword != "" && organization.MasterPassword != "***" {
|
if organization.MasterPassword != "" && organization.MasterPassword != "***" {
|
||||||
@ -202,18 +199,18 @@ func GetAccountItemByName(name string, organization *Organization) *AccountItem
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAccountItemModifyRule(accountItem *AccountItem, user *User) (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.IsAdmin || user.IsGlobalAdmin) {
|
||||||
return false, fmt.Sprintf("Only admin can modify the %s.", accountItem.Name)
|
return false, fmt.Sprintf(i18n.Translate(lang, "OrgErr.OnlyAdmin"), accountItem.Name)
|
||||||
}
|
}
|
||||||
case "Immutable":
|
case "Immutable":
|
||||||
return false, fmt.Sprintf("The %s is immutable.", accountItem.Name)
|
return false, fmt.Sprintf(i18n.Translate(lang, "OrgErr.Immutable"), accountItem.Name)
|
||||||
case "Self":
|
case "Self":
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
return false, fmt.Sprintf("Unknown modify rule %s.", accountItem.ModifyRule)
|
return false, fmt.Sprintf(i18n.Translate(lang, "OrgErr.UnknownModifyRule"), accountItem.ModifyRule)
|
||||||
}
|
}
|
||||||
return true, ""
|
return true, ""
|
||||||
}
|
}
|
||||||
@ -251,3 +248,148 @@ func GetDefaultApplication(id string) (*Application, error) {
|
|||||||
|
|
||||||
return defaultApplication, nil
|
return defaultApplication, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func organizationChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
application := new(Application)
|
||||||
|
application.Organization = newName
|
||||||
|
_, err = session.Where("organization=?", oldName).Update(application)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
user := new(User)
|
||||||
|
user.Owner = newName
|
||||||
|
_, err = session.Where("owner=?", oldName).Update(user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
role := new(Role)
|
||||||
|
_, err = adapter.Engine.Where("owner=?", oldName).Get(role)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, u := range role.Users {
|
||||||
|
// u = organization/username
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[0] == oldName {
|
||||||
|
split[0] = newName
|
||||||
|
role.Users[i] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, u := range role.Roles {
|
||||||
|
// u = organization/username
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[0] == oldName {
|
||||||
|
split[0] = newName
|
||||||
|
role.Roles[i] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
role.Owner = newName
|
||||||
|
_, err = session.Where("owner=?", oldName).Update(role)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
permission := new(Permission)
|
||||||
|
_, err = adapter.Engine.Where("owner=?", oldName).Get(permission)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, u := range permission.Users {
|
||||||
|
// u = organization/username
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[0] == oldName {
|
||||||
|
split[0] = newName
|
||||||
|
permission.Users[i] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, u := range permission.Roles {
|
||||||
|
// u = organization/username
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[0] == oldName {
|
||||||
|
split[0] = newName
|
||||||
|
permission.Roles[i] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
permission.Owner = newName
|
||||||
|
_, err = session.Where("owner=?", oldName).Update(permission)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
casbinAdapter := new(CasbinAdapter)
|
||||||
|
casbinAdapter.Owner = newName
|
||||||
|
casbinAdapter.Organization = newName
|
||||||
|
_, err = session.Where("owner=?", oldName).Update(casbinAdapter)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ldap := new(Ldap)
|
||||||
|
ldap.Owner = newName
|
||||||
|
_, err = session.Where("owner=?", oldName).Update(ldap)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
model := new(Model)
|
||||||
|
model.Owner = newName
|
||||||
|
_, err = session.Where("owner=?", oldName).Update(model)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
payment := new(Payment)
|
||||||
|
payment.Organization = newName
|
||||||
|
_, err = session.Where("organization=?", oldName).Update(payment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
record := new(Record)
|
||||||
|
record.Owner = newName
|
||||||
|
record.Organization = newName
|
||||||
|
_, err = session.Where("organization=?", oldName).Update(record)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resource := new(Resource)
|
||||||
|
resource.Owner = newName
|
||||||
|
_, err = session.Where("owner=?", oldName).Update(resource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
syncer := new(Syncer)
|
||||||
|
syncer.Organization = newName
|
||||||
|
_, err = session.Where("organization=?", oldName).Update(syncer)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
token := new(Token)
|
||||||
|
token.Organization = newName
|
||||||
|
_, err = session.Where("organization=?", oldName).Update(token)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
webhook := new(Webhook)
|
||||||
|
webhook.Organization = newName
|
||||||
|
_, err = session.Where("organization=?", oldName).Update(webhook)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
@ -17,6 +17,7 @@ package object
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/pp"
|
"github.com/casdoor/casdoor/pp"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
@ -174,6 +175,13 @@ func UpdateProvider(id string, provider *Provider) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != provider.Name {
|
||||||
|
err := providerChangeTrigger(name, provider.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
||||||
if provider.ClientSecret == "***" {
|
if provider.ClientSecret == "***" {
|
||||||
session = session.Omit("client_secret")
|
session = session.Omit("client_secret")
|
||||||
@ -228,7 +236,7 @@ func (p *Provider) GetId() string {
|
|||||||
return fmt.Sprintf("%s/%s", p.Owner, p.Name)
|
return fmt.Sprintf("%s/%s", p.Owner, p.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCaptchaProviderByOwnerName(applicationId string) (*Provider, error) {
|
func GetCaptchaProviderByOwnerName(applicationId, lang string) (*Provider, error) {
|
||||||
owner, name := util.GetOwnerAndNameFromId(applicationId)
|
owner, name := util.GetOwnerAndNameFromId(applicationId)
|
||||||
provider := Provider{Owner: owner, Name: name, Category: "Captcha"}
|
provider := Provider{Owner: owner, Name: name, Category: "Captcha"}
|
||||||
existed, err := adapter.Engine.Get(&provider)
|
existed, err := adapter.Engine.Get(&provider)
|
||||||
@ -237,27 +245,65 @@ func GetCaptchaProviderByOwnerName(applicationId string) (*Provider, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !existed {
|
if !existed {
|
||||||
return nil, fmt.Errorf("the provider: %s does not exist", applicationId)
|
return nil, fmt.Errorf(i18n.Translate(lang, "ProviderErr.DoNotExist"), applicationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &provider, nil
|
return &provider, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCaptchaProviderByApplication(applicationId, isCurrentProvider string) (*Provider, error) {
|
func GetCaptchaProviderByApplication(applicationId, isCurrentProvider, lang string) (*Provider, error) {
|
||||||
if isCurrentProvider == "true" {
|
if isCurrentProvider == "true" {
|
||||||
return GetCaptchaProviderByOwnerName(applicationId)
|
return GetCaptchaProviderByOwnerName(applicationId, lang)
|
||||||
}
|
}
|
||||||
application := GetApplication(applicationId)
|
application := GetApplication(applicationId)
|
||||||
if application == nil || len(application.Providers) == 0 {
|
if application == nil || len(application.Providers) == 0 {
|
||||||
return nil, fmt.Errorf("invalid application id")
|
return nil, fmt.Errorf(i18n.Translate(lang, "ApplicationErr.InvalidID"))
|
||||||
}
|
}
|
||||||
for _, provider := range application.Providers {
|
for _, provider := range application.Providers {
|
||||||
if provider.Provider == nil {
|
if provider.Provider == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if provider.Provider.Category == "Captcha" {
|
if provider.Provider.Category == "Captcha" {
|
||||||
return GetCaptchaProviderByOwnerName(fmt.Sprintf("%s/%s", provider.Provider.Owner, provider.Provider.Name))
|
return GetCaptchaProviderByOwnerName(fmt.Sprintf("%s/%s", provider.Provider.Owner, provider.Provider.Name), lang)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func providerChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var applications []*Application
|
||||||
|
err = adapter.Engine.Find(&applications)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i := 0; i < len(applications); i++ {
|
||||||
|
providers := applications[i].Providers
|
||||||
|
for j := 0; j < len(providers); j++ {
|
||||||
|
if providers[j].Name == oldName {
|
||||||
|
providers[j].Name = newName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
applications[i].Providers = providers
|
||||||
|
_, err = session.Where("name=?", applications[i].Name).Update(applications[i])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource := new(Resource)
|
||||||
|
resource.Provider = newName
|
||||||
|
_, err = session.Where("provider=?", oldName).Update(resource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ type ProviderItem struct {
|
|||||||
CanUnlink bool `json:"canUnlink"`
|
CanUnlink bool `json:"canUnlink"`
|
||||||
Prompted bool `json:"prompted"`
|
Prompted bool `json:"prompted"`
|
||||||
AlertType string `json:"alertType"`
|
AlertType string `json:"alertType"`
|
||||||
|
Rule string `json:"rule"`
|
||||||
Provider *Provider `json:"provider"`
|
Provider *Provider `json:"provider"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ package object
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
@ -94,6 +95,13 @@ func UpdateRole(id string, role *Role) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != role.Name {
|
||||||
|
err := roleChangeTrigger(name, role.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(role)
|
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(role)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -133,3 +141,54 @@ func GetRolesByUser(userId string) []*Role {
|
|||||||
|
|
||||||
return roles
|
return roles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func roleChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var roles []*Role
|
||||||
|
err = adapter.Engine.Find(&roles)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, role := range roles {
|
||||||
|
for j, u := range role.Roles {
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[1] == oldName {
|
||||||
|
split[1] = newName
|
||||||
|
role.Roles[j] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = session.Where("name=?", role.Name).Update(role)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var permissions []*Permission
|
||||||
|
err = adapter.Engine.Find(&permissions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, permission := range permissions {
|
||||||
|
for j, u := range permission.Roles {
|
||||||
|
// u = organization/username
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[1] == oldName {
|
||||||
|
split[1] = newName
|
||||||
|
permission.Roles[j] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = session.Where("name=?", permission.Name).Update(permission)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
saml2 "github.com/russellhaering/gosaml2"
|
saml2 "github.com/russellhaering/gosaml2"
|
||||||
dsig "github.com/russellhaering/goxmldsig"
|
dsig "github.com/russellhaering/goxmldsig"
|
||||||
)
|
)
|
||||||
@ -41,10 +42,10 @@ func ParseSamlResponse(samlResponse string, providerType string) (string, error)
|
|||||||
return assertionInfo.NameID, nil
|
return assertionInfo.NameID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateSamlLoginUrl(id, relayState string) (string, string, error) {
|
func GenerateSamlLoginUrl(id, relayState, lang string) (string, string, error) {
|
||||||
provider := GetProvider(id)
|
provider := GetProvider(id)
|
||||||
if provider.Category != "SAML" {
|
if provider.Category != "SAML" {
|
||||||
return "", "", fmt.Errorf("provider %s's category is not SAML", provider.Name)
|
return "", "", fmt.Errorf(i18n.Translate(lang, "ProviderErr.CategoryNotSAML"), provider.Name)
|
||||||
}
|
}
|
||||||
sp, err := buildSp(provider, "")
|
sp, err := buildSp(provider, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/storage"
|
"github.com/casdoor/casdoor/storage"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
)
|
)
|
||||||
@ -126,16 +127,16 @@ func UploadFileSafe(provider *Provider, fullFilePath string, fileBuffer *bytes.B
|
|||||||
return fileUrl, objectKey, nil
|
return fileUrl, objectKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteFile(provider *Provider, objectKey string) error {
|
func DeleteFile(provider *Provider, objectKey string, lang string) error {
|
||||||
// check fullFilePath is there security issue
|
// check fullFilePath is there security issue
|
||||||
if strings.Contains(objectKey, "..") {
|
if strings.Contains(objectKey, "..") {
|
||||||
return fmt.Errorf("the objectKey: %s is not allowed", objectKey)
|
return fmt.Errorf(i18n.Translate(lang, "StorageErr.ObjectKeyNotAllowed"), objectKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoint := getProviderEndpoint(provider)
|
endpoint := getProviderEndpoint(provider)
|
||||||
storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
|
storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
|
||||||
if storageProvider == nil {
|
if storageProvider == nil {
|
||||||
return fmt.Errorf("the provider type: %s is not supported", provider.Type)
|
return fmt.Errorf(i18n.Translate(lang, "ProviderErr.ProviderNotSupported"), provider.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
if provider.Domain == "" {
|
if provider.Domain == "" {
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/idp"
|
"github.com/casdoor/casdoor/idp"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
@ -238,14 +239,14 @@ func GetTokenByTokenAndApplication(token string, application string) *Token {
|
|||||||
return &tokenResult
|
return &tokenResult
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckOAuthLogin(clientId string, responseType string, redirectUri string, scope string, state string) (string, *Application) {
|
func CheckOAuthLogin(clientId string, responseType string, redirectUri string, scope string, state string, lang string) (string, *Application) {
|
||||||
if responseType != "code" && responseType != "token" && responseType != "id_token" {
|
if responseType != "code" && responseType != "token" && responseType != "id_token" {
|
||||||
return fmt.Sprintf("error: grant_type: %s is not supported in this application", responseType), nil
|
return fmt.Sprintf(i18n.Translate(lang, "ApplicationErr.GrantTypeNotSupport"), responseType), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
application := GetApplicationByClientId(clientId)
|
application := GetApplicationByClientId(clientId)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
return "Invalid client_id", nil
|
return i18n.Translate(lang, "TokenErr.InvalidClientId"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
validUri := false
|
validUri := false
|
||||||
@ -256,7 +257,7 @@ func CheckOAuthLogin(clientId string, responseType string, redirectUri string, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !validUri {
|
if !validUri {
|
||||||
return fmt.Sprintf("Redirect URI: \"%s\" doesn't exist in the allowed Redirect URI list", redirectUri), application
|
return fmt.Sprintf(i18n.Translate(lang, "TokenErr.RedirectURIDoNotExist"), redirectUri), application
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mask application for /api/get-app-login
|
// Mask application for /api/get-app-login
|
||||||
@ -264,7 +265,7 @@ func CheckOAuthLogin(clientId string, responseType string, redirectUri string, s
|
|||||||
return "", application
|
return "", application
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOAuthCode(userId string, clientId string, responseType string, redirectUri string, scope string, state string, nonce string, challenge string, host string) *Code {
|
func GetOAuthCode(userId string, clientId string, responseType string, redirectUri string, scope string, state string, nonce string, challenge string, host string, lang string) *Code {
|
||||||
user := GetUser(userId)
|
user := GetUser(userId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return &Code{
|
return &Code{
|
||||||
@ -279,7 +280,7 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, application := CheckOAuthLogin(clientId, responseType, redirectUri, scope, state)
|
msg, application := CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, lang)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
return &Code{
|
return &Code{
|
||||||
Message: msg,
|
Message: msg,
|
||||||
@ -322,7 +323,7 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOAuthToken(grantType string, clientId string, clientSecret string, code string, verifier string, scope string, username string, password string, host string, tag string, avatar string) interface{} {
|
func GetOAuthToken(grantType string, clientId string, clientSecret string, code string, verifier string, scope string, username string, password string, host string, tag string, avatar string, lang string) interface{} {
|
||||||
application := GetApplicationByClientId(clientId)
|
application := GetApplicationByClientId(clientId)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
return &TokenError{
|
return &TokenError{
|
||||||
@ -353,7 +354,7 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
|||||||
|
|
||||||
if tag == "wechat_miniprogram" {
|
if tag == "wechat_miniprogram" {
|
||||||
// Wechat Mini Program
|
// Wechat Mini Program
|
||||||
token, tokenError = GetWechatMiniProgramToken(application, code, host, username, avatar)
|
token, tokenError = GetWechatMiniProgramToken(application, code, host, username, avatar, lang)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tokenError != nil {
|
if tokenError != nil {
|
||||||
@ -559,7 +560,7 @@ func GetPasswordToken(application *Application, username string, password string
|
|||||||
ErrorDescription: "the user does not exist",
|
ErrorDescription: "the user does not exist",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg := CheckPassword(user, password)
|
msg := CheckPassword(user, password, "en")
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
return nil, &TokenError{
|
return nil, &TokenError{
|
||||||
Error: InvalidGrant,
|
Error: InvalidGrant,
|
||||||
@ -669,7 +670,7 @@ func GetTokenByUser(application *Application, user *User, scope string, host str
|
|||||||
|
|
||||||
// GetWechatMiniProgramToken
|
// GetWechatMiniProgramToken
|
||||||
// Wechat Mini Program flow
|
// Wechat Mini Program flow
|
||||||
func GetWechatMiniProgramToken(application *Application, code string, host string, username string, avatar string) (*Token, *TokenError) {
|
func GetWechatMiniProgramToken(application *Application, code string, host string, username string, avatar string, lang string) (*Token, *TokenError) {
|
||||||
mpProvider := GetWechatMiniProgramProvider(application)
|
mpProvider := GetWechatMiniProgramProvider(application)
|
||||||
if mpProvider == nil {
|
if mpProvider == nil {
|
||||||
return nil, &TokenError{
|
return nil, &TokenError{
|
||||||
@ -703,7 +704,7 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
|
|||||||
}
|
}
|
||||||
// Add new user
|
// Add new user
|
||||||
var name string
|
var name string
|
||||||
if CheckUsername(username) == "" {
|
if CheckUsername(username, lang) == "" {
|
||||||
name = username
|
name = username
|
||||||
} else {
|
} else {
|
||||||
name = fmt.Sprintf("wechat-%s", openId)
|
name = fmt.Sprintf("wechat-%s", openId)
|
||||||
|
@ -37,7 +37,7 @@ func generateRsaKeys(bitSize int, expireInYears int, commonName string, organiza
|
|||||||
// Encode private key to PKCS#1 ASN.1 PEM.
|
// Encode private key to PKCS#1 ASN.1 PEM.
|
||||||
privateKeyPem := pem.EncodeToMemory(
|
privateKeyPem := pem.EncodeToMemory(
|
||||||
&pem.Block{
|
&pem.Block{
|
||||||
Type: "PRIVATE KEY",
|
Type: "RSA PRIVATE KEY",
|
||||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -380,6 +380,13 @@ func UpdateUser(id string, user *User, columns []string, isGlobalAdmin bool) boo
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != user.Name {
|
||||||
|
err := userChangeTrigger(name, user.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if user.Password == "***" {
|
if user.Password == "***" {
|
||||||
user.Password = oldUser.Password
|
user.Password = oldUser.Password
|
||||||
}
|
}
|
||||||
@ -416,6 +423,13 @@ func UpdateUserForAllFields(id string, user *User) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != user.Name {
|
||||||
|
err := userChangeTrigger(name, user.Name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
user.UpdateUserHash()
|
user.UpdateUserHash()
|
||||||
|
|
||||||
if user.Avatar != oldUser.Avatar && user.Avatar != "" {
|
if user.Avatar != oldUser.Avatar && user.Avatar != "" {
|
||||||
@ -567,3 +581,62 @@ func ExtendUserWithRolesAndPermissions(user *User) {
|
|||||||
user.Roles = GetRolesByUser(user.GetId())
|
user.Roles = GetRolesByUser(user.GetId())
|
||||||
user.Permissions = GetPermissionsByUser(user.GetId())
|
user.Permissions = GetPermissionsByUser(user.GetId())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func userChangeTrigger(oldName string, newName string) error {
|
||||||
|
session := adapter.Engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
err := session.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var roles []*Role
|
||||||
|
err = adapter.Engine.Find(&roles)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, role := range roles {
|
||||||
|
for j, u := range role.Users {
|
||||||
|
// u = organization/username
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[1] == oldName {
|
||||||
|
split[1] = newName
|
||||||
|
role.Users[j] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = session.Where("name=?", role.Name).Update(role)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var permissions []*Permission
|
||||||
|
err = adapter.Engine.Find(&permissions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, permission := range permissions {
|
||||||
|
for j, u := range permission.Users {
|
||||||
|
// u = organization/username
|
||||||
|
split := strings.Split(u, "/")
|
||||||
|
if split[1] == oldName {
|
||||||
|
split[1] = newName
|
||||||
|
permission.Users[j] = split[0] + "/" + split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = session.Where("name=?", permission.Name).Update(permission)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource := new(Resource)
|
||||||
|
resource.User = newName
|
||||||
|
_, err = session.Where("user=?", oldName).Update(resource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.Commit()
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
@ -122,11 +123,11 @@ func getVerificationRecord(dest string) *VerificationRecord {
|
|||||||
return &record
|
return &record
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckVerificationCode(dest, code string) string {
|
func CheckVerificationCode(dest, code, lang string) string {
|
||||||
record := getVerificationRecord(dest)
|
record := getVerificationRecord(dest)
|
||||||
|
|
||||||
if record == nil {
|
if record == nil {
|
||||||
return "Code has not been sent yet!"
|
return i18n.Translate(lang, "PhoneErr.CodeNotSent")
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout, err := conf.GetConfigInt64("verificationCodeTimeout")
|
timeout, err := conf.GetConfigInt64("verificationCodeTimeout")
|
||||||
@ -136,7 +137,7 @@ func CheckVerificationCode(dest, code string) string {
|
|||||||
|
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
if now-record.Time > timeout*60 {
|
if now-record.Time > timeout*60 {
|
||||||
return fmt.Sprintf("You should verify your code in %d min!", timeout)
|
return fmt.Sprintf(i18n.Translate(lang, "PhoneErr.CodeTimeOut"), timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
if record.Code != code {
|
if record.Code != code {
|
||||||
|
@ -62,7 +62,7 @@ func AutoSigninFilter(ctx *context.Context) {
|
|||||||
password := ctx.Input.Query("password")
|
password := ctx.Input.Query("password")
|
||||||
if userId != "" && password != "" && ctx.Input.Query("grant_type") == "" {
|
if userId != "" && password != "" && ctx.Input.Query("grant_type") == "" {
|
||||||
owner, name := util.GetOwnerAndNameFromId(userId)
|
owner, name := util.GetOwnerAndNameFromId(userId)
|
||||||
_, msg := object.CheckUserPassword(owner, name, password)
|
_, msg := object.CheckUserPassword(owner, name, password, "en")
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
responseError(ctx, msg)
|
responseError(ctx, msg)
|
||||||
return
|
return
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
"eslint-plugin-react": "^7.31.1",
|
"eslint-plugin-react": "^7.31.1",
|
||||||
"husky": "^4.3.8",
|
"husky": "^4.3.8",
|
||||||
"lint-staged": "^13.0.3",
|
"lint-staged": "^13.0.3",
|
||||||
|
"path-browserify": "^1.0.1",
|
||||||
"stylelint": "^14.11.0",
|
"stylelint": "^14.11.0",
|
||||||
"stylelint-config-recommended-less": "^1.0.4",
|
"stylelint-config-recommended-less": "^1.0.4",
|
||||||
"stylelint-config-standard": "^28.0.0"
|
"stylelint-config-standard": "^28.0.0"
|
||||||
|
@ -221,10 +221,9 @@ class App extends Component {
|
|||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
account = res.data;
|
account = res.data;
|
||||||
account.organization = res.data2;
|
account.organization = res.data2;
|
||||||
|
|
||||||
this.setLanguage(account);
|
this.setLanguage(account);
|
||||||
} else {
|
} else {
|
||||||
if (res.msg !== "Please sign in first") {
|
if (res.data !== "Please login first") {
|
||||||
Setting.showMessage("error", `Failed to sign in: ${res.msg}`);
|
Setting.showMessage("error", `Failed to sign in: ${res.msg}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,38 @@
|
|||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.side-image {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
@media screen and (min-width: 1100px) {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 500px;
|
||||||
|
border-right: 0.5px solid rgb(196 203 215);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.forget-content {
|
||||||
|
padding: 10px 100px 20px;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 7px;
|
||||||
|
background-color: rgb(255 255 255);
|
||||||
|
box-shadow: 0 0 20px rgb(0 0 0 / 20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-panel {
|
||||||
|
margin-top: 50px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
display: flex;
|
||||||
|
background-color: rgb(255 255 255);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.login-content {
|
.login-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -105,7 +137,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.loginBackground {
|
.loginBackground {
|
||||||
height: 100%;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1 1 0;
|
||||||
background: #fff no-repeat;
|
background: #fff no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
|
@ -32,6 +32,7 @@ import copy from "copy-to-clipboard";
|
|||||||
|
|
||||||
import {Controlled as CodeMirror} from "react-codemirror2";
|
import {Controlled as CodeMirror} from "react-codemirror2";
|
||||||
import "codemirror/lib/codemirror.css";
|
import "codemirror/lib/codemirror.css";
|
||||||
|
|
||||||
require("codemirror/theme/material-darker.css");
|
require("codemirror/theme/material-darker.css");
|
||||||
require("codemirror/mode/htmlmixed/htmlmixed");
|
require("codemirror/mode/htmlmixed/htmlmixed");
|
||||||
require("codemirror/mode/xml/xml");
|
require("codemirror/mode/xml/xml");
|
||||||
@ -39,13 +40,51 @@ require("codemirror/mode/css/css");
|
|||||||
|
|
||||||
const {Option} = Select;
|
const {Option} = Select;
|
||||||
|
|
||||||
const template = {
|
const template = `<style>
|
||||||
padding: "30px",
|
.login-panel{
|
||||||
border: "2px solid #ffffff",
|
padding: 40px 70px 0 70px;
|
||||||
borderRadius: "7px",
|
border-radius: 10px;
|
||||||
backgroundColor: "#ffffff",
|
background-color: #ffffff;
|
||||||
boxShadow: " 0px 0px 20px rgba(0, 0, 0, 0.20)",
|
box-shadow: 0 0 30px 20px rgba(0, 0, 0, 0.20);
|
||||||
};
|
}
|
||||||
|
</style>`;
|
||||||
|
|
||||||
|
const sideTemplate = `<style>
|
||||||
|
.left-model{
|
||||||
|
text-align: center;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: #8ca0ed;
|
||||||
|
position: absolute;
|
||||||
|
transform: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.side-logo{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.side-logo span {
|
||||||
|
font-family: Montserrat, sans-serif;
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 2.4rem;
|
||||||
|
line-height: 1.3;
|
||||||
|
margin-left: 16px;
|
||||||
|
color: #404040;
|
||||||
|
}
|
||||||
|
.img{
|
||||||
|
max-width: none;
|
||||||
|
margin: 41px 0 13px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="left-model">
|
||||||
|
<span class="side-logo"> <img src="https://cdn.casbin.org/img/casdoor-logo_1185x256.png" alt="Casdoor" style="width: 120px">
|
||||||
|
<span>SSO</span>
|
||||||
|
</span>
|
||||||
|
<div class="img">
|
||||||
|
<img src="https://cdn.casbin.org/img/casbin.svg" alt="Casdoor"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
class ApplicationEditPage extends React.Component {
|
class ApplicationEditPage extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -157,7 +196,6 @@ class ApplicationEditPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderApplication() {
|
renderApplication() {
|
||||||
const preview = JSON.stringify(template, null, 2);
|
|
||||||
return (
|
return (
|
||||||
<Card size="small" title={
|
<Card size="small" title={
|
||||||
<div>
|
<div>
|
||||||
@ -562,10 +600,10 @@ class ApplicationEditPage extends React.Component {
|
|||||||
</Col>
|
</Col>
|
||||||
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
|
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
|
||||||
<Row style={{marginTop: "20px"}} >
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 1}>
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||||
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
|
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={23} >
|
<Col span={22} >
|
||||||
<Input prefix={<LinkOutlined />} value={this.state.application.formBackgroundUrl} onChange={e => {
|
<Input prefix={<LinkOutlined />} value={this.state.application.formBackgroundUrl} onChange={e => {
|
||||||
this.updateApplicationField("formBackgroundUrl", e.target.value);
|
this.updateApplicationField("formBackgroundUrl", e.target.value);
|
||||||
}} />
|
}} />
|
||||||
@ -590,7 +628,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
<Col span={22}>
|
<Col span={22}>
|
||||||
<Popover placement="right" content={
|
<Popover placement="right" content={
|
||||||
<div style={{width: "900px", height: "300px"}} >
|
<div style={{width: "900px", height: "300px"}} >
|
||||||
<CodeMirror value={this.state.application.formCss === "" ? preview : this.state.application.formCss}
|
<CodeMirror value={this.state.application.formCss === "" ? template : this.state.application.formCss}
|
||||||
options={{mode: "css", theme: "material-darker"}}
|
options={{mode: "css", theme: "material-darker"}}
|
||||||
onBeforeChange={(editor, data, value) => {
|
onBeforeChange={(editor, data, value) => {
|
||||||
this.updateApplicationField("formCss", value);
|
this.updateApplicationField("formCss", value);
|
||||||
@ -606,14 +644,42 @@ class ApplicationEditPage extends React.Component {
|
|||||||
</Row>
|
</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("application:From position"), i18next.t("application:From position - Tooltip"))} :
|
{Setting.getLabel(i18next.t("application:Form position"), i18next.t("application:Form position - Tooltip"))} :
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={22} >
|
<Col span={22} >
|
||||||
<Radio.Group onChange={e => {this.updateApplicationField("formOffset", e.target.value);}} value={this.state.application.formOffset !== 0 ? this.state.application.formOffset : 8}>
|
<Row style={{marginTop: "20px"}} >
|
||||||
<Radio.Button value={2}>left</Radio.Button>
|
<Radio.Group onChange={e => {this.updateApplicationField("formOffset", e.target.value);}} value={this.state.application.formOffset}>
|
||||||
<Radio.Button value={8}>center</Radio.Button>
|
<Radio.Button value={1}>{i18next.t("application:Left")}</Radio.Button>
|
||||||
<Radio.Button value={14}>right</Radio.Button>
|
<Radio.Button value={2}>{i18next.t("application:Center")}</Radio.Button>
|
||||||
</Radio.Group>
|
<Radio.Button value={3}>{i18next.t("application:Right")}</Radio.Button>
|
||||||
|
<Radio.Button value={4}>
|
||||||
|
{i18next.t("application:Enable side panel")}
|
||||||
|
</Radio.Button>
|
||||||
|
</Radio.Group>
|
||||||
|
</Row>
|
||||||
|
{this.state.application.formOffset === 4 ?
|
||||||
|
<Row style={{marginTop: "20px"}} >
|
||||||
|
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 3}>
|
||||||
|
{Setting.getLabel(i18next.t("application:Side panel HTML"), i18next.t("application:Side panel HTML - Tooltip"))} :
|
||||||
|
</Col>
|
||||||
|
<Col span={21} >
|
||||||
|
<Popover placement="right" content={
|
||||||
|
<div style={{width: "900px", height: "300px"}} >
|
||||||
|
<CodeMirror value={this.state.application.formSideHtml === "" ? sideTemplate : this.state.application.formSideHtml}
|
||||||
|
options={{mode: "htmlmixed", theme: "material-darker"}}
|
||||||
|
onBeforeChange={(editor, data, value) => {
|
||||||
|
this.updateApplicationField("formSideHtml", value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
} title={i18next.t("application:Side panel HTML - Edit")} trigger="click">
|
||||||
|
<Input value={this.state.application.formSideHtml} style={{marginBottom: "10px"}} onChange={e => {
|
||||||
|
this.updateApplicationField("formSideHtml", e.target.value);
|
||||||
|
}} />
|
||||||
|
</Popover>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
: null}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{
|
{
|
||||||
@ -707,7 +773,7 @@ class ApplicationEditPage extends React.Component {
|
|||||||
<br />
|
<br />
|
||||||
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", flexDirection: "column", flex: "auto"}}>
|
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", flexDirection: "column", flex: "auto"}}>
|
||||||
<PromptPage application={this.state.application} account={this.props.account} />
|
<PromptPage application={this.state.application} account={this.props.account} />
|
||||||
<div style={maskStyle}></div>
|
<div style={maskStyle} />
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
|
@ -39,7 +39,7 @@ class ProviderTable extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addRow(table) {
|
addRow(table) {
|
||||||
const row = {name: Setting.getNewRowNameForTable(table, "Please select a provider"), canSignUp: true, canSignIn: true, canUnlink: true, alertType: "None"};
|
const row = {name: Setting.getNewRowNameForTable(table, "Please select a provider"), canSignUp: true, canSignIn: true, canUnlink: true, alertType: "None", rule: "None"};
|
||||||
if (table === undefined) {
|
if (table === undefined) {
|
||||||
table = [];
|
table = [];
|
||||||
}
|
}
|
||||||
@ -193,6 +193,28 @@ class ProviderTable extends React.Component {
|
|||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
|
{
|
||||||
|
title: i18next.t("application:Rule"),
|
||||||
|
dataIndex: "rule",
|
||||||
|
key: "rule",
|
||||||
|
width: "100px",
|
||||||
|
render: (text, record, index) => {
|
||||||
|
if (record.provider?.category !== "Captcha") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Select virtual={false} style={{width: "100%"}}
|
||||||
|
value={text}
|
||||||
|
defaultValue="None"
|
||||||
|
onChange={value => {
|
||||||
|
this.updateField(table, index, "rule", value);
|
||||||
|
}} >
|
||||||
|
<Option key="None" value="None">{i18next.t("application:None")}</Option>
|
||||||
|
<Option key="Always" value="Always">{i18next.t("application:Always")}</Option>
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Action"),
|
title: i18next.t("general:Action"),
|
||||||
key: "action",
|
key: "action",
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import {Link, useHistory} from "react-router-dom";
|
||||||
import {Tag, Tooltip, message} from "antd";
|
import {Tag, Tooltip, message} from "antd";
|
||||||
import {QuestionCircleTwoTone} from "@ant-design/icons";
|
import {QuestionCircleTwoTone} from "@ant-design/icons";
|
||||||
import React from "react";
|
|
||||||
import {isMobile as isMobileDevice} from "react-device-detect";
|
import {isMobile as isMobileDevice} from "react-device-detect";
|
||||||
import "./i18n";
|
import "./i18n";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
@ -22,6 +23,7 @@ import copy from "copy-to-clipboard";
|
|||||||
import {authConfig} from "./auth/Auth";
|
import {authConfig} from "./auth/Auth";
|
||||||
import {Helmet} from "react-helmet";
|
import {Helmet} from "react-helmet";
|
||||||
import * as Conf from "./Conf";
|
import * as Conf from "./Conf";
|
||||||
|
import * as path from "path-browserify";
|
||||||
|
|
||||||
export const ServerUrl = "";
|
export const ServerUrl = "";
|
||||||
|
|
||||||
@ -557,6 +559,10 @@ export function changeLanguage(language) {
|
|||||||
// window.location.reload(true);
|
// window.location.reload(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAcceptLanguage() {
|
||||||
|
return i18next.language + ";q=0.9,en;q=0.8";
|
||||||
|
}
|
||||||
|
|
||||||
export function changeMomentLanguage(language) {
|
export function changeMomentLanguage(language) {
|
||||||
// if (language === "zh") {
|
// if (language === "zh") {
|
||||||
// moment.locale("zh", {
|
// moment.locale("zh", {
|
||||||
@ -737,64 +743,97 @@ export function renderLogo(application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goToLogin(ths, application) {
|
export function getLoginLink(application) {
|
||||||
|
let url;
|
||||||
if (application === null) {
|
if (application === null) {
|
||||||
return;
|
url = null;
|
||||||
}
|
} else if (!application.enablePassword && window.location.pathname.includes("/auto-signup/oauth/authorize")) {
|
||||||
|
url = window.location.href.replace("/auto-signup/oauth/authorize", "/login/oauth/authorize");
|
||||||
if (!application.enablePassword && window.location.pathname.includes("/auto-signup/oauth/authorize")) {
|
} else if (authConfig.appName === application.name) {
|
||||||
const link = window.location.href.replace("/auto-signup/oauth/authorize", "/login/oauth/authorize");
|
url = "/login";
|
||||||
goToLink(link);
|
} else if (application.signinUrl === "") {
|
||||||
return;
|
url = path.join(application.homepageUrl, "login");
|
||||||
}
|
|
||||||
|
|
||||||
if (authConfig.appName === application.name) {
|
|
||||||
goToLinkSoft(ths, "/login");
|
|
||||||
} else {
|
} else {
|
||||||
if (application.signinUrl === "") {
|
url = application.signinUrl;
|
||||||
goToLink(`${application.homepageUrl}/login`);
|
}
|
||||||
} else {
|
return url;
|
||||||
goToLink(application.signinUrl);
|
}
|
||||||
}
|
|
||||||
|
export function renderLoginLink(application, text) {
|
||||||
|
const url = getLoginLink(application);
|
||||||
|
return renderLink(url, text, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function redirectToLoginPage(application) {
|
||||||
|
const loginLink = getLoginLink(application);
|
||||||
|
const history = useHistory();
|
||||||
|
history.push(loginLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderLink(url, text, onClick) {
|
||||||
|
if (url === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.startsWith("/")) {
|
||||||
|
return (
|
||||||
|
<Link style={{float: "right"}} to={url} onClick={() => {
|
||||||
|
if (onClick !== null) {
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
}}>{text}</Link>
|
||||||
|
);
|
||||||
|
} else if (url.startsWith("http")) {
|
||||||
|
return (
|
||||||
|
<a target="_blank" rel="noopener noreferrer" style={{float: "right"}} href={url} onClick={() => {
|
||||||
|
if (onClick !== null) {
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
}}>{text}</a>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goToSignup(ths, application) {
|
export function renderSignupLink(application, text) {
|
||||||
|
let url;
|
||||||
if (application === null) {
|
if (application === null) {
|
||||||
return;
|
url = null;
|
||||||
}
|
} else if (!application.enablePassword && window.location.pathname.includes("/login/oauth/authorize")) {
|
||||||
|
url = window.location.href.replace("/login/oauth/authorize", "/auto-signup/oauth/authorize");
|
||||||
if (!application.enablePassword && window.location.pathname.includes("/login/oauth/authorize")) {
|
} else if (authConfig.appName === application.name) {
|
||||||
const link = window.location.href.replace("/login/oauth/authorize", "/auto-signup/oauth/authorize");
|
url = "/signup";
|
||||||
goToLink(link);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (authConfig.appName === application.name) {
|
|
||||||
goToLinkSoft(ths, "/signup");
|
|
||||||
} else {
|
} else {
|
||||||
if (application.signupUrl === "") {
|
if (application.signupUrl === "") {
|
||||||
goToLinkSoft(ths, `/signup/${application.name}`);
|
url = `/signup/${application.name}`;
|
||||||
} else {
|
} else {
|
||||||
goToLink(application.signupUrl);
|
url = application.signupUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const storeSigninUrl = () => {
|
||||||
|
sessionStorage.setItem("signinUrl", window.location.href);
|
||||||
|
};
|
||||||
|
|
||||||
|
return renderLink(url, text, storeSigninUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goToForget(ths, application) {
|
export function renderForgetLink(application, text) {
|
||||||
|
let url;
|
||||||
if (application === null) {
|
if (application === null) {
|
||||||
return;
|
url = null;
|
||||||
}
|
} else if (authConfig.appName === application.name) {
|
||||||
|
url = "/forget";
|
||||||
if (authConfig.appName === application.name) {
|
|
||||||
goToLinkSoft(ths, "/forget");
|
|
||||||
} else {
|
} else {
|
||||||
if (application.forgetUrl === "") {
|
if (application.forgetUrl === "") {
|
||||||
goToLinkSoft(ths, `/forget/${application.name}`);
|
url = `/forget/${application.name}`;
|
||||||
} else {
|
} else {
|
||||||
goToLink(application.forgetUrl);
|
url = application.forgetUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return renderLink(url, text, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderHelmet(application) {
|
export function renderHelmet(application) {
|
||||||
|
@ -164,7 +164,7 @@ class SignupTable extends React.Component {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("application:rule"),
|
title: i18next.t("application:Rule"),
|
||||||
dataIndex: "rule",
|
dataIndex: "rule",
|
||||||
key: "rule",
|
key: "rule",
|
||||||
width: "155px",
|
width: "155px",
|
||||||
|
@ -352,7 +352,7 @@ class UserListPage extends BaseListPage {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={users} rowKey="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}
|
||||||
title={() => (
|
title={() => (
|
||||||
<div>
|
<div>
|
||||||
{i18next.t("general:Users")}
|
{i18next.t("general:Users")}
|
||||||
|
@ -13,11 +13,15 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import {authConfig} from "./Auth";
|
import {authConfig} from "./Auth";
|
||||||
|
import * as Setting from "../Setting";
|
||||||
|
|
||||||
export function getAccount(query) {
|
export function getAccount(query) {
|
||||||
return fetch(`${authConfig.serverUrl}/api/get-account${query}`, {
|
return fetch(`${authConfig.serverUrl}/api/get-account${query}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +30,9 @@ export function signup(values) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(values),
|
body: JSON.stringify(values),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +41,9 @@ export function getEmailAndPhone(values) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(values),
|
body: JSON.stringify(values),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then((res) => res.json());
|
}).then((res) => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +61,9 @@ export function getApplicationLogin(oAuthParams) {
|
|||||||
return fetch(`${authConfig.serverUrl}/api/get-app-login${oAuthParamsToQuery(oAuthParams)}`, {
|
return fetch(`${authConfig.serverUrl}/api/get-app-login${oAuthParamsToQuery(oAuthParams)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +72,9 @@ export function login(values, oAuthParams) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(values),
|
body: JSON.stringify(values),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +83,9 @@ export function loginCas(values, params) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(values),
|
body: JSON.stringify(values),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +93,9 @@ export function logout() {
|
|||||||
return fetch(`${authConfig.serverUrl}/api/logout`, {
|
return fetch(`${authConfig.serverUrl}/api/logout`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,6 +104,9 @@ export function unlink(values) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(values),
|
body: JSON.stringify(values),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +114,9 @@ export function getSamlLogin(providerId, relayState) {
|
|||||||
return fetch(`${authConfig.serverUrl}/api/get-saml-login?id=${providerId}&relayState=${relayState}`, {
|
return fetch(`${authConfig.serverUrl}/api/get-saml-login?id=${providerId}&relayState=${relayState}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,5 +125,8 @@ export function loginWithSaml(values, param) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(values),
|
body: JSON.stringify(values),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ class ForgetPage extends React.Component {
|
|||||||
values.userOwner = this.state.application?.organizationObj.name;
|
values.userOwner = this.state.application?.organizationObj.name;
|
||||||
UserBackend.setPassword(values.userOwner, values.username, "", values?.newPassword).then(res => {
|
UserBackend.setPassword(values.userOwner, values.username, "", values?.newPassword).then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.goToLogin(this, this.state.application);
|
Setting.redirectToLoginPage(this.state.application);
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
|
Setting.showMessage("error", i18next.t(`signup:${res.msg}`));
|
||||||
}
|
}
|
||||||
@ -487,61 +487,65 @@ class ForgetPage extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
||||||
<Col span={24} style={{justifyContent: "center"}}>
|
<CustomGithubCorner />
|
||||||
|
<div className="login-content forget-content">
|
||||||
<Row>
|
<Row>
|
||||||
<Col span={24}>
|
<Col span={24} style={{justifyContent: "center"}}>
|
||||||
<div style={{marginTop: "80px", marginBottom: "10px", textAlign: "center"}}>
|
<Row>
|
||||||
{
|
<Col span={24}>
|
||||||
Setting.renderHelmet(application)
|
<div style={{marginTop: "80px", marginBottom: "10px", textAlign: "center"}}>
|
||||||
}
|
{
|
||||||
<CustomGithubCorner />
|
Setting.renderHelmet(application)
|
||||||
{
|
}
|
||||||
Setting.renderLogo(application)
|
{
|
||||||
}
|
Setting.renderLogo(application)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>
|
||||||
|
<div style={{textAlign: "center", fontSize: "28px"}}>
|
||||||
|
{i18next.t("forget:Retrieve password")}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>
|
||||||
|
<Steps
|
||||||
|
current={this.state.current}
|
||||||
|
style={{
|
||||||
|
width: "90%",
|
||||||
|
maxWidth: "500px",
|
||||||
|
margin: "auto",
|
||||||
|
marginTop: "80px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Step
|
||||||
|
title={i18next.t("forget:Account")}
|
||||||
|
icon={<UserOutlined />}
|
||||||
|
/>
|
||||||
|
<Step
|
||||||
|
title={i18next.t("forget:Verify")}
|
||||||
|
icon={<SolutionOutlined />}
|
||||||
|
/>
|
||||||
|
<Step
|
||||||
|
title={i18next.t("forget:Reset")}
|
||||||
|
icon={<KeyOutlined />}
|
||||||
|
/>
|
||||||
|
</Steps>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
<Col span={24} style={{display: "flex", justifyContent: "center"}}>
|
||||||
|
<div style={{marginTop: "10px", textAlign: "center"}}>
|
||||||
|
{this.renderForm(application)}
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
</div>
|
||||||
<Col span={24}>
|
</div>
|
||||||
<div style={{textAlign: "center", fontSize: "28px"}}>
|
|
||||||
{i18next.t("forget:Retrieve password")}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
|
||||||
<Col span={24}>
|
|
||||||
<Steps
|
|
||||||
current={this.state.current}
|
|
||||||
style={{
|
|
||||||
width: "90%",
|
|
||||||
maxWidth: "500px",
|
|
||||||
margin: "auto",
|
|
||||||
marginTop: "80px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Step
|
|
||||||
title={i18next.t("forget:Account")}
|
|
||||||
icon={<UserOutlined />}
|
|
||||||
/>
|
|
||||||
<Step
|
|
||||||
title={i18next.t("forget:Verify")}
|
|
||||||
icon={<SolutionOutlined />}
|
|
||||||
/>
|
|
||||||
<Step
|
|
||||||
title={i18next.t("forget:Reset")}
|
|
||||||
icon={<KeyOutlined />}
|
|
||||||
/>
|
|
||||||
</Steps>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</Col>
|
|
||||||
<Col span={24} style={{display: "flex", justifyContent: "center"}}>
|
|
||||||
<div style={{marginTop: "10px", textAlign: "center"}}>
|
|
||||||
{this.renderForm(application)}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Link} from "react-router-dom";
|
|
||||||
import {Button, Checkbox, Col, Form, Input, Result, Row, Spin, Tabs} from "antd";
|
import {Button, Checkbox, Col, Form, Input, Result, Row, Spin, Tabs} from "antd";
|
||||||
import {LockOutlined, UserOutlined} from "@ant-design/icons";
|
import {LockOutlined, UserOutlined} from "@ant-design/icons";
|
||||||
import * as UserWebauthnBackend from "../backend/UserWebauthnBackend";
|
import * as UserWebauthnBackend from "../backend/UserWebauthnBackend";
|
||||||
@ -30,6 +29,7 @@ import CustomGithubCorner from "../CustomGithubCorner";
|
|||||||
import {CountDownInput} from "../common/CountDownInput";
|
import {CountDownInput} from "../common/CountDownInput";
|
||||||
import SelectLanguageBox from "../SelectLanguageBox";
|
import SelectLanguageBox from "../SelectLanguageBox";
|
||||||
import {withTranslation} from "react-i18next";
|
import {withTranslation} from "react-i18next";
|
||||||
|
import {CaptchaModal} from "../common/CaptchaModal";
|
||||||
|
|
||||||
const {TabPane} = Tabs;
|
const {TabPane} = Tabs;
|
||||||
|
|
||||||
@ -49,6 +49,9 @@ class LoginPage extends React.Component {
|
|||||||
validEmail: false,
|
validEmail: false,
|
||||||
validPhone: false,
|
validPhone: false,
|
||||||
loginMethod: "password",
|
loginMethod: "password",
|
||||||
|
enableCaptchaModal: false,
|
||||||
|
openCaptchaModal: false,
|
||||||
|
verifyCaptcha: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
|
if (this.state.type === "cas" && props.match?.params.casApplicationName !== undefined) {
|
||||||
@ -69,6 +72,18 @@ class LoginPage extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||||
|
if (this.state.application && !prevState.application) {
|
||||||
|
const defaultCaptchaProviderItems = this.getDefaultCaptchaProviderItems(this.state.application);
|
||||||
|
|
||||||
|
if (!defaultCaptchaProviderItems) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({enableCaptchaModal: defaultCaptchaProviderItems.some(providerItem => providerItem.rule === "Always")});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getApplicationLogin() {
|
getApplicationLogin() {
|
||||||
const oAuthParams = Util.getOAuthGetParameters();
|
const oAuthParams = Util.getOAuthGetParameters();
|
||||||
AuthBackend.getApplicationLogin(oAuthParams)
|
AuthBackend.getApplicationLogin(oAuthParams)
|
||||||
@ -139,6 +154,18 @@ class LoginPage extends React.Component {
|
|||||||
this.props.onUpdateAccount(account);
|
this.props.onUpdateAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseOffset(offset) {
|
||||||
|
if (offset === 2 || offset === 4 || Setting.inIframe() || Setting.isMobile()) {
|
||||||
|
return "0 auto";
|
||||||
|
}
|
||||||
|
if (offset === 1) {
|
||||||
|
return "0 10%";
|
||||||
|
}
|
||||||
|
if (offset === 3) {
|
||||||
|
return "0 60%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
populateOauthValues(values) {
|
populateOauthValues(values) {
|
||||||
const oAuthParams = Util.getOAuthGetParameters();
|
const oAuthParams = Util.getOAuthGetParameters();
|
||||||
if (oAuthParams !== null && oAuthParams.responseType !== null && oAuthParams.responseType !== "") {
|
if (oAuthParams !== null && oAuthParams.responseType !== null && oAuthParams.responseType !== "") {
|
||||||
@ -214,6 +241,23 @@ class LoginPage extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.state.loginMethod === "password" && this.state.enableCaptchaModal) {
|
||||||
|
this.setState({
|
||||||
|
openCaptchaModal: true,
|
||||||
|
verifyCaptcha: (captchaType, captchaToken, secret) => {
|
||||||
|
values["captchaType"] = captchaType;
|
||||||
|
values["captchaToken"] = captchaToken;
|
||||||
|
values["clientSecret"] = secret;
|
||||||
|
|
||||||
|
this.login(values);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.login(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
login(values) {
|
||||||
// here we are supposed to determine whether Casdoor is working as an OAuth server or CAS server
|
// here we are supposed to determine whether Casdoor is working as an OAuth server or CAS server
|
||||||
if (this.state.type === "cas") {
|
if (this.state.type === "cas") {
|
||||||
// CAS
|
// CAS
|
||||||
@ -228,6 +272,8 @@ class LoginPage extends React.Component {
|
|||||||
}
|
}
|
||||||
Util.showMessage("success", msg);
|
Util.showMessage("success", msg);
|
||||||
|
|
||||||
|
this.setState({openCaptchaModal: false});
|
||||||
|
|
||||||
if (casParams.service !== "") {
|
if (casParams.service !== "") {
|
||||||
const st = res.data;
|
const st = res.data;
|
||||||
const newUrl = new URL(casParams.service);
|
const newUrl = new URL(casParams.service);
|
||||||
@ -235,6 +281,7 @@ class LoginPage extends React.Component {
|
|||||||
window.location.href = newUrl.toString();
|
window.location.href = newUrl.toString();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
this.setState({openCaptchaModal: false});
|
||||||
Util.showMessage("error", `Failed to log in: ${res.msg}`);
|
Util.showMessage("error", `Failed to log in: ${res.msg}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -247,6 +294,7 @@ class LoginPage extends React.Component {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
const responseType = values["type"];
|
const responseType = values["type"];
|
||||||
|
|
||||||
if (responseType === "login") {
|
if (responseType === "login") {
|
||||||
Util.showMessage("success", "Logged in successfully");
|
Util.showMessage("success", "Logged in successfully");
|
||||||
|
|
||||||
@ -264,6 +312,7 @@ class LoginPage extends React.Component {
|
|||||||
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
Setting.goToLink(`${redirectUri}?SAMLResponse=${encodeURIComponent(SAMLResponse)}&RelayState=${oAuthParams.relayState}`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
this.setState({openCaptchaModal: false});
|
||||||
Util.showMessage("error", `Failed to log in: ${res.msg}`);
|
Util.showMessage("error", `Failed to log in: ${res.msg}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -290,13 +339,11 @@ class LoginPage extends React.Component {
|
|||||||
title="Sign Up Error"
|
title="Sign Up Error"
|
||||||
subTitle={"The application does not allow to sign up new account"}
|
subTitle={"The application does not allow to sign up new account"}
|
||||||
extra={[
|
extra={[
|
||||||
<Link key="login" onClick={() => {
|
<Button type="primary" key="signin" onClick={() => Setting.redirectToLoginPage(application)}>
|
||||||
Setting.goToLogin(this, application);
|
{
|
||||||
}}>
|
i18next.t("login:Sign In")
|
||||||
<Button type="primary" key="signin">
|
}
|
||||||
Sign In
|
</Button>,
|
||||||
</Button>
|
|
||||||
</Link>,
|
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
</Result>
|
</Result>
|
||||||
@ -393,11 +440,9 @@ class LoginPage extends React.Component {
|
|||||||
{i18next.t("login:Auto sign in")}
|
{i18next.t("login:Auto sign in")}
|
||||||
</Checkbox>
|
</Checkbox>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<a style={{float: "right"}} onClick={() => {
|
{
|
||||||
Setting.goToForget(this, application);
|
Setting.renderForgetLink(application, i18next.t("login:Forgot password?"))
|
||||||
}}>
|
}
|
||||||
{i18next.t("login:Forgot password?")}
|
|
||||||
</a>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button
|
<Button
|
||||||
@ -411,6 +456,9 @@ class LoginPage extends React.Component {
|
|||||||
i18next.t("login:Sign In")
|
i18next.t("login:Sign In")
|
||||||
}
|
}
|
||||||
</Button>
|
</Button>
|
||||||
|
{
|
||||||
|
this.renderCaptchaModal(application)
|
||||||
|
}
|
||||||
{
|
{
|
||||||
this.renderFooter(application)
|
this.renderFooter(application)
|
||||||
}
|
}
|
||||||
@ -453,16 +501,54 @@ class LoginPage extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDefaultCaptchaProviderItems(application) {
|
||||||
|
const providers = application?.providers;
|
||||||
|
|
||||||
|
if (providers === undefined || providers === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return providers.filter(providerItem => {
|
||||||
|
if (providerItem.provider === undefined || providerItem.provider === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return providerItem.provider.category === "Captcha" && providerItem.provider.type === "Default";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCaptchaModal(application) {
|
||||||
|
if (!this.state.enableCaptchaModal) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = this.getDefaultCaptchaProviderItems(application)
|
||||||
|
.filter(providerItem => providerItem.rule === "Always")
|
||||||
|
.map(providerItem => providerItem.provider)[0];
|
||||||
|
|
||||||
|
return <CaptchaModal
|
||||||
|
owner={provider.owner}
|
||||||
|
name={provider.name}
|
||||||
|
captchaType={provider.type}
|
||||||
|
subType={provider.subType}
|
||||||
|
clientId={provider.clientId}
|
||||||
|
clientId2={provider.clientId2}
|
||||||
|
clientSecret={provider.clientSecret}
|
||||||
|
clientSecret2={provider.clientSecret2}
|
||||||
|
open={this.state.openCaptchaModal}
|
||||||
|
onOk={(captchaType, captchaToken, secret) => this.state.verifyCaptcha?.(captchaType, captchaToken, secret)}
|
||||||
|
canCancel={false}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
|
||||||
renderFooter(application) {
|
renderFooter(application) {
|
||||||
if (this.state.mode === "signup") {
|
if (this.state.mode === "signup") {
|
||||||
return (
|
return (
|
||||||
<div style={{float: "right"}}>
|
<div style={{float: "right"}}>
|
||||||
{i18next.t("signup:Have account?")}
|
{i18next.t("signup:Have account?")}
|
||||||
<Link onClick={() => {
|
{
|
||||||
Setting.goToLogin(this, application);
|
Setting.renderLoginLink(application, i18next.t("signup:sign in now"))
|
||||||
}}>
|
}
|
||||||
{i18next.t("signup:sign in now")}
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -473,12 +559,9 @@ class LoginPage extends React.Component {
|
|||||||
!application.enableSignUp ? null : (
|
!application.enableSignUp ? null : (
|
||||||
<>
|
<>
|
||||||
{i18next.t("login:No account?")}
|
{i18next.t("login:No account?")}
|
||||||
<a onClick={() => {
|
{
|
||||||
sessionStorage.setItem("signinUrl", window.location.href);
|
Setting.renderSignupLink(application, i18next.t("login:sign up now"))
|
||||||
Setting.goToSignup(this, application);
|
}
|
||||||
}}>
|
|
||||||
{i18next.t("login:sign up now")}
|
|
||||||
</a>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -695,16 +778,18 @@ class LoginPage extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const formStyle = Setting.inIframe() ? null : Setting.parseObject(application.formCss);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
||||||
<CustomGithubCorner />
|
<CustomGithubCorner />
|
||||||
<Row>
|
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
|
||||||
<Col span={8} offset={application.formOffset === 0 || Setting.inIframe() || Setting.isMobile() ? 8 : application.formOffset} style={{display: "flex", justifyContent: "center"}}>
|
{Setting.inIframe() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
||||||
<div className="login-content">
|
<div className="login-panel">
|
||||||
<div style={{marginTop: "80px", marginBottom: "50px", textAlign: "center", ...formStyle}}>
|
<SelectLanguageBox id="language-box-corner" style={{top: "50px"}} />
|
||||||
<SelectLanguageBox id="language-box-corner" style={{top: formStyle !== null ? "80px" : "45px", right: formStyle !== null ? "5px" : "-45px"}} />
|
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
||||||
|
<div dangerouslySetInnerHTML={{__html: application.formSideHtml}} />
|
||||||
|
</div>
|
||||||
|
<div className="login-form">
|
||||||
|
<div >
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
Setting.renderHelmet(application)
|
Setting.renderHelmet(application)
|
||||||
@ -724,8 +809,8 @@ class LoginPage extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</div>
|
||||||
</Row>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ class PromptPage extends React.Component {
|
|||||||
if (redirectUrl !== "" && redirectUrl !== null) {
|
if (redirectUrl !== "" && redirectUrl !== null) {
|
||||||
Setting.goToLink(redirectUrl);
|
Setting.goToLink(redirectUrl);
|
||||||
} else {
|
} else {
|
||||||
Setting.goToLogin(this, this.getApplicationObj());
|
Setting.redirectToLoginPage(this.getApplicationObj());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Setting.showMessage("error", `Failed to log out: ${res.msg}`);
|
Setting.showMessage("error", `Failed to log out: ${res.msg}`);
|
||||||
@ -234,10 +234,10 @@ class PromptPage extends React.Component {
|
|||||||
title="Sign Up Error"
|
title="Sign Up Error"
|
||||||
subTitle={"You are unexpected to see this prompt page"}
|
subTitle={"You are unexpected to see this prompt page"}
|
||||||
extra={[
|
extra={[
|
||||||
<Button type="primary" key="signin" onClick={() => {
|
<Button type="primary" key="signin" onClick={() => Setting.redirectToLoginPage(application)}>
|
||||||
Setting.goToLogin(this, application);
|
{
|
||||||
}}>
|
i18next.t("login:Sign In")
|
||||||
Sign In
|
}
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
@ -69,7 +69,7 @@ class ResultPage extends React.Component {
|
|||||||
if (linkInStorage !== null && linkInStorage !== "") {
|
if (linkInStorage !== null && linkInStorage !== "") {
|
||||||
Setting.goToLink(linkInStorage);
|
Setting.goToLink(linkInStorage);
|
||||||
} else {
|
} else {
|
||||||
Setting.goToLogin(this, application);
|
Setting.redirectToLoginPage(application);
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
{i18next.t("login:Sign In")}
|
{i18next.t("login:Sign In")}
|
||||||
|
@ -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, Checkbox, Col, Form, Input, Modal, Result, Row} 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";
|
||||||
@ -148,6 +148,18 @@ class SignupPage extends React.Component {
|
|||||||
this.props.onUpdateAccount(account);
|
this.props.onUpdateAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseOffset(offset) {
|
||||||
|
if (offset === 2 || offset === 4 || Setting.inIframe() || Setting.isMobile()) {
|
||||||
|
return "0 auto";
|
||||||
|
}
|
||||||
|
if (offset === 1) {
|
||||||
|
return "0 10%";
|
||||||
|
}
|
||||||
|
if (offset === 3) {
|
||||||
|
return "0 60%";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onFinish(values) {
|
onFinish(values) {
|
||||||
const application = this.getApplicationObj();
|
const application = this.getApplicationObj();
|
||||||
values.phonePrefix = application.organizationObj.phonePrefix;
|
values.phonePrefix = application.organizationObj.phonePrefix;
|
||||||
@ -529,10 +541,10 @@ class SignupPage extends React.Component {
|
|||||||
title="Sign Up Error"
|
title="Sign Up Error"
|
||||||
subTitle={"The application does not allow to sign up new account"}
|
subTitle={"The application does not allow to sign up new account"}
|
||||||
extra={[
|
extra={[
|
||||||
<Button type="primary" key="signin" onClick={() => {
|
<Button type="primary" key="signin" onClick={() => Setting.redirectToLoginPage(application)}>
|
||||||
Setting.goToLogin(this, application);
|
{
|
||||||
}}>
|
i18next.t("login:Sign In")
|
||||||
Sign In
|
}
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
@ -588,7 +600,7 @@ class SignupPage extends React.Component {
|
|||||||
if (linkInStorage !== null && linkInStorage !== "") {
|
if (linkInStorage !== null && linkInStorage !== "") {
|
||||||
Setting.goToLink(linkInStorage);
|
Setting.goToLink(linkInStorage);
|
||||||
} else {
|
} else {
|
||||||
Setting.goToLogin(this, application);
|
Setting.redirectToLoginPage(application);
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
{i18next.t("signup:sign in now")}
|
{i18next.t("signup:sign in now")}
|
||||||
@ -615,17 +627,18 @@ class SignupPage extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const formStyle = Setting.inIframe() ? null : Setting.parseObject(application.formCss);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
||||||
<CustomGithubCorner />
|
<CustomGithubCorner />
|
||||||
|
<div className="login-content" style={{margin: this.parseOffset(application.formOffset)}}>
|
||||||
<Row>
|
{Setting.inIframe() ? null : <div dangerouslySetInnerHTML={{__html: application.formCss}} />}
|
||||||
<Col span={8} offset={application.formOffset === 0 || Setting.inIframe() || Setting.isMobile() ? 8 : application.formOffset} style={{display: "flex", justifyContent: "center"}} >
|
<div className="login-panel" >
|
||||||
<div className="login-content">
|
<SelectLanguageBox id="language-box-corner" style={{top: "50px"}} />
|
||||||
<div style={{marginBottom: "10px", textAlign: "center", ...formStyle}}>
|
<div className="side-image" style={{display: application.formOffset !== 4 ? "none" : null}}>
|
||||||
<SelectLanguageBox id="language-box-corner" style={{top: formStyle !== null ? "3px" : "-20px", right: formStyle !== null ? "5px" : "-45px"}} />
|
<div dangerouslySetInnerHTML={{__html: application.formSideHtml}} />
|
||||||
|
</div>
|
||||||
|
<div className="login-form">
|
||||||
|
<div >
|
||||||
{
|
{
|
||||||
Setting.renderHelmet(application)
|
Setting.renderHelmet(application)
|
||||||
}
|
}
|
||||||
@ -637,8 +650,8 @@ class SignupPage extends React.Component {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</div>
|
||||||
</Row>
|
</div>
|
||||||
{
|
{
|
||||||
this.renderModal()
|
this.renderModal()
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getAdapters(owner, page = "", pageSize = "", field = "", value =
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-adapters?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-adapters?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getAdapter(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-adapter?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-adapter?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateAdapter(owner, name, Adapter) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newAdapter),
|
body: JSON.stringify(newAdapter),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addAdapter(Adapter) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newAdapter),
|
body: JSON.stringify(newAdapter),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +64,9 @@ export function deleteAdapter(Adapter) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newAdapter),
|
body: JSON.stringify(newAdapter),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,5 +74,8 @@ export function syncPolicies(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/sync-policies?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/sync-policies?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getApplications(owner, page = "", pageSize = "", field = "", val
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-applications?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-applications?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getApplicationsByOrganization(owner, organization) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-organization-applications?owner=${owner}&organization=${organization}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-organization-applications?owner=${owner}&organization=${organization}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +38,9 @@ export function getApplication(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-application?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-application?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +48,9 @@ export function getUserApplication(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-user-application?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-user-application?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +60,9 @@ export function updateApplication(owner, name, application) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newApplication),
|
body: JSON.stringify(newApplication),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +73,9 @@ export function addApplication(application) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newApplication),
|
body: JSON.stringify(newApplication),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +85,9 @@ export function deleteApplication(application) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newApplication),
|
body: JSON.stringify(newApplication),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,5 +95,8 @@ export function getSamlMetadata(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/saml/metadata?application=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/saml/metadata?application=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.text());
|
}).then(res => res.text());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getCerts(owner, page = "", pageSize = "", field = "", value = ""
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-certs?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-certs?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getCert(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-cert?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-cert?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateCert(owner, name, cert) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newCert),
|
body: JSON.stringify(newCert),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addCert(cert) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newCert),
|
body: JSON.stringify(newCert),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,5 +64,8 @@ export function deleteCert(cert) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newCert),
|
body: JSON.stringify(newCert),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getLdaps(owner) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-ldaps?owner=${owner}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-ldaps?owner=${owner}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getLdap(id) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-ldap?id=${id}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-ldap?id=${id}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +39,9 @@ export function addLdap(body) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +50,9 @@ export function deleteLdap(body) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +61,9 @@ export function updateLdap(body) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +72,9 @@ export function getLdapUser(body) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +83,9 @@ export function syncUsers(owner, ldapId, body) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,5 +94,8 @@ export function checkLdapUsersExist(owner, body) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getModels(owner, page = "", pageSize = "", field = "", value = "
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-models?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-models?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getModel(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-model?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-model?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateModel(owner, name, model) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newModel),
|
body: JSON.stringify(newModel),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addModel(model) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newModel),
|
body: JSON.stringify(newModel),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,5 +64,8 @@ export function deleteModel(model) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newModel),
|
body: JSON.stringify(newModel),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getOrganizations(owner, page = "", pageSize = "", field = "", va
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-organizations?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-organizations?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getOrganization(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-organization?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-organization?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateOrganization(owner, name, organization) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newOrganization),
|
body: JSON.stringify(newOrganization),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addOrganization(organization) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newOrganization),
|
body: JSON.stringify(newOrganization),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +64,9 @@ export function deleteOrganization(organization) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newOrganization),
|
body: JSON.stringify(newOrganization),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,5 +74,8 @@ export function getDefaultApplication(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-default-application?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-default-application?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getPayments(owner, page = "", pageSize = "", field = "", value =
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-payments?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-payments?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getPayment(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-payment?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-payment?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updatePayment(owner, name, payment) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newPayment),
|
body: JSON.stringify(newPayment),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addPayment(payment) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newPayment),
|
body: JSON.stringify(newPayment),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +64,9 @@ export function deletePayment(payment) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newPayment),
|
body: JSON.stringify(newPayment),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,5 +74,8 @@ export function invoicePayment(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/invoice-payment?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/invoice-payment?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getPermissions(owner, page = "", pageSize = "", field = "", valu
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-permissions?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-permissions?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getPermissionsBySubmitter() {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-permissions-by-submitter`, {
|
return fetch(`${Setting.ServerUrl}/api/get-permissions-by-submitter`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +38,9 @@ export function getPermission(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-permission?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-permission?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +50,9 @@ export function updatePermission(owner, name, permission) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newPermission),
|
body: JSON.stringify(newPermission),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +62,9 @@ export function addPermission(permission) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newPermission),
|
body: JSON.stringify(newPermission),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,5 +74,8 @@ export function deletePermission(permission) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newPermission),
|
body: JSON.stringify(newPermission),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getProducts(owner, page = "", pageSize = "", field = "", value =
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-products?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-products?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getProduct(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-product?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-product?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateProduct(owner, name, product) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newProduct),
|
body: JSON.stringify(newProduct),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addProduct(product) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newProduct),
|
body: JSON.stringify(newProduct),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +64,9 @@ export function deleteProduct(product) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newProduct),
|
body: JSON.stringify(newProduct),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,5 +74,8 @@ export function buyProduct(owner, name, providerId) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/buy-product?id=${owner}/${encodeURIComponent(name)}&providerName=${providerId}`, {
|
return fetch(`${Setting.ServerUrl}/api/buy-product?id=${owner}/${encodeURIComponent(name)}&providerName=${providerId}`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getProviders(owner, page = "", pageSize = "", field = "", value
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-providers?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-providers?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getProvider(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-provider?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-provider?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateProvider(owner, name, provider) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newProvider),
|
body: JSON.stringify(newProvider),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addProvider(provider) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newProvider),
|
body: JSON.stringify(newProvider),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,5 +64,8 @@ export function deleteProvider(provider) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newProvider),
|
body: JSON.stringify(newProvider),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,5 +18,8 @@ export function getRecords(page, pageSize, field = "", value = "", sortField = "
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-records?pageSize=${pageSize}&p=${page}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-records?pageSize=${pageSize}&p=${page}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getResources(owner, user, page = "", pageSize = "", field = "",
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-resources?owner=${owner}&user=${user}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-resources?owner=${owner}&user=${user}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getResource(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-resource?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-resource?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateResource(owner, name, resource) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newResource),
|
body: JSON.stringify(newResource),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addResource(resource) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newResource),
|
body: JSON.stringify(newResource),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +64,9 @@ export function deleteResource(resource, provider = "") {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newResource),
|
body: JSON.stringify(newResource),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,5 +78,8 @@ export function uploadResource(owner, user, tag, parent, fullFilePath, file, pro
|
|||||||
body: formData,
|
body: formData,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getRoles(owner, page = "", pageSize = "", field = "", value = ""
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-roles?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-roles?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getRole(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-role?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-role?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateRole(owner, name, role) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newRole),
|
body: JSON.stringify(newRole),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addRole(role) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newRole),
|
body: JSON.stringify(newRole),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,5 +64,8 @@ export function deleteRole(role) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newRole),
|
body: JSON.stringify(newRole),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getSyncers(owner, page = "", pageSize = "", field = "", value =
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-syncers?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-syncers?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getSyncer(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-syncer?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-syncer?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateSyncer(owner, name, syncer) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newSyncer),
|
body: JSON.stringify(newSyncer),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addSyncer(syncer) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newSyncer),
|
body: JSON.stringify(newSyncer),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +64,9 @@ export function deleteSyncer(syncer) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newSyncer),
|
body: JSON.stringify(newSyncer),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,5 +74,8 @@ export function runSyncer(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/run-syncer?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/run-syncer?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getSystemInfo(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-system-info?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-system-info?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,5 +28,8 @@ export function getGitHubLatestReleaseVersion() {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-release`, {
|
return fetch(`${Setting.ServerUrl}/api/get-release`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function getTokens(owner, page = "", pageSize = "", field = "", value = "
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-tokens?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-tokens?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getToken(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-token?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-token?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateToken(owner, name, token) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newToken),
|
body: JSON.stringify(newToken),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addToken(token) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newToken),
|
body: JSON.stringify(newToken),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,5 +64,8 @@ export function deleteToken(token) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newToken),
|
body: JSON.stringify(newToken),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,9 @@ export function getGlobalUsers(page, pageSize, field = "", value = "", sortField
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-global-users?p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-global-users?p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +29,9 @@ export function getUsers(owner, page = "", pageSize = "", field = "", value = ""
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-users?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-users?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +39,9 @@ export function getUser(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-user?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-user?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +51,9 @@ export function updateUser(owner, name, user) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newUser),
|
body: JSON.stringify(newUser),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +63,9 @@ export function addUser(user) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newUser),
|
body: JSON.stringify(newUser),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +75,9 @@ export function deleteUser(user) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newUser),
|
body: JSON.stringify(newUser),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +103,9 @@ export function setPassword(userOwner, userName, oldPassword, newPassword) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: formData,
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +122,9 @@ export function sendCode(checkType, checkId, checkKey, dest, type, applicationId
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: formData,
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json()).then(res => {
|
}).then(res => res.json()).then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
Setting.showMessage("success", i18next.t("user:Code Sent"));
|
Setting.showMessage("success", i18next.t("user:Code Sent"));
|
||||||
@ -121,6 +145,9 @@ export function verifyCaptcha(captchaType, captchaToken, clientSecret) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: formData,
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json()).then(res => {
|
}).then(res => res.json()).then(res => {
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
@ -145,11 +172,17 @@ export function resetEmailOrPhone(dest, type, code) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: formData,
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCaptcha(owner, name, isCurrentProvider) {
|
export function getCaptcha(owner, name, isCurrentProvider) {
|
||||||
return fetch(`${Setting.ServerUrl}/api/get-captcha?applicationId=${owner}/${encodeURIComponent(name)}&isCurrentProvider=${isCurrentProvider}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-captcha?applicationId=${owner}/${encodeURIComponent(name)}&isCurrentProvider=${isCurrentProvider}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json()).then(res => res.data);
|
}).then(res => res.json()).then(res => res.data);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,9 @@ export function registerWebauthnCredential() {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/webauthn/signup/begin`, {
|
return fetch(`${Setting.ServerUrl}/api/webauthn/signup/begin`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then((credentialCreationOptions) => {
|
.then((credentialCreationOptions) => {
|
||||||
@ -62,6 +65,9 @@ export function deleteUserWebAuthnCredential(credentialID) {
|
|||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: form,
|
body: form,
|
||||||
dataType: "text",
|
dataType: "text",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,9 @@ export function getWebhooks(owner, page = "", pageSize = "", field = "", value =
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-webhooks?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-webhooks?owner=${owner}&p=${page}&pageSize=${pageSize}&field=${field}&value=${value}&sortField=${sortField}&sortOrder=${sortOrder}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +28,9 @@ export function getWebhook(owner, name) {
|
|||||||
return fetch(`${Setting.ServerUrl}/api/get-webhook?id=${owner}/${encodeURIComponent(name)}`, {
|
return fetch(`${Setting.ServerUrl}/api/get-webhook?id=${owner}/${encodeURIComponent(name)}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +40,9 @@ export function updateWebhook(owner, name, webhook) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newWebhook),
|
body: JSON.stringify(newWebhook),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +52,9 @@ export function addWebhook(webhook) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newWebhook),
|
body: JSON.stringify(newWebhook),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,5 +64,8 @@ export function deleteWebhook(webhook) {
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
body: JSON.stringify(newWebhook),
|
body: JSON.stringify(newWebhook),
|
||||||
|
headers: {
|
||||||
|
"Accept-Language": Setting.getAcceptLanguage(),
|
||||||
|
},
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,10 @@ class SingleCard extends React.Component {
|
|||||||
<Card
|
<Card
|
||||||
hoverable
|
hoverable
|
||||||
cover={
|
cover={
|
||||||
<img alt="logo" src={logo} style={{width: "100%", objectFit: "scale-down"}} />
|
<img alt="logo" src={logo} style={{width: "100%", height: "200px", padding: "20px", objectFit: "scale-down"}} />
|
||||||
}
|
}
|
||||||
onClick={() => Setting.goToLinkSoft(this, silentSigninLink)}
|
onClick={() => Setting.goToLinkSoft(this, silentSigninLink)}
|
||||||
style={isSingle ? {width: "320px"} : {width: "100%"}}
|
style={isSingle ? {width: "320px", height: "100%"} : {width: "100%", height: "100%"}}
|
||||||
>
|
>
|
||||||
<Meta title={title} description={desc} />
|
<Meta title={title} description={desc} />
|
||||||
<br />
|
<br />
|
||||||
|
159
web/src/common/CaptchaModal.js
Normal file
159
web/src/common/CaptchaModal.js
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
// 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 {Button, Col, Input, Modal, Row} from "antd";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import React, {useEffect} from "react";
|
||||||
|
import * as UserBackend from "../backend/UserBackend";
|
||||||
|
import {CaptchaWidget} from "./CaptchaWidget";
|
||||||
|
import {SafetyOutlined} from "@ant-design/icons";
|
||||||
|
|
||||||
|
export const CaptchaModal = ({
|
||||||
|
owner,
|
||||||
|
name,
|
||||||
|
captchaType,
|
||||||
|
subType,
|
||||||
|
clientId,
|
||||||
|
clientId2,
|
||||||
|
clientSecret,
|
||||||
|
clientSecret2,
|
||||||
|
open,
|
||||||
|
onOk,
|
||||||
|
onCancel,
|
||||||
|
canCancel,
|
||||||
|
}) => {
|
||||||
|
const [visible, setVisible] = React.useState(false);
|
||||||
|
const [captchaImg, setCaptchaImg] = React.useState("");
|
||||||
|
const [captchaToken, setCaptchaToken] = React.useState("");
|
||||||
|
const [secret, setSecret] = React.useState(clientSecret);
|
||||||
|
const [secret2, setSecret2] = React.useState(clientSecret2);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setVisible(() => {
|
||||||
|
if (open) {
|
||||||
|
getCaptchaFromBackend();
|
||||||
|
} else {
|
||||||
|
cleanUp();
|
||||||
|
}
|
||||||
|
return open;
|
||||||
|
});
|
||||||
|
}, [open]);
|
||||||
|
|
||||||
|
const handleOk = () => {
|
||||||
|
onOk?.(captchaType, captchaToken, secret);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
onCancel?.();
|
||||||
|
};
|
||||||
|
|
||||||
|
const cleanUp = () => {
|
||||||
|
setCaptchaToken("");
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCaptchaFromBackend = () => {
|
||||||
|
UserBackend.getCaptcha(owner, name, true).then((res) => {
|
||||||
|
if (captchaType === "Default") {
|
||||||
|
setSecret(res.captchaId);
|
||||||
|
setCaptchaImg(res.captchaImage);
|
||||||
|
} else {
|
||||||
|
setSecret(res.clientSecret);
|
||||||
|
setSecret2(res.clientSecret2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderDefaultCaptcha = () => {
|
||||||
|
return (
|
||||||
|
<Col>
|
||||||
|
<Row
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url('data:image/png;base64,${captchaImg}')`,
|
||||||
|
backgroundRepeat: "no-repeat",
|
||||||
|
height: "80px",
|
||||||
|
width: "200px",
|
||||||
|
borderRadius: "5px",
|
||||||
|
border: "1px solid #ccc",
|
||||||
|
marginBottom: 10,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Row>
|
||||||
|
<Input
|
||||||
|
autoFocus
|
||||||
|
value={captchaToken}
|
||||||
|
prefix={<SafetyOutlined />}
|
||||||
|
placeholder={i18next.t("general:Captcha")}
|
||||||
|
onPressEnter={handleOk}
|
||||||
|
onChange={(e) => setCaptchaToken(e.target.value)}
|
||||||
|
/>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = (token) => {
|
||||||
|
setCaptchaToken(token);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCheck = () => {
|
||||||
|
if (captchaType === "Default") {
|
||||||
|
return renderDefaultCaptcha();
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<Col>
|
||||||
|
<Row>
|
||||||
|
<CaptchaWidget
|
||||||
|
captchaType={captchaType}
|
||||||
|
subType={subType}
|
||||||
|
siteKey={clientId}
|
||||||
|
clientSecret={secret}
|
||||||
|
onChange={onSubmit}
|
||||||
|
clientId2={clientId2}
|
||||||
|
clientSecret2={secret2}
|
||||||
|
/>
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderFooter = () => {
|
||||||
|
if (canCancel) {
|
||||||
|
return [
|
||||||
|
<Button key="cancel" onClick={handleCancel}>{i18next.t("user:Cancel")}</Button>,
|
||||||
|
<Button key="ok" type="primary" onClick={handleOk}>{i18next.t("user:OK")}</Button>,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
<Button key="ok" type="primary" onClick={handleOk}>{i18next.t("user:OK")}</Button>,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Modal
|
||||||
|
closable={false}
|
||||||
|
maskClosable={false}
|
||||||
|
destroyOnClose={true}
|
||||||
|
title={i18next.t("general:Captcha")}
|
||||||
|
visible={visible}
|
||||||
|
width={348}
|
||||||
|
footer={renderFooter()}
|
||||||
|
>
|
||||||
|
{renderCheck()}
|
||||||
|
</Modal>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
};
|
@ -12,13 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import {Button, Col, Input, Modal, Row} from "antd";
|
import {Button} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import * as UserBackend from "../backend/UserBackend";
|
import {CaptchaModal} from "./CaptchaModal";
|
||||||
import * as ProviderBackend from "../backend/ProviderBackend";
|
import * as ProviderBackend from "../backend/ProviderBackend";
|
||||||
import {SafetyOutlined} from "@ant-design/icons";
|
import * as UserBackend from "../backend/UserBackend";
|
||||||
import {CaptchaWidget} from "./CaptchaWidget";
|
|
||||||
|
|
||||||
export const CaptchaPreview = ({
|
export const CaptchaPreview = ({
|
||||||
provider,
|
provider,
|
||||||
@ -33,37 +32,9 @@ export const CaptchaPreview = ({
|
|||||||
clientId2,
|
clientId2,
|
||||||
clientSecret2,
|
clientSecret2,
|
||||||
}) => {
|
}) => {
|
||||||
const [visible, setVisible] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const [captchaImg, setCaptchaImg] = React.useState("");
|
|
||||||
const [captchaToken, setCaptchaToken] = React.useState("");
|
|
||||||
const [secret, setSecret] = React.useState(clientSecret);
|
|
||||||
const [secret2, setSecret2] = React.useState(clientSecret2);
|
|
||||||
|
|
||||||
const handleOk = () => {
|
|
||||||
UserBackend.verifyCaptcha(captchaType, captchaToken, secret).then(() => {
|
|
||||||
setCaptchaToken("");
|
|
||||||
setVisible(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
setVisible(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getCaptchaFromBackend = () => {
|
|
||||||
UserBackend.getCaptcha(owner, name, true).then((res) => {
|
|
||||||
if (captchaType === "Default") {
|
|
||||||
setSecret(res.captchaId);
|
|
||||||
setCaptchaImg(res.captchaImage);
|
|
||||||
} else {
|
|
||||||
setSecret(res.clientSecret);
|
|
||||||
setSecret2(res.clientSecret2);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const clickPreview = () => {
|
const clickPreview = () => {
|
||||||
setVisible(true);
|
|
||||||
provider.name = name;
|
provider.name = name;
|
||||||
provider.clientId = clientId;
|
provider.clientId = clientId;
|
||||||
provider.type = captchaType;
|
provider.type = captchaType;
|
||||||
@ -71,64 +42,10 @@ export const CaptchaPreview = ({
|
|||||||
if (clientSecret !== "***") {
|
if (clientSecret !== "***") {
|
||||||
provider.clientSecret = clientSecret;
|
provider.clientSecret = clientSecret;
|
||||||
ProviderBackend.updateProvider(owner, providerName, provider).then(() => {
|
ProviderBackend.updateProvider(owner, providerName, provider).then(() => {
|
||||||
getCaptchaFromBackend();
|
setOpen(true);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
getCaptchaFromBackend();
|
setOpen(true);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderDefaultCaptcha = () => {
|
|
||||||
return (
|
|
||||||
<Col>
|
|
||||||
<Row
|
|
||||||
style={{
|
|
||||||
backgroundImage: `url('data:image/png;base64,${captchaImg}')`,
|
|
||||||
backgroundRepeat: "no-repeat",
|
|
||||||
height: "80px",
|
|
||||||
width: "200px",
|
|
||||||
borderRadius: "5px",
|
|
||||||
border: "1px solid #ccc",
|
|
||||||
marginBottom: 10,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Row>
|
|
||||||
<Input
|
|
||||||
autoFocus
|
|
||||||
value={captchaToken}
|
|
||||||
prefix={<SafetyOutlined />}
|
|
||||||
placeholder={i18next.t("general:Captcha")}
|
|
||||||
onPressEnter={handleOk}
|
|
||||||
onChange={(e) => setCaptchaToken(e.target.value)}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
</Col>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit = (token) => {
|
|
||||||
setCaptchaToken(token);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderCheck = () => {
|
|
||||||
if (captchaType === "Default") {
|
|
||||||
return renderDefaultCaptcha();
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<Col>
|
|
||||||
<Row>
|
|
||||||
<CaptchaWidget
|
|
||||||
captchaType={captchaType}
|
|
||||||
subType={subType}
|
|
||||||
siteKey={clientId}
|
|
||||||
clientSecret={secret}
|
|
||||||
onChange={onSubmit}
|
|
||||||
clientId2={clientId2}
|
|
||||||
clientSecret2={secret2}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
</Col>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,6 +63,16 @@ export const CaptchaPreview = ({
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onOk = (captchaType, captchaToken, secret) => {
|
||||||
|
UserBackend.verifyCaptcha(captchaType, captchaToken, secret).then(() => {
|
||||||
|
setOpen(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Button
|
<Button
|
||||||
@ -156,20 +83,20 @@ export const CaptchaPreview = ({
|
|||||||
>
|
>
|
||||||
{i18next.t("general:Preview")}
|
{i18next.t("general:Preview")}
|
||||||
</Button>
|
</Button>
|
||||||
<Modal
|
<CaptchaModal
|
||||||
closable={false}
|
owner={owner}
|
||||||
maskClosable={false}
|
name={name}
|
||||||
destroyOnClose={true}
|
captchaType={captchaType}
|
||||||
title={i18next.t("general:Captcha")}
|
subType={subType}
|
||||||
visible={visible}
|
clientId={clientId}
|
||||||
okText={i18next.t("user:OK")}
|
clientId2={clientId2}
|
||||||
cancelText={i18next.t("user:Cancel")}
|
clientSecret={clientSecret}
|
||||||
onOk={handleOk}
|
clientSecret2={clientSecret2}
|
||||||
onCancel={handleCancel}
|
open={open}
|
||||||
width={348}
|
onOk={onOk}
|
||||||
>
|
onCancel={onCancel}
|
||||||
{renderCheck()}
|
canCancel={true}
|
||||||
</Modal>
|
/>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"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 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",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@ -35,10 +37,11 @@
|
|||||||
"Form CSS": "Form CSS",
|
"Form CSS": "Form CSS",
|
||||||
"Form CSS - Edit": "Form CSS - Edit",
|
"Form CSS - Edit": "Form CSS - Edit",
|
||||||
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
||||||
"From position": "From position",
|
"Form position": "Form position",
|
||||||
"From position - Tooltip": "From position - Tooltip",
|
"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",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Passwort AN",
|
"Password ON": "Passwort AN",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Aktualisierungs-Token läuft ab",
|
"Refresh token expire": "Aktualisierungs-Token läuft ab",
|
||||||
"Refresh token expire - Tooltip": "Aktualisierungs-Token läuft ab - Tooltip",
|
"Refresh token expire - Tooltip": "Aktualisierungs-Token läuft ab - Tooltip",
|
||||||
|
"Right": "Right",
|
||||||
"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 copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"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": "Anmeldesitzung",
|
"Signin session": "Anmeldesitzung",
|
||||||
"Signup items": "Artikel registrieren",
|
"Signup items": "Artikel registrieren",
|
||||||
@ -61,7 +68,9 @@
|
|||||||
"Token expire - Tooltip": "Token läuft ab - Tooltip",
|
"Token expire - Tooltip": "Token läuft ab - Tooltip",
|
||||||
"Token format": "Token-Format",
|
"Token format": "Token-Format",
|
||||||
"Token format - Tooltip": "Token-Format - Tooltip",
|
"Token format - Tooltip": "Token-Format - Tooltip",
|
||||||
"rule": "rule"
|
"Rule": "Rule",
|
||||||
|
"None": "None",
|
||||||
|
"Always": "Always"
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "Bitgröße",
|
"Bit size": "Bitgröße",
|
||||||
@ -688,6 +697,7 @@
|
|||||||
"Old Password": "Altes Passwort",
|
"Old Password": "Altes Passwort",
|
||||||
"Password": "Passwort",
|
"Password": "Passwort",
|
||||||
"Password Set": "Passwort setzen",
|
"Password Set": "Passwort setzen",
|
||||||
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Eigenschaften",
|
"Properties": "Eigenschaften",
|
||||||
"Re-enter New": "Neu erneut eingeben",
|
"Re-enter New": "Neu erneut eingeben",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"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 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",
|
||||||
"Enable signup - Tooltip": "Enable signup - Tooltip",
|
"Enable signup - Tooltip": "Enable signup - Tooltip",
|
||||||
@ -35,10 +37,11 @@
|
|||||||
"Form CSS": "Form CSS",
|
"Form CSS": "Form CSS",
|
||||||
"Form CSS - Edit": "Form CSS - Edit",
|
"Form CSS - Edit": "Form CSS - Edit",
|
||||||
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
||||||
"From position": "From position",
|
"Form position": "Form position",
|
||||||
"From position - Tooltip": "From position - Tooltip",
|
"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",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Password ON",
|
"Password ON": "Password ON",
|
||||||
"Password ON - Tooltip": "Password ON - Tooltip",
|
"Password ON - Tooltip": "Password ON - Tooltip",
|
||||||
@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "Redirect URLs - Tooltip",
|
"Redirect URLs - Tooltip": "Redirect URLs - Tooltip",
|
||||||
"Refresh token expire": "Refresh token expire",
|
"Refresh token expire": "Refresh token expire",
|
||||||
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
||||||
|
"Right": "Right",
|
||||||
"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 copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"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",
|
||||||
"Signup items": "Signup items",
|
"Signup items": "Signup items",
|
||||||
@ -61,7 +68,9 @@
|
|||||||
"Token expire - Tooltip": "Token expire - Tooltip",
|
"Token expire - Tooltip": "Token expire - Tooltip",
|
||||||
"Token format": "Token format",
|
"Token format": "Token format",
|
||||||
"Token format - Tooltip": "Token format - Tooltip",
|
"Token format - Tooltip": "Token format - Tooltip",
|
||||||
"rule": "rule"
|
"Rule": "Rule",
|
||||||
|
"None": "None",
|
||||||
|
"Always": "Always"
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "Bit size",
|
"Bit size": "Bit size",
|
||||||
@ -688,6 +697,7 @@
|
|||||||
"Old Password": "Old Password",
|
"Old Password": "Old Password",
|
||||||
"Password": "Password",
|
"Password": "Password",
|
||||||
"Password Set": "Password Set",
|
"Password Set": "Password Set",
|
||||||
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Properties",
|
"Properties": "Properties",
|
||||||
"Re-enter New": "Re-enter New",
|
"Re-enter New": "Re-enter New",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
|
@ -45,7 +45,9 @@
|
|||||||
"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",
|
||||||
"rule": "rule"
|
"Rule": "Rule",
|
||||||
|
"None": "None",
|
||||||
|
"Always": "Always"
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "Tamaño del Bit",
|
"Bit size": "Tamaño del Bit",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
"Enable WebAuthn signin - Tooltip": "Enable WebAuthn signin - Tooltip",
|
||||||
"Enable code signin": "Activer la connexion au code",
|
"Enable code signin": "Activer la connexion au code",
|
||||||
"Enable code signin - Tooltip": "Activer la connexion au code - infobulle",
|
"Enable code signin - Tooltip": "Activer la connexion au code - infobulle",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
|
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
|
||||||
"Enable signup": "Activer l'inscription",
|
"Enable signup": "Activer l'inscription",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@ -35,10 +37,11 @@
|
|||||||
"Form CSS": "Form CSS",
|
"Form CSS": "Form CSS",
|
||||||
"Form CSS - Edit": "Form CSS - Edit",
|
"Form CSS - Edit": "Form CSS - Edit",
|
||||||
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
||||||
"From position": "From position",
|
"Form position": "Form position",
|
||||||
"From position - Tooltip": "From position - Tooltip",
|
"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",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Mot de passe activé",
|
"Password ON": "Mot de passe activé",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Expiration du jeton d'actualisation",
|
"Refresh token expire": "Expiration du jeton d'actualisation",
|
||||||
"Refresh token expire - Tooltip": "Expiration du jeton d'actualisation - infobulle",
|
"Refresh token expire - Tooltip": "Expiration du jeton d'actualisation - infobulle",
|
||||||
|
"Right": "Right",
|
||||||
"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 copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"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": "Connexion à la session",
|
"Signin session": "Connexion à la session",
|
||||||
"Signup items": "Inscrire des éléments",
|
"Signup items": "Inscrire des éléments",
|
||||||
@ -61,7 +68,9 @@
|
|||||||
"Token expire - Tooltip": "Expiration du jeton - Info-bulle",
|
"Token expire - Tooltip": "Expiration du jeton - Info-bulle",
|
||||||
"Token format": "Format du jeton",
|
"Token format": "Format du jeton",
|
||||||
"Token format - Tooltip": "Format du jeton - infobulle",
|
"Token format - Tooltip": "Format du jeton - infobulle",
|
||||||
"rule": "rule"
|
"Rule": "Rule",
|
||||||
|
"None": "None",
|
||||||
|
"Always": "Always"
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "Taille du bit",
|
"Bit size": "Taille du bit",
|
||||||
@ -688,6 +697,7 @@
|
|||||||
"Old Password": "Ancien mot de passe",
|
"Old Password": "Ancien mot de passe",
|
||||||
"Password": "Mot de passe",
|
"Password": "Mot de passe",
|
||||||
"Password Set": "Mot de passe défini",
|
"Password Set": "Mot de passe défini",
|
||||||
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Propriétés",
|
"Properties": "Propriétés",
|
||||||
"Re-enter New": "Nouvelle entrée",
|
"Re-enter New": "Nouvelle entrée",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"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 - Tooltip": "Enable code signin - Tooltip",
|
"Enable code signin - Tooltip": "Enable code signin - 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": "サインアップを有効にする",
|
"Enable signup": "サインアップを有効にする",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@ -35,10 +37,11 @@
|
|||||||
"Form CSS": "Form CSS",
|
"Form CSS": "Form CSS",
|
||||||
"Form CSS - Edit": "Form CSS - Edit",
|
"Form CSS - Edit": "Form CSS - Edit",
|
||||||
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
||||||
"From position": "From position",
|
"Form position": "Form position",
|
||||||
"From position - Tooltip": "From position - Tooltip",
|
"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",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "パスワードON",
|
"Password ON": "パスワードON",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "トークンの更新の期限が切れます",
|
"Refresh token expire": "トークンの更新の期限が切れます",
|
||||||
"Refresh token expire - Tooltip": "トークンの有効期限を更新する - ツールチップ",
|
"Refresh token expire - Tooltip": "トークンの有効期限を更新する - ツールチップ",
|
||||||
|
"Right": "Right",
|
||||||
"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 copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"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": "サインインセッション",
|
||||||
"Signup items": "アイテムの登録",
|
"Signup items": "アイテムの登録",
|
||||||
@ -61,7 +68,9 @@
|
|||||||
"Token expire - Tooltip": "トークンの有効期限 - ツールチップ",
|
"Token expire - Tooltip": "トークンの有効期限 - ツールチップ",
|
||||||
"Token format": "トークンのフォーマット",
|
"Token format": "トークンのフォーマット",
|
||||||
"Token format - Tooltip": "トークンフォーマット - ツールチップ",
|
"Token format - Tooltip": "トークンフォーマット - ツールチップ",
|
||||||
"rule": "rule"
|
"Rule": "Rule",
|
||||||
|
"None": "None",
|
||||||
|
"Always": "Always"
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "ビットサイズ",
|
"Bit size": "ビットサイズ",
|
||||||
@ -688,6 +697,7 @@
|
|||||||
"Old Password": "古いパスワード",
|
"Old Password": "古いパスワード",
|
||||||
"Password": "パスワード",
|
"Password": "パスワード",
|
||||||
"Password Set": "パスワード設定",
|
"Password Set": "パスワード設定",
|
||||||
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "プロパティー",
|
"Properties": "プロパティー",
|
||||||
"Re-enter New": "新しい入力",
|
"Re-enter New": "新しい入力",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
"Copy SAML metadata URL": "Copy SAML metadata URL",
|
||||||
"Copy prompt page URL": "Copy prompt page URL",
|
"Copy prompt page URL": "Copy prompt page URL",
|
||||||
"Copy signin page URL": "Copy signin page URL",
|
"Copy signin page URL": "Copy signin page URL",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"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 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",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@ -35,10 +37,11 @@
|
|||||||
"Form CSS": "Form CSS",
|
"Form CSS": "Form CSS",
|
||||||
"Form CSS - Edit": "Form CSS - Edit",
|
"Form CSS - Edit": "Form CSS - Edit",
|
||||||
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
||||||
"From position": "From position",
|
"Form position": "Form position",
|
||||||
"From position - Tooltip": "From position - Tooltip",
|
"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",
|
||||||
"New Application": "New Application",
|
"New Application": "New Application",
|
||||||
"Password ON": "Password ON",
|
"Password ON": "Password ON",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Refresh token expire",
|
"Refresh token expire": "Refresh token expire",
|
||||||
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
||||||
|
"Right": "Right",
|
||||||
"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 copied to clipboard successfully",
|
"SAML metadata URL copied to clipboard successfully": "SAML metadata URL copied to clipboard successfully",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"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",
|
||||||
"Signup items": "Signup items",
|
"Signup items": "Signup items",
|
||||||
@ -61,7 +68,9 @@
|
|||||||
"Token expire - Tooltip": "Token expire - Tooltip",
|
"Token expire - Tooltip": "Token expire - Tooltip",
|
||||||
"Token format": "Token format",
|
"Token format": "Token format",
|
||||||
"Token format - Tooltip": "Token format - Tooltip",
|
"Token format - Tooltip": "Token format - Tooltip",
|
||||||
"rule": "rule"
|
"Rule": "Rule",
|
||||||
|
"None": "None",
|
||||||
|
"Always": "Always"
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "Bit size",
|
"Bit size": "Bit size",
|
||||||
@ -688,6 +697,7 @@
|
|||||||
"Old Password": "Old Password",
|
"Old Password": "Old Password",
|
||||||
"Password": "Password",
|
"Password": "Password",
|
||||||
"Password Set": "Password Set",
|
"Password Set": "Password Set",
|
||||||
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Properties",
|
"Properties": "Properties",
|
||||||
"Re-enter New": "Re-enter New",
|
"Re-enter New": "Re-enter New",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
"Auto signin - Tooltip": "Auto signin - Tooltip",
|
||||||
"Background URL": "Background URL",
|
"Background URL": "Background URL",
|
||||||
"Background URL - Tooltip": "Background URL - Tooltip",
|
"Background URL - Tooltip": "Background URL - Tooltip",
|
||||||
|
"Center": "Center",
|
||||||
"Copy SAML metadata URL": "Копировать адрес метаданных SAML",
|
"Copy SAML metadata URL": "Копировать адрес метаданных SAML",
|
||||||
"Copy prompt page URL": "Скопировать URL-адрес страницы запроса",
|
"Copy prompt page URL": "Скопировать URL-адрес страницы запроса",
|
||||||
"Copy signin page URL": "Скопировать URL-адрес страницы входа",
|
"Copy signin page URL": "Скопировать URL-адрес страницы входа",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"Enable WebAuthn signin - Tooltip": "Включить вход с WebAuthn - Подсказка",
|
"Enable WebAuthn signin - Tooltip": "Включить вход с WebAuthn - Подсказка",
|
||||||
"Enable code signin": "Включить кодовый вход",
|
"Enable code signin": "Включить кодовый вход",
|
||||||
"Enable code signin - Tooltip": "Включить вход с кодом - Tooltip",
|
"Enable code signin - Tooltip": "Включить вход с кодом - Tooltip",
|
||||||
|
"Enable side panel": "Enable side panel",
|
||||||
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
|
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
|
||||||
"Enable signup": "Включить регистрацию",
|
"Enable signup": "Включить регистрацию",
|
||||||
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
"Enable signup - Tooltip": "Whether to allow users to sign up",
|
||||||
@ -35,10 +37,11 @@
|
|||||||
"Form CSS": "Form CSS",
|
"Form CSS": "Form CSS",
|
||||||
"Form CSS - Edit": "Form CSS - Edit",
|
"Form CSS - Edit": "Form CSS - Edit",
|
||||||
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
"Form CSS - Tooltip": "Form CSS - Tooltip",
|
||||||
"From position": "From position",
|
"Form position": "Form position",
|
||||||
"From position - Tooltip": "From position - Tooltip",
|
"Form position - Tooltip": "Form position - Tooltip",
|
||||||
"Grant types": "Виды грантов",
|
"Grant types": "Виды грантов",
|
||||||
"Grant types - Tooltip": "Виды грантов - Подсказка",
|
"Grant types - Tooltip": "Виды грантов - Подсказка",
|
||||||
|
"Left": "Left",
|
||||||
"New Application": "Новое приложение",
|
"New Application": "Новое приложение",
|
||||||
"Password ON": "Пароль ВКЛ",
|
"Password ON": "Пароль ВКЛ",
|
||||||
"Password ON - Tooltip": "Whether to allow password login",
|
"Password ON - Tooltip": "Whether to allow password login",
|
||||||
@ -49,9 +52,13 @@
|
|||||||
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
"Redirect URLs - Tooltip": "List of redirect addresses after successful login",
|
||||||
"Refresh token expire": "Срок действия обновления токена истекает",
|
"Refresh token expire": "Срок действия обновления токена истекает",
|
||||||
"Refresh token expire - Tooltip": "Срок обновления токена истекает - Подсказка",
|
"Refresh token expire - Tooltip": "Срок обновления токена истекает - Подсказка",
|
||||||
|
"Right": "Right",
|
||||||
"SAML metadata": "Метаданные SAML",
|
"SAML metadata": "Метаданные SAML",
|
||||||
"SAML metadata - Tooltip": "Метаданные SAML - Подсказка",
|
"SAML metadata - Tooltip": "Метаданные SAML - Подсказка",
|
||||||
"SAML metadata URL copied to clipboard successfully": "Адрес метаданных SAML скопирован в буфер обмена",
|
"SAML metadata URL copied to clipboard successfully": "Адрес метаданных SAML скопирован в буфер обмена",
|
||||||
|
"Side panel HTML": "Side panel HTML",
|
||||||
|
"Side panel HTML - Edit": "Side panel HTML - Edit",
|
||||||
|
"Side panel HTML - Tooltip": "Side panel HTML - Tooltip",
|
||||||
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL страницы входа успешно скопирован в буфер обмена, пожалуйста, вставьте его в окно инкогнито или другой браузер",
|
"Signin page URL copied to clipboard successfully, please paste it into the incognito window or another browser": "URL страницы входа успешно скопирован в буфер обмена, пожалуйста, вставьте его в окно инкогнито или другой браузер",
|
||||||
"Signin session": "Сессия входа",
|
"Signin session": "Сессия входа",
|
||||||
"Signup items": "Элементы регистрации",
|
"Signup items": "Элементы регистрации",
|
||||||
@ -61,7 +68,9 @@
|
|||||||
"Token expire - Tooltip": "Истек токен - Подсказка",
|
"Token expire - Tooltip": "Истек токен - Подсказка",
|
||||||
"Token format": "Формат токена",
|
"Token format": "Формат токена",
|
||||||
"Token format - Tooltip": "Формат токена - Подсказка",
|
"Token format - Tooltip": "Формат токена - Подсказка",
|
||||||
"rule": "правило"
|
"Rule": "правило",
|
||||||
|
"None": "None",
|
||||||
|
"Always": "Always"
|
||||||
},
|
},
|
||||||
"cert": {
|
"cert": {
|
||||||
"Bit size": "Размер бита",
|
"Bit size": "Размер бита",
|
||||||
@ -688,6 +697,7 @@
|
|||||||
"Old Password": "Старый пароль",
|
"Old Password": "Старый пароль",
|
||||||
"Password": "Пароль",
|
"Password": "Пароль",
|
||||||
"Password Set": "Пароль установлен",
|
"Password Set": "Пароль установлен",
|
||||||
|
"Please select avatar from resources": "Please select avatar from resources",
|
||||||
"Properties": "Свойства",
|
"Properties": "Свойства",
|
||||||
"Re-enter New": "Введите еще раз",
|
"Re-enter New": "Введите еще раз",
|
||||||
"Reset Email...": "Reset Email...",
|
"Reset Email...": "Reset Email...",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user