mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-16 06:23:50 +08:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
b8e324cadf | |||
f37fd6ba87 | |||
b4bf734fe8 | |||
f0431701c9 | |||
aa5078de15 | |||
9a324b2cca | |||
919eaf1df4 |
@ -98,7 +98,7 @@ For casdoor, if you have any questions, you can give Issues, or you can also dir
|
|||||||
|
|
||||||
### I18n translation
|
### I18n translation
|
||||||
|
|
||||||
If you are contributing to casdoor, please note that we use [Crowdin](https://crowdin.com/project/casdoor-web) as translating platform and i18next as translating tool. When you add some words using i18next in the ```web/``` directory, please remember to add what you have added to the ```web/src/locales/en/data.json``` file.
|
If you are contributing to casdoor, please note that we use [Crowdin](https://crowdin.com/project/casdoor-site) as translating platform and i18next as translating tool. When you add some words using i18next in the ```web/``` directory, please remember to add what you have added to the ```web/src/locales/en/data.json``` file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,6 +165,8 @@ func (c *ApiController) GetOAuthCode() {
|
|||||||
// @Param client_secret query string true "OAuth client secret"
|
// @Param client_secret query string true "OAuth client secret"
|
||||||
// @Param code query string true "OAuth code"
|
// @Param code query string true "OAuth code"
|
||||||
// @Success 200 {object} object.TokenWrapper The Response object
|
// @Success 200 {object} object.TokenWrapper The Response object
|
||||||
|
// @Success 400 {object} object.TokenError The Response object
|
||||||
|
// @Success 401 {object} object.TokenError The Response object
|
||||||
// @router /login/oauth/access_token [post]
|
// @router /login/oauth/access_token [post]
|
||||||
func (c *ApiController) GetOAuthToken() {
|
func (c *ApiController) GetOAuthToken() {
|
||||||
grantType := c.Input().Get("grant_type")
|
grantType := c.Input().Get("grant_type")
|
||||||
@ -200,6 +202,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.SetTokenErrorHttpStatus()
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +216,8 @@ func (c *ApiController) GetOAuthToken() {
|
|||||||
// @Param client_id query string true "OAuth client id"
|
// @Param client_id query string true "OAuth client id"
|
||||||
// @Param client_secret query string false "OAuth client secret"
|
// @Param client_secret query string false "OAuth client secret"
|
||||||
// @Success 200 {object} object.TokenWrapper The Response object
|
// @Success 200 {object} object.TokenWrapper The Response object
|
||||||
|
// @Success 400 {object} object.TokenError The Response object
|
||||||
|
// @Success 401 {object} object.TokenError The Response object
|
||||||
// @router /login/oauth/refresh_token [post]
|
// @router /login/oauth/refresh_token [post]
|
||||||
func (c *ApiController) RefreshToken() {
|
func (c *ApiController) RefreshToken() {
|
||||||
grantType := c.Input().Get("grant_type")
|
grantType := c.Input().Get("grant_type")
|
||||||
@ -235,6 +240,7 @@ func (c *ApiController) RefreshToken() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.Data["json"] = object.RefreshToken(grantType, refreshToken, scope, clientId, clientSecret, host)
|
c.Data["json"] = object.RefreshToken(grantType, refreshToken, scope, clientId, clientSecret, host)
|
||||||
|
c.SetTokenErrorHttpStatus()
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,6 +276,8 @@ func (c *ApiController) TokenLogout() {
|
|||||||
// @Param token formData string true "access_token's value or refresh_token's value"
|
// @Param token formData string true "access_token's value or refresh_token's value"
|
||||||
// @Param token_type_hint formData string true "the token type access_token or refresh_token"
|
// @Param token_type_hint formData string true "the token type access_token or refresh_token"
|
||||||
// @Success 200 {object} object.IntrospectionResponse The Response object
|
// @Success 200 {object} object.IntrospectionResponse The Response object
|
||||||
|
// @Success 400 {object} object.TokenError The Response object
|
||||||
|
// @Success 401 {object} object.TokenError The Response object
|
||||||
// @router /login/oauth/introspect [post]
|
// @router /login/oauth/introspect [post]
|
||||||
func (c *ApiController) IntrospectToken() {
|
func (c *ApiController) IntrospectToken() {
|
||||||
tokenValue := c.Input().Get("token")
|
tokenValue := c.Input().Get("token")
|
||||||
@ -279,12 +287,21 @@ func (c *ApiController) IntrospectToken() {
|
|||||||
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("empty clientId or clientSecret")
|
||||||
|
c.Data["json"] = &object.TokenError{
|
||||||
|
Error: object.INVALID_REQUEST,
|
||||||
|
}
|
||||||
|
c.SetTokenErrorHttpStatus()
|
||||||
|
c.ServeJSON()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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("invalid application or wrong clientSecret")
|
||||||
|
c.Data["json"] = &object.TokenError{
|
||||||
|
Error: object.INVALID_CLIENT,
|
||||||
|
}
|
||||||
|
c.SetTokenErrorHttpStatus()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
token := object.GetTokenByTokenAndApplication(tokenValue, application.Name)
|
token := object.GetTokenByTokenAndApplication(tokenValue, application.Name)
|
||||||
|
@ -51,6 +51,23 @@ func (c *ApiController) ResponseError(error string, data ...interface{}) {
|
|||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTokenErrorHttpStatus ...
|
||||||
|
func (c *ApiController) SetTokenErrorHttpStatus() {
|
||||||
|
_, ok := c.Data["json"].(*object.TokenError)
|
||||||
|
if ok {
|
||||||
|
if c.Data["json"].(*object.TokenError).Error == object.INVALID_CLIENT {
|
||||||
|
c.Ctx.Output.SetStatus(401)
|
||||||
|
c.Ctx.Output.Header("WWW-Authenticate", "Basic realm=\"OAuth2\"")
|
||||||
|
} else {
|
||||||
|
c.Ctx.Output.SetStatus(400)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, ok = c.Data["json"].(*object.TokenWrapper)
|
||||||
|
if ok {
|
||||||
|
c.Ctx.Output.SetStatus(200)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RequireSignedIn ...
|
// RequireSignedIn ...
|
||||||
func (c *ApiController) RequireSignedIn() (string, bool) {
|
func (c *ApiController) RequireSignedIn() (string, bool) {
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
|
2
go.mod
2
go.mod
@ -11,7 +11,7 @@ require (
|
|||||||
github.com/casbin/casbin/v2 v2.30.1
|
github.com/casbin/casbin/v2 v2.30.1
|
||||||
github.com/casbin/xorm-adapter/v2 v2.5.1
|
github.com/casbin/xorm-adapter/v2 v2.5.1
|
||||||
github.com/casdoor/go-sms-sender v0.2.0
|
github.com/casdoor/go-sms-sender v0.2.0
|
||||||
github.com/casdoor/goth v1.69.0-FIX1
|
github.com/casdoor/goth v1.69.0-FIX2
|
||||||
github.com/casdoor/oss v1.2.0
|
github.com/casdoor/oss v1.2.0
|
||||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
||||||
|
4
go.sum
4
go.sum
@ -100,8 +100,8 @@ github.com/casbin/xorm-adapter/v2 v2.5.1 h1:BkpIxRHKa0s3bSMx173PpuU7oTs+Zw7XmD0B
|
|||||||
github.com/casbin/xorm-adapter/v2 v2.5.1/go.mod h1:AeH4dBKHC9/zYxzdPVHhPDzF8LYLqjDdb767CWJoV54=
|
github.com/casbin/xorm-adapter/v2 v2.5.1/go.mod h1:AeH4dBKHC9/zYxzdPVHhPDzF8LYLqjDdb767CWJoV54=
|
||||||
github.com/casdoor/go-sms-sender v0.2.0 h1:52bin4EBOPzOee64s9UK7jxd22FODvT9/+Y/Z+PSHpg=
|
github.com/casdoor/go-sms-sender v0.2.0 h1:52bin4EBOPzOee64s9UK7jxd22FODvT9/+Y/Z+PSHpg=
|
||||||
github.com/casdoor/go-sms-sender v0.2.0/go.mod h1:fsZsNnALvFIo+HFcE1U/oCQv4ZT42FdglXKMsEm3WSk=
|
github.com/casdoor/go-sms-sender v0.2.0/go.mod h1:fsZsNnALvFIo+HFcE1U/oCQv4ZT42FdglXKMsEm3WSk=
|
||||||
github.com/casdoor/goth v1.69.0-FIX1 h1:24Y3tfaJxWGJbxickGe3F9y2c8X1PgsQynhxGXV1f9Q=
|
github.com/casdoor/goth v1.69.0-FIX2 h1:RgfIMkL9kekylgxHHK2ZY8ASAwOGns2HVlaBwLu7Bcs=
|
||||||
github.com/casdoor/goth v1.69.0-FIX1/go.mod h1:Om55nRo8CkeDkPSNBbzXW4G5uI28ZUkSk5S69dPek3s=
|
github.com/casdoor/goth v1.69.0-FIX2/go.mod h1:Om55nRo8CkeDkPSNBbzXW4G5uI28ZUkSk5S69dPek3s=
|
||||||
github.com/casdoor/oss v1.2.0 h1:ozLAE+nnNdFQBWbzH8U9spzaO8h8NrB57lBcdyMUUQ8=
|
github.com/casdoor/oss v1.2.0 h1:ozLAE+nnNdFQBWbzH8U9spzaO8h8NrB57lBcdyMUUQ8=
|
||||||
github.com/casdoor/oss v1.2.0/go.mod h1:qii35VBuxnR/uEuYSKpS0aJ8htQFOcCVsZ4FHgHLuss=
|
github.com/casdoor/oss v1.2.0/go.mod h1:qii35VBuxnR/uEuYSKpS0aJ8htQFOcCVsZ4FHgHLuss=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
@ -51,6 +51,10 @@ func downloadFile(url string) (*bytes.Buffer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getPermanentAvatarUrl(organization string, username string, url string) string {
|
func getPermanentAvatarUrl(organization string, username string, url string) string {
|
||||||
|
if url == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
if defaultStorageProvider == nil {
|
if defaultStorageProvider == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
230
object/token.go
230
object/token.go
@ -17,7 +17,6 @@ package object
|
|||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -29,6 +28,13 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
hourSeconds = 3600
|
hourSeconds = 3600
|
||||||
|
INVALID_REQUEST = "invalid_request"
|
||||||
|
INVALID_CLIENT = "invalid_client"
|
||||||
|
INVALID_GRANT = "invalid_grant"
|
||||||
|
UNAUTHORIZED_CLIENT = "unauthorized_client"
|
||||||
|
UNSUPPORTED_GRANT_TYPE = "unsupported_grant_type"
|
||||||
|
INVALID_SCOPE = "invalid_scope"
|
||||||
|
ENDPOINT_ERROR = "endpoint_error"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Code struct {
|
type Code struct {
|
||||||
@ -63,7 +69,11 @@ type TokenWrapper struct {
|
|||||||
TokenType string `json:"token_type"`
|
TokenType string `json:"token_type"`
|
||||||
ExpiresIn int `json:"expires_in"`
|
ExpiresIn int `json:"expires_in"`
|
||||||
Scope string `json:"scope"`
|
Scope string `json:"scope"`
|
||||||
Error string `json:"error,omitempty"`
|
}
|
||||||
|
|
||||||
|
type TokenError struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
ErrorDescription string `json:"error_description,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IntrospectionResponse struct {
|
type IntrospectionResponse struct {
|
||||||
@ -311,59 +321,42 @@ 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) *TokenWrapper {
|
|
||||||
var errString string
|
|
||||||
application := GetApplicationByClientId(clientId)
|
application := GetApplicationByClientId(clientId)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
errString = "error: invalid client_id"
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: INVALID_CLIENT,
|
||||||
AccessToken: errString,
|
ErrorDescription: "client_id is invalid",
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if grantType is allowed in the current application
|
//Check if grantType is allowed in the current application
|
||||||
|
|
||||||
if !IsGrantTypeValid(grantType, application.GrantTypes) && tag == "" {
|
if !IsGrantTypeValid(grantType, application.GrantTypes) && tag == "" {
|
||||||
errString = fmt.Sprintf("error: grant_type: %s is not supported in this application", grantType)
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: UNSUPPORTED_GRANT_TYPE,
|
||||||
AccessToken: errString,
|
ErrorDescription: fmt.Sprintf("grant_type: %s is not supported in this application", grantType),
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var token *Token
|
var token *Token
|
||||||
var err error
|
var tokenError *TokenError
|
||||||
switch grantType {
|
switch grantType {
|
||||||
case "authorization_code": // Authorization Code Grant
|
case "authorization_code": // Authorization Code Grant
|
||||||
token, err = GetAuthorizationCodeToken(application, clientSecret, code, verifier)
|
token, tokenError = GetAuthorizationCodeToken(application, clientSecret, code, verifier)
|
||||||
case "password": // Resource Owner Password Credentials Grant
|
case "password": // Resource Owner Password Credentials Grant
|
||||||
token, err = GetPasswordToken(application, username, password, scope, host)
|
token, tokenError = GetPasswordToken(application, username, password, scope, host)
|
||||||
case "client_credentials": // Client Credentials Grant
|
case "client_credentials": // Client Credentials Grant
|
||||||
token, err = GetClientCredentialsToken(application, clientSecret, scope, host)
|
token, tokenError = GetClientCredentialsToken(application, clientSecret, scope, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tag == "wechat_miniprogram" {
|
if tag == "wechat_miniprogram" {
|
||||||
// Wechat Mini Program
|
// Wechat Mini Program
|
||||||
token, err = GetWechatMiniProgramToken(application, code, host, username, avatar)
|
token, tokenError = GetWechatMiniProgramToken(application, code, host, username, avatar)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if tokenError != nil {
|
||||||
errString = err.Error()
|
return tokenError
|
||||||
return &TokenWrapper{
|
|
||||||
AccessToken: errString,
|
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
token.CodeIsUsed = true
|
token.CodeIsUsed = true
|
||||||
@ -380,81 +373,59 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
|||||||
return tokenWrapper
|
return tokenWrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
func RefreshToken(grantType string, refreshToken string, scope string, clientId string, clientSecret string, host string) *TokenWrapper {
|
func RefreshToken(grantType string, refreshToken string, scope string, clientId string, clientSecret string, host string) interface{} {
|
||||||
var errString string
|
|
||||||
// check parameters
|
// check parameters
|
||||||
if grantType != "refresh_token" {
|
if grantType != "refresh_token" {
|
||||||
errString = "error: grant_type should be \"refresh_token\""
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: UNSUPPORTED_GRANT_TYPE,
|
||||||
AccessToken: errString,
|
ErrorDescription: "grant_type should be refresh_token",
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
application := GetApplicationByClientId(clientId)
|
application := GetApplicationByClientId(clientId)
|
||||||
if application == nil {
|
if application == nil {
|
||||||
errString = "error: invalid client_id"
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: INVALID_CLIENT,
|
||||||
AccessToken: errString,
|
ErrorDescription: "client_id is invalid",
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if clientSecret != "" && application.ClientSecret != clientSecret {
|
if clientSecret != "" && application.ClientSecret != clientSecret {
|
||||||
errString = "error: invalid client_secret"
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: INVALID_CLIENT,
|
||||||
AccessToken: errString,
|
ErrorDescription: "client_secret is invalid",
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check whether the refresh token is valid, and has not expired.
|
// check whether the refresh token is valid, and has not expired.
|
||||||
token := Token{RefreshToken: refreshToken}
|
token := Token{RefreshToken: refreshToken}
|
||||||
existed, err := adapter.Engine.Get(&token)
|
existed, err := adapter.Engine.Get(&token)
|
||||||
if err != nil || !existed {
|
if err != nil || !existed {
|
||||||
errString = "error: invalid refresh_token"
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: INVALID_GRANT,
|
||||||
AccessToken: errString,
|
ErrorDescription: "refresh token is invalid, expired or revoked",
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cert := getCertByApplication(application)
|
cert := getCertByApplication(application)
|
||||||
_, err = ParseJwtToken(refreshToken, cert)
|
_, err = ParseJwtToken(refreshToken, cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errString := fmt.Sprintf("error: %s", err.Error())
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: INVALID_GRANT,
|
||||||
AccessToken: errString,
|
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// generate a new token
|
// generate a new token
|
||||||
user := getUser(application.Organization, token.User)
|
user := getUser(application.Organization, token.User)
|
||||||
if user.IsForbidden {
|
if user.IsForbidden {
|
||||||
errString = "error: the user is forbidden to sign in, please contact the administrator"
|
return &TokenError{
|
||||||
return &TokenWrapper{
|
Error: INVALID_GRANT,
|
||||||
AccessToken: errString,
|
ErrorDescription: "the user is forbidden to sign in, please contact the administrator",
|
||||||
TokenType: "",
|
|
||||||
ExpiresIn: 0,
|
|
||||||
Scope: "",
|
|
||||||
Error: errString,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newAccessToken, newRefreshToken, err := generateJwtToken(application, user, "", scope, host)
|
newAccessToken, newRefreshToken, err := generateJwtToken(application, user, "", scope, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return &TokenError{
|
||||||
|
Error: ENDPOINT_ERROR,
|
||||||
|
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newToken := &Token{
|
newToken := &Token{
|
||||||
@ -508,63 +479,99 @@ func IsGrantTypeValid(method string, grantTypes []string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Authorization code flow
|
// Authorization code flow
|
||||||
func GetAuthorizationCodeToken(application *Application, clientSecret string, code string, verifier string) (*Token, error) {
|
func GetAuthorizationCodeToken(application *Application, clientSecret string, code string, verifier string) (*Token, *TokenError) {
|
||||||
if code == "" {
|
if code == "" {
|
||||||
return nil, errors.New("error: authorization code should not be empty")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_REQUEST,
|
||||||
|
ErrorDescription: "authorization code should not be empty",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
token := getTokenByCode(code)
|
token := getTokenByCode(code)
|
||||||
if token == nil {
|
if token == nil {
|
||||||
return nil, errors.New("error: invalid authorization code")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "authorization code is invalid",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if token.CodeIsUsed {
|
if token.CodeIsUsed {
|
||||||
// anti replay attacks
|
// anti replay attacks
|
||||||
return nil, errors.New("error: authorization code has been used")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "authorization code has been used",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if token.CodeChallenge != "" && pkceChallenge(verifier) != token.CodeChallenge {
|
if token.CodeChallenge != "" && pkceChallenge(verifier) != token.CodeChallenge {
|
||||||
return nil, errors.New("error: incorrect code_verifier")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "verifier is invalid",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.ClientSecret != clientSecret {
|
if application.ClientSecret != clientSecret {
|
||||||
// when using PKCE, the Client Secret can be empty,
|
// when using PKCE, the Client Secret can be empty,
|
||||||
// but if it is provided, it must be accurate.
|
// but if it is provided, it must be accurate.
|
||||||
if token.CodeChallenge == "" {
|
if token.CodeChallenge == "" {
|
||||||
return nil, errors.New("error: invalid client_secret")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_CLIENT,
|
||||||
|
ErrorDescription: "client_secret is invalid",
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if clientSecret != "" {
|
if clientSecret != "" {
|
||||||
return nil, errors.New("error: invalid client_secret")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_CLIENT,
|
||||||
|
ErrorDescription: "client_secret is invalid",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.Name != token.Application {
|
if application.Name != token.Application {
|
||||||
return nil, errors.New("error: the token is for wrong application (client_id)")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "the token is for wrong application (client_id)",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Now().Unix() > token.CodeExpireIn {
|
if time.Now().Unix() > token.CodeExpireIn {
|
||||||
// code must be used within 5 minutes
|
// code must be used within 5 minutes
|
||||||
return nil, errors.New("error: authorization code has expired")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "authorization code has expired",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resource Owner Password Credentials flow
|
// Resource Owner Password Credentials flow
|
||||||
func GetPasswordToken(application *Application, username string, password string, scope string, host string) (*Token, error) {
|
func GetPasswordToken(application *Application, username string, password string, scope string, host string) (*Token, *TokenError) {
|
||||||
user := getUser(application.Organization, username)
|
user := getUser(application.Organization, username)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return nil, errors.New("error: the user does not exist")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "the user does not exist",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
msg := CheckPassword(user, password)
|
msg := CheckPassword(user, password)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
return nil, errors.New("error: invalid username or password")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "invalid username or password",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if user.IsForbidden {
|
if user.IsForbidden {
|
||||||
return nil, errors.New("error: the user is forbidden to sign in, please contact the administrator")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "the user is forbidden to sign in, please contact the administrator",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
accessToken, refreshToken, err := generateJwtToken(application, user, "", scope, host)
|
accessToken, refreshToken, err := generateJwtToken(application, user, "", scope, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, &TokenError{
|
||||||
|
Error: ENDPOINT_ERROR,
|
||||||
|
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
token := &Token{
|
token := &Token{
|
||||||
Owner: application.Owner,
|
Owner: application.Owner,
|
||||||
@ -586,9 +593,12 @@ func GetPasswordToken(application *Application, username string, password string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Client Credentials flow
|
// Client Credentials flow
|
||||||
func GetClientCredentialsToken(application *Application, clientSecret string, scope string, host string) (*Token, error) {
|
func GetClientCredentialsToken(application *Application, clientSecret string, scope string, host string) (*Token, *TokenError) {
|
||||||
if application.ClientSecret != clientSecret {
|
if application.ClientSecret != clientSecret {
|
||||||
return nil, errors.New("error: invalid client_secret")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_CLIENT,
|
||||||
|
ErrorDescription: "client_secret is invalid",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nullUser := &User{
|
nullUser := &User{
|
||||||
Owner: application.Owner,
|
Owner: application.Owner,
|
||||||
@ -597,7 +607,10 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
|
|||||||
}
|
}
|
||||||
accessToken, _, err := generateJwtToken(application, nullUser, "", scope, host)
|
accessToken, _, err := generateJwtToken(application, nullUser, "", scope, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, &TokenError{
|
||||||
|
Error: ENDPOINT_ERROR,
|
||||||
|
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
token := &Token{
|
token := &Token{
|
||||||
Owner: application.Owner,
|
Owner: application.Owner,
|
||||||
@ -643,25 +656,37 @@ func GetTokenByUser(application *Application, user *User, scope string, host str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wechat Mini Program flow
|
// Wechat Mini Program flow
|
||||||
func GetWechatMiniProgramToken(application *Application, code string, host string, username string, avatar string) (*Token, error) {
|
func GetWechatMiniProgramToken(application *Application, code string, host string, username string, avatar string) (*Token, *TokenError) {
|
||||||
mpProvider := GetWechatMiniProgramProvider(application)
|
mpProvider := GetWechatMiniProgramProvider(application)
|
||||||
if mpProvider == nil {
|
if mpProvider == nil {
|
||||||
return nil, errors.New("error: the application does not support wechat mini program")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_CLIENT,
|
||||||
|
ErrorDescription: "the application does not support wechat mini program",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
provider := GetProvider(util.GetId(mpProvider.Name))
|
provider := GetProvider(util.GetId(mpProvider.Name))
|
||||||
mpIdp := idp.NewWeChatMiniProgramIdProvider(provider.ClientId, provider.ClientSecret)
|
mpIdp := idp.NewWeChatMiniProgramIdProvider(provider.ClientId, provider.ClientSecret)
|
||||||
session, err := mpIdp.GetSessionByCode(code)
|
session, err := mpIdp.GetSessionByCode(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: fmt.Sprintf("get wechat mini program session error: %s", err.Error()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
openId, unionId := session.Openid, session.Unionid
|
openId, unionId := session.Openid, session.Unionid
|
||||||
if openId == "" && unionId == "" {
|
if openId == "" && unionId == "" {
|
||||||
return nil, errors.New("err: WeChat's openid and unionid are empty")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_REQUEST,
|
||||||
|
ErrorDescription: "the wechat mini program session is invalid",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
user := getUserByWechatId(openId, unionId)
|
user := getUserByWechatId(openId, unionId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
if !application.EnableSignUp {
|
if !application.EnableSignUp {
|
||||||
return nil, errors.New("err: the application does not allow to sign up new account")
|
return nil, &TokenError{
|
||||||
|
Error: INVALID_GRANT,
|
||||||
|
ErrorDescription: "the application does not allow to sign up new account",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Add new user
|
//Add new user
|
||||||
var name string
|
var name string
|
||||||
@ -691,7 +716,10 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
|
|||||||
|
|
||||||
accessToken, refreshToken, err := generateJwtToken(application, user, "", "", host)
|
accessToken, refreshToken, err := generateJwtToken(application, user, "", "", host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, &TokenError{
|
||||||
|
Error: ENDPOINT_ERROR,
|
||||||
|
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
token := &Token{
|
token := &Token{
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
|
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package routers
|
package routers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/astaxie/beego/context"
|
"github.com/astaxie/beego/context"
|
||||||
|
"github.com/casdoor/casdoor/conf"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,17 +30,22 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func CorsFilter(ctx *context.Context) {
|
func CorsFilter(ctx *context.Context) {
|
||||||
if ctx.Input.Method() == "OPTIONS" {
|
|
||||||
origin := ctx.Input.Header(headerOrigin)
|
origin := ctx.Input.Header(headerOrigin)
|
||||||
|
originConf := conf.GetConfigString("origin")
|
||||||
|
|
||||||
|
if origin != "" && originConf != "" && origin != originConf {
|
||||||
if object.IsAllowOrigin(origin) {
|
if object.IsAllowOrigin(origin) {
|
||||||
ctx.Output.Header(headerAllowOrigin, origin)
|
ctx.Output.Header(headerAllowOrigin, origin)
|
||||||
ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS")
|
ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS")
|
||||||
ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization")
|
ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization")
|
||||||
ctx.ResponseWriter.WriteHeader(http.StatusOK)
|
|
||||||
} else {
|
} else {
|
||||||
ctx.ResponseWriter.WriteHeader(http.StatusForbidden)
|
ctx.ResponseWriter.WriteHeader(http.StatusForbidden)
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.Input.Method() == "OPTIONS" {
|
||||||
|
ctx.ResponseWriter.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2194,6 +2194,18 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/object.TokenWrapper"
|
"$ref": "#/definitions/object.TokenWrapper"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.TokenError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.TokenError"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2285,6 +2297,18 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/object.IntrospectionResponse"
|
"$ref": "#/definitions/object.IntrospectionResponse"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.TokenError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.TokenError"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2377,6 +2401,18 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/object.TokenWrapper"
|
"$ref": "#/definitions/object.TokenWrapper"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.TokenError"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/object.TokenError"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3063,11 +3099,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"2200.0xc0003c4b70.false": {
|
"2127.0xc000398090.false": {
|
||||||
"title": "false",
|
"title": "false",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"2235.0xc0003c4ba0.false": {
|
"2161.0xc0003980c0.false": {
|
||||||
"title": "false",
|
"title": "false",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
@ -3082,6 +3118,9 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"provider": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"receivers": {
|
"receivers": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@ -3182,10 +3221,10 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"$ref": "#/definitions/2200.0xc0003c4b70.false"
|
"$ref": "#/definitions/2127.0xc000398090.false"
|
||||||
},
|
},
|
||||||
"data2": {
|
"data2": {
|
||||||
"$ref": "#/definitions/2235.0xc0003c4ba0.false"
|
"$ref": "#/definitions/2161.0xc0003980c0.false"
|
||||||
},
|
},
|
||||||
"msg": {
|
"msg": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -4209,6 +4248,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"object.TokenError": {
|
||||||
|
"title": "TokenError",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"error": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"error_description": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"object.TokenWrapper": {
|
"object.TokenWrapper": {
|
||||||
"title": "TokenWrapper",
|
"title": "TokenWrapper",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -4216,9 +4267,6 @@
|
|||||||
"access_token": {
|
"access_token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"error": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"expires_in": {
|
"expires_in": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64"
|
"format": "int64"
|
||||||
|
@ -1435,6 +1435,14 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/object.TokenWrapper'
|
$ref: '#/definitions/object.TokenWrapper'
|
||||||
|
"400":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.TokenError'
|
||||||
|
"401":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.TokenError'
|
||||||
/api/login/oauth/code:
|
/api/login/oauth/code:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -1497,6 +1505,14 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/object.IntrospectionResponse'
|
$ref: '#/definitions/object.IntrospectionResponse'
|
||||||
|
"400":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.TokenError'
|
||||||
|
"401":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.TokenError'
|
||||||
/api/login/oauth/logout:
|
/api/login/oauth/logout:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -1559,6 +1575,14 @@ paths:
|
|||||||
description: The Response object
|
description: The Response object
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/object.TokenWrapper'
|
$ref: '#/definitions/object.TokenWrapper'
|
||||||
|
"400":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.TokenError'
|
||||||
|
"401":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/object.TokenError'
|
||||||
/api/logout:
|
/api/logout:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -2005,10 +2029,10 @@ paths:
|
|||||||
- Verification API
|
- Verification API
|
||||||
operationId: ApiController.VerifyCaptcha
|
operationId: ApiController.VerifyCaptcha
|
||||||
definitions:
|
definitions:
|
||||||
2200.0xc0003c4b70.false:
|
2127.0xc000398090.false:
|
||||||
title: "false"
|
title: "false"
|
||||||
type: object
|
type: object
|
||||||
2235.0xc0003c4ba0.false:
|
2161.0xc0003980c0.false:
|
||||||
title: "false"
|
title: "false"
|
||||||
type: object
|
type: object
|
||||||
Response:
|
Response:
|
||||||
@ -2020,6 +2044,8 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
content:
|
content:
|
||||||
type: string
|
type: string
|
||||||
|
provider:
|
||||||
|
type: string
|
||||||
receivers:
|
receivers:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
@ -2087,9 +2113,9 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
data:
|
data:
|
||||||
$ref: '#/definitions/2200.0xc0003c4b70.false'
|
$ref: '#/definitions/2127.0xc000398090.false'
|
||||||
data2:
|
data2:
|
||||||
$ref: '#/definitions/2235.0xc0003c4ba0.false'
|
$ref: '#/definitions/2161.0xc0003980c0.false'
|
||||||
msg:
|
msg:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
@ -2776,14 +2802,20 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
type: string
|
type: string
|
||||||
|
object.TokenError:
|
||||||
|
title: TokenError
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
error_description:
|
||||||
|
type: string
|
||||||
object.TokenWrapper:
|
object.TokenWrapper:
|
||||||
title: TokenWrapper
|
title: TokenWrapper
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
access_token:
|
access_token:
|
||||||
type: string
|
type: string
|
||||||
error:
|
|
||||||
type: string
|
|
||||||
expires_in:
|
expires_in:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
@ -97,8 +97,8 @@ const authInfo = {
|
|||||||
endpoint: "https://appleid.apple.com/auth/authorize",
|
endpoint: "https://appleid.apple.com/auth/authorize",
|
||||||
},
|
},
|
||||||
AzureAD: {
|
AzureAD: {
|
||||||
scope: "user_impersonation",
|
scope: "user.read",
|
||||||
endpoint: "https://login.microsoftonline.com/common/oauth2/authorize",
|
endpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
||||||
},
|
},
|
||||||
Slack: {
|
Slack: {
|
||||||
scope: "users:read",
|
scope: "users:read",
|
||||||
@ -236,7 +236,7 @@ export function getAuthUrl(application, provider, method) {
|
|||||||
} else if (provider.type === "Apple") {
|
} else if (provider.type === "Apple") {
|
||||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&response_mode=form_post`;
|
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&response_mode=form_post`;
|
||||||
} else if (provider.type === "AzureAD") {
|
} else if (provider.type === "AzureAD") {
|
||||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&resource=https://graph.windows.net/`;
|
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||||
} else if (provider.type === "Slack") {
|
} else if (provider.type === "Slack") {
|
||||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||||
} else if (provider.type === "Steam") {
|
} else if (provider.type === "Steam") {
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
"Sign Up": "Registrieren"
|
"Sign Up": "Registrieren"
|
||||||
},
|
},
|
||||||
"application": {
|
"application": {
|
||||||
|
"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",
|
||||||
"Copy signup page URL": "Copy signup page URL",
|
"Copy signup page URL": "Copy signup page URL",
|
||||||
"Edit Application": "Anwendung bearbeiten",
|
"Edit Application": "Anwendung bearbeiten",
|
||||||
|
"Enable SAML compress": "Enable SAML compress",
|
||||||
|
"Enable SAML compress - Tooltip": "Enable SAML compress - 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 signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
|
"Enable signin session - Tooltip": "Aktiviere Anmeldesession - Tooltip",
|
||||||
@ -30,6 +33,7 @@
|
|||||||
"Refresh token expire - Tooltip": "Aktualisierungs-Token läuft ab - Tooltip",
|
"Refresh token expire - Tooltip": "Aktualisierungs-Token läuft ab - Tooltip",
|
||||||
"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",
|
||||||
"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",
|
||||||
@ -442,6 +446,8 @@
|
|||||||
"SP ACS URL": "SP-ACS-URL",
|
"SP ACS URL": "SP-ACS-URL",
|
||||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||||
"SP Entity ID": "SP Entity ID",
|
"SP Entity ID": "SP Entity ID",
|
||||||
|
"Scene": "Scene",
|
||||||
|
"Scene - Tooltip": "Scene - Tooltip",
|
||||||
"Scope": "Scope",
|
"Scope": "Scope",
|
||||||
"Scope - Tooltip": "Scope - Tooltip",
|
"Scope - Tooltip": "Scope - Tooltip",
|
||||||
"Secret access key": "Geheimer Zugangsschlüssel",
|
"Secret access key": "Geheimer Zugangsschlüssel",
|
||||||
@ -533,7 +539,6 @@
|
|||||||
"The input is not invoice title!": "The input is not invoice title!",
|
"The input is not invoice title!": "The input is not invoice title!",
|
||||||
"The input is not valid Email!": "Die Eingabe ist ungültig!",
|
"The input is not valid Email!": "Die Eingabe ist ungültig!",
|
||||||
"The input is not valid Phone!": "Die Eingabe ist nicht gültig!",
|
"The input is not valid Phone!": "Die Eingabe ist nicht gültig!",
|
||||||
"Unknown Check Type": "Unbekannter Schecktyp",
|
|
||||||
"Username": "Benutzername",
|
"Username": "Benutzername",
|
||||||
"Username - Tooltip": "Benutzername - Tooltip",
|
"Username - Tooltip": "Benutzername - Tooltip",
|
||||||
"Your account has been created!": "Ihr Konto wurde erstellt!",
|
"Your account has been created!": "Ihr Konto wurde erstellt!",
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
"Sign Up": "Sign Up"
|
"Sign Up": "Sign Up"
|
||||||
},
|
},
|
||||||
"application": {
|
"application": {
|
||||||
|
"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",
|
||||||
"Copy signup page URL": "Copy signup page URL",
|
"Copy signup page URL": "Copy signup page URL",
|
||||||
"Edit Application": "Edit Application",
|
"Edit Application": "Edit Application",
|
||||||
|
"Enable SAML compress": "Enable SAML compress",
|
||||||
|
"Enable SAML compress - Tooltip": "Enable SAML compress - 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 signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
@ -30,6 +33,7 @@
|
|||||||
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
||||||
"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",
|
||||||
"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",
|
||||||
@ -407,9 +411,9 @@
|
|||||||
"Domain": "Domain",
|
"Domain": "Domain",
|
||||||
"Domain - Tooltip": "Domain - Tooltip",
|
"Domain - Tooltip": "Domain - Tooltip",
|
||||||
"Edit Provider": "Edit Provider",
|
"Edit Provider": "Edit Provider",
|
||||||
"Email Content": "Email content",
|
"Email Content": "Email Content",
|
||||||
"Email Content - Tooltip": "Email Content - Tooltip",
|
"Email Content - Tooltip": "Email Content - Tooltip",
|
||||||
"Email Title": "Email title",
|
"Email Title": "Email Title",
|
||||||
"Email Title - Tooltip": "Email Title - Tooltip",
|
"Email Title - Tooltip": "Email Title - Tooltip",
|
||||||
"Endpoint": "Endpoint",
|
"Endpoint": "Endpoint",
|
||||||
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
"Endpoint (Intranet)": "Endpoint (Intranet)",
|
||||||
@ -442,6 +446,8 @@
|
|||||||
"SP ACS URL": "SP ACS URL",
|
"SP ACS URL": "SP ACS URL",
|
||||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||||
"SP Entity ID": "SP Entity ID",
|
"SP Entity ID": "SP Entity ID",
|
||||||
|
"Scene": "Scene",
|
||||||
|
"Scene - Tooltip": "Scene - Tooltip",
|
||||||
"Scope": "Scope",
|
"Scope": "Scope",
|
||||||
"Scope - Tooltip": "Scope - Tooltip",
|
"Scope - Tooltip": "Scope - Tooltip",
|
||||||
"Secret access key": "Secret access key",
|
"Secret access key": "Secret access key",
|
||||||
@ -467,9 +473,9 @@
|
|||||||
"Template Code - Tooltip": "Template Code - Tooltip",
|
"Template Code - Tooltip": "Template Code - Tooltip",
|
||||||
"Terms of Use": "Terms of Use",
|
"Terms of Use": "Terms of Use",
|
||||||
"Terms of Use - Tooltip": "Terms of Use - Tooltip",
|
"Terms of Use - Tooltip": "Terms of Use - Tooltip",
|
||||||
"Test Connection": "Test Smtp Connection",
|
"Test Connection": "Test Connection",
|
||||||
"Test Email": "Test email config",
|
"Test Email": "Test Email",
|
||||||
"Test Email - Tooltip": "Email Address",
|
"Test Email - Tooltip": "Test Email - Tooltip",
|
||||||
"Token URL": "Token URL",
|
"Token URL": "Token URL",
|
||||||
"Token URL - Tooltip": "Token URL - Tooltip",
|
"Token URL - Tooltip": "Token URL - Tooltip",
|
||||||
"Type": "Type",
|
"Type": "Type",
|
||||||
@ -533,7 +539,6 @@
|
|||||||
"The input is not invoice title!": "The input is not invoice title!",
|
"The input is not invoice title!": "The input is not invoice title!",
|
||||||
"The input is not valid Email!": "The input is not valid Email!",
|
"The input is not valid Email!": "The input is not valid Email!",
|
||||||
"The input is not valid Phone!": "The input is not valid Phone!",
|
"The input is not valid Phone!": "The input is not valid Phone!",
|
||||||
"Unknown Check Type": "Unknown Check Type",
|
|
||||||
"Username": "Username",
|
"Username": "Username",
|
||||||
"Username - Tooltip": "Username - Tooltip",
|
"Username - Tooltip": "Username - Tooltip",
|
||||||
"Your account has been created!": "Your account has been created!",
|
"Your account has been created!": "Your account has been created!",
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
"Sign Up": "S'inscrire"
|
"Sign Up": "S'inscrire"
|
||||||
},
|
},
|
||||||
"application": {
|
"application": {
|
||||||
|
"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",
|
||||||
"Copy signup page URL": "Copy signup page URL",
|
"Copy signup page URL": "Copy signup page URL",
|
||||||
"Edit Application": "Modifier l'application",
|
"Edit Application": "Modifier l'application",
|
||||||
|
"Enable SAML compress": "Enable SAML compress",
|
||||||
|
"Enable SAML compress - Tooltip": "Enable SAML compress - 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 signin session - Tooltip": "Activer la session de connexion - infobulle",
|
"Enable signin session - Tooltip": "Activer la session de connexion - infobulle",
|
||||||
@ -30,6 +33,7 @@
|
|||||||
"Refresh token expire - Tooltip": "Expiration du jeton d'actualisation - infobulle",
|
"Refresh token expire - Tooltip": "Expiration du jeton d'actualisation - infobulle",
|
||||||
"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",
|
||||||
"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",
|
||||||
@ -442,6 +446,8 @@
|
|||||||
"SP ACS URL": "URL du SP ACS",
|
"SP ACS URL": "URL du SP ACS",
|
||||||
"SP ACS URL - Tooltip": "URL SP ACS - infobulle",
|
"SP ACS URL - Tooltip": "URL SP ACS - infobulle",
|
||||||
"SP Entity ID": "ID de l'entité SP",
|
"SP Entity ID": "ID de l'entité SP",
|
||||||
|
"Scene": "Scene",
|
||||||
|
"Scene - Tooltip": "Scene - Tooltip",
|
||||||
"Scope": "Scope",
|
"Scope": "Scope",
|
||||||
"Scope - Tooltip": "Scope - Tooltip",
|
"Scope - Tooltip": "Scope - Tooltip",
|
||||||
"Secret access key": "Clé d'accès secrète",
|
"Secret access key": "Clé d'accès secrète",
|
||||||
@ -533,7 +539,6 @@
|
|||||||
"The input is not invoice title!": "The input is not invoice title!",
|
"The input is not invoice title!": "The input is not invoice title!",
|
||||||
"The input is not valid Email!": "L'entrée n'est pas un email valide !",
|
"The input is not valid Email!": "L'entrée n'est pas un email valide !",
|
||||||
"The input is not valid Phone!": "L'entrée n'est pas un téléphone valide !",
|
"The input is not valid Phone!": "L'entrée n'est pas un téléphone valide !",
|
||||||
"Unknown Check Type": "Type de vérification inconnu",
|
|
||||||
"Username": "Nom d'utilisateur",
|
"Username": "Nom d'utilisateur",
|
||||||
"Username - Tooltip": "Nom d'utilisateur - Info-bulle",
|
"Username - Tooltip": "Nom d'utilisateur - Info-bulle",
|
||||||
"Your account has been created!": "Votre compte a été créé !",
|
"Your account has been created!": "Votre compte a été créé !",
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
"Sign Up": "新規登録"
|
"Sign Up": "新規登録"
|
||||||
},
|
},
|
||||||
"application": {
|
"application": {
|
||||||
|
"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",
|
||||||
"Copy signup page URL": "Copy signup page URL",
|
"Copy signup page URL": "Copy signup page URL",
|
||||||
"Edit Application": "アプリケーションを編集",
|
"Edit Application": "アプリケーションを編集",
|
||||||
|
"Enable SAML compress": "Enable SAML compress",
|
||||||
|
"Enable SAML compress - Tooltip": "Enable SAML compress - Tooltip",
|
||||||
"Enable code signin": "コードサインインを有効にする",
|
"Enable code signin": "コードサインインを有効にする",
|
||||||
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
"Enable code signin - Tooltip": "Enable code signin - Tooltip",
|
||||||
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
@ -30,6 +33,7 @@
|
|||||||
"Refresh token expire - Tooltip": "トークンの有効期限を更新する - ツールチップ",
|
"Refresh token expire - Tooltip": "トークンの有効期限を更新する - ツールチップ",
|
||||||
"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",
|
||||||
"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": "アイテムの登録",
|
||||||
@ -442,6 +446,8 @@
|
|||||||
"SP ACS URL": "SP ACS URL",
|
"SP ACS URL": "SP ACS URL",
|
||||||
"SP ACS URL - Tooltip": "SP ACS URL - ツールチップ",
|
"SP ACS URL - Tooltip": "SP ACS URL - ツールチップ",
|
||||||
"SP Entity ID": "SP ID",
|
"SP Entity ID": "SP ID",
|
||||||
|
"Scene": "Scene",
|
||||||
|
"Scene - Tooltip": "Scene - Tooltip",
|
||||||
"Scope": "Scope",
|
"Scope": "Scope",
|
||||||
"Scope - Tooltip": "Scope - Tooltip",
|
"Scope - Tooltip": "Scope - Tooltip",
|
||||||
"Secret access key": "シークレットアクセスキー",
|
"Secret access key": "シークレットアクセスキー",
|
||||||
@ -533,7 +539,6 @@
|
|||||||
"The input is not invoice title!": "The input is not invoice title!",
|
"The input is not invoice title!": "The input is not invoice title!",
|
||||||
"The input is not valid Email!": "入力されたメールアドレスが無効です!",
|
"The input is not valid Email!": "入力されたメールアドレスが無効です!",
|
||||||
"The input is not valid Phone!": "入力された電話番号が正しくありません!",
|
"The input is not valid Phone!": "入力された電話番号が正しくありません!",
|
||||||
"Unknown Check Type": "不明なチェックタイプ",
|
|
||||||
"Username": "ユーザー名",
|
"Username": "ユーザー名",
|
||||||
"Username - Tooltip": "ユーザー名 - ツールチップ",
|
"Username - Tooltip": "ユーザー名 - ツールチップ",
|
||||||
"Your account has been created!": "あなたのアカウントが作成されました!",
|
"Your account has been created!": "あなたのアカウントが作成されました!",
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
"Sign Up": "Sign Up"
|
"Sign Up": "Sign Up"
|
||||||
},
|
},
|
||||||
"application": {
|
"application": {
|
||||||
|
"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",
|
||||||
"Copy signup page URL": "Copy signup page URL",
|
"Copy signup page URL": "Copy signup page URL",
|
||||||
"Edit Application": "Edit Application",
|
"Edit Application": "Edit Application",
|
||||||
|
"Enable SAML compress": "Enable SAML compress",
|
||||||
|
"Enable SAML compress - Tooltip": "Enable SAML compress - 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 signin session - Tooltip": "Enable signin session - Tooltip",
|
"Enable signin session - Tooltip": "Enable signin session - Tooltip",
|
||||||
@ -30,6 +33,7 @@
|
|||||||
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
"Refresh token expire - Tooltip": "Refresh token expire - Tooltip",
|
||||||
"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",
|
||||||
"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",
|
||||||
@ -442,6 +446,8 @@
|
|||||||
"SP ACS URL": "SP ACS URL",
|
"SP ACS URL": "SP ACS URL",
|
||||||
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
"SP ACS URL - Tooltip": "SP ACS URL - Tooltip",
|
||||||
"SP Entity ID": "SP Entity ID",
|
"SP Entity ID": "SP Entity ID",
|
||||||
|
"Scene": "Scene",
|
||||||
|
"Scene - Tooltip": "Scene - Tooltip",
|
||||||
"Scope": "Scope",
|
"Scope": "Scope",
|
||||||
"Scope - Tooltip": "Scope - Tooltip",
|
"Scope - Tooltip": "Scope - Tooltip",
|
||||||
"Secret access key": "Secret access key",
|
"Secret access key": "Secret access key",
|
||||||
@ -533,7 +539,6 @@
|
|||||||
"The input is not invoice title!": "The input is not invoice title!",
|
"The input is not invoice title!": "The input is not invoice title!",
|
||||||
"The input is not valid Email!": "The input is not valid Email!",
|
"The input is not valid Email!": "The input is not valid Email!",
|
||||||
"The input is not valid Phone!": "The input is not valid Phone!",
|
"The input is not valid Phone!": "The input is not valid Phone!",
|
||||||
"Unknown Check Type": "Unknown Check Type",
|
|
||||||
"Username": "Username",
|
"Username": "Username",
|
||||||
"Username - Tooltip": "Username - Tooltip",
|
"Username - Tooltip": "Username - Tooltip",
|
||||||
"Your account has been created!": "Your account has been created!",
|
"Your account has been created!": "Your account has been created!",
|
||||||
|
@ -6,10 +6,13 @@
|
|||||||
"Sign Up": "Регистрация"
|
"Sign Up": "Регистрация"
|
||||||
},
|
},
|
||||||
"application": {
|
"application": {
|
||||||
|
"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",
|
||||||
"Copy signup page URL": "Copy signup page URL",
|
"Copy signup page URL": "Copy signup page URL",
|
||||||
"Edit Application": "Изменить приложение",
|
"Edit Application": "Изменить приложение",
|
||||||
|
"Enable SAML compress": "Enable SAML compress",
|
||||||
|
"Enable SAML compress - Tooltip": "Enable SAML compress - Tooltip",
|
||||||
"Enable code signin": "Включить кодовый вход",
|
"Enable code signin": "Включить кодовый вход",
|
||||||
"Enable code signin - Tooltip": "Включить вход с кодом - Tooltip",
|
"Enable code signin - Tooltip": "Включить вход с кодом - Tooltip",
|
||||||
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
|
"Enable signin session - Tooltip": "Включить сеанс входа - Подсказка",
|
||||||
@ -30,6 +33,7 @@
|
|||||||
"Refresh token expire - Tooltip": "Срок обновления токена истекает - Подсказка",
|
"Refresh token expire - Tooltip": "Срок обновления токена истекает - Подсказка",
|
||||||
"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",
|
||||||
"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": "Элементы регистрации",
|
||||||
@ -442,6 +446,8 @@
|
|||||||
"SP ACS URL": "SP ACS URL",
|
"SP ACS URL": "SP ACS URL",
|
||||||
"SP ACS URL - Tooltip": "SP ACS URL - Подсказка",
|
"SP ACS URL - Tooltip": "SP ACS URL - Подсказка",
|
||||||
"SP Entity ID": "Идентификатор сущности SP",
|
"SP Entity ID": "Идентификатор сущности SP",
|
||||||
|
"Scene": "Scene",
|
||||||
|
"Scene - Tooltip": "Scene - Tooltip",
|
||||||
"Scope": "Scope",
|
"Scope": "Scope",
|
||||||
"Scope - Tooltip": "Scope - Tooltip",
|
"Scope - Tooltip": "Scope - Tooltip",
|
||||||
"Secret access key": "Секретный ключ доступа",
|
"Secret access key": "Секретный ключ доступа",
|
||||||
@ -533,7 +539,6 @@
|
|||||||
"The input is not invoice title!": "The input is not invoice title!",
|
"The input is not invoice title!": "The input is not invoice title!",
|
||||||
"The input is not valid Email!": "Ввод не является допустимым Email!",
|
"The input is not valid Email!": "Ввод не является допустимым Email!",
|
||||||
"The input is not valid Phone!": "Введен неверный телефон!",
|
"The input is not valid Phone!": "Введен неверный телефон!",
|
||||||
"Unknown Check Type": "Неизвестный тип проверки",
|
|
||||||
"Username": "Имя пользователя",
|
"Username": "Имя пользователя",
|
||||||
"Username - Tooltip": "Имя пользователя - Подсказка",
|
"Username - Tooltip": "Имя пользователя - Подсказка",
|
||||||
"Your account has been created!": "Ваша учетная запись была создана!",
|
"Your account has been created!": "Ваша учетная запись была создана!",
|
||||||
|
@ -6,15 +6,15 @@
|
|||||||
"Sign Up": "注册"
|
"Sign Up": "注册"
|
||||||
},
|
},
|
||||||
"application": {
|
"application": {
|
||||||
"Copy prompt page URL": "复制提醒页面URL",
|
|
||||||
"Copy SAML metadata URL": "复制SAML元数据URL",
|
"Copy SAML metadata URL": "复制SAML元数据URL",
|
||||||
|
"Copy prompt page URL": "复制提醒页面URL",
|
||||||
"Copy signin page URL": "复制登录页面URL",
|
"Copy signin page URL": "复制登录页面URL",
|
||||||
"Copy signup page URL": "复制注册页面URL",
|
"Copy signup page URL": "复制注册页面URL",
|
||||||
"Edit Application": "编辑应用",
|
"Edit Application": "编辑应用",
|
||||||
"Enable code signin": "启用验证码登录",
|
|
||||||
"Enable code signin - Tooltip": "是否允许用手机或邮箱验证码登录",
|
|
||||||
"Enable SAML compress": "压缩SAML响应",
|
"Enable SAML compress": "压缩SAML响应",
|
||||||
"Enable SAML compress - Tooltip": "Casdoor作为SAML idp时,是否压缩SAML响应信息",
|
"Enable SAML compress - Tooltip": "Casdoor作为SAML idp时,是否压缩SAML响应信息",
|
||||||
|
"Enable code signin": "启用验证码登录",
|
||||||
|
"Enable code signin - Tooltip": "是否允许用手机或邮箱验证码登录",
|
||||||
"Enable signin session - Tooltip": "从应用登录Casdoor后,Casdoor是否保持会话",
|
"Enable signin session - Tooltip": "从应用登录Casdoor后,Casdoor是否保持会话",
|
||||||
"Enable signup": "启用注册",
|
"Enable signup": "启用注册",
|
||||||
"Enable signup - Tooltip": "是否允许用户注册",
|
"Enable signup - Tooltip": "是否允许用户注册",
|
||||||
@ -446,6 +446,8 @@
|
|||||||
"SP ACS URL": "SP ACS URL",
|
"SP ACS URL": "SP ACS URL",
|
||||||
"SP ACS URL - Tooltip": "SP ACS URL - 工具提示",
|
"SP ACS URL - Tooltip": "SP ACS URL - 工具提示",
|
||||||
"SP Entity ID": "SP 实体 ID",
|
"SP Entity ID": "SP 实体 ID",
|
||||||
|
"Scene": "Scene",
|
||||||
|
"Scene - Tooltip": "Scene - Tooltip",
|
||||||
"Scope": "Scope",
|
"Scope": "Scope",
|
||||||
"Scope - Tooltip": "Scope - 工具提示",
|
"Scope - Tooltip": "Scope - 工具提示",
|
||||||
"Secret access key": "秘密访问密钥",
|
"Secret access key": "秘密访问密钥",
|
||||||
@ -537,7 +539,6 @@
|
|||||||
"The input is not invoice title!": "您输入的发票抬头有误!",
|
"The input is not invoice title!": "您输入的发票抬头有误!",
|
||||||
"The input is not valid Email!": "您输入的电子邮箱格式有误!",
|
"The input is not valid Email!": "您输入的电子邮箱格式有误!",
|
||||||
"The input is not valid Phone!": "您输入的手机号格式有误!",
|
"The input is not valid Phone!": "您输入的手机号格式有误!",
|
||||||
"Unknown Check Type": "未知的验证码类型",
|
|
||||||
"Username": "用户名",
|
"Username": "用户名",
|
||||||
"Username - Tooltip": "允许字符包括字母、数字、下划线,不得以数字开头",
|
"Username - Tooltip": "允许字符包括字母、数字、下划线,不得以数字开头",
|
||||||
"Your account has been created!": "您的账号已创建!",
|
"Your account has been created!": "您的账号已创建!",
|
||||||
|
Reference in New Issue
Block a user