mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-20 09:44:26 +08:00
store oauth 2.0 user info in token context instead of being passed through frontend parameters
This commit is contained in:
+19
-11
@@ -1,6 +1,8 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/pquerna/otp/totp"
|
"github.com/pquerna/otp/totp"
|
||||||
|
|
||||||
"github.com/mayswind/ezbookkeeping/pkg/avatars"
|
"github.com/mayswind/ezbookkeeping/pkg/avatars"
|
||||||
@@ -147,6 +149,7 @@ func (a *AuthorizationsApi) AuthorizeHandler(c *core.WebContext) (any, *errs.Err
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
||||||
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
||||||
@@ -238,6 +241,7 @@ func (a *AuthorizationsApi) TwoFactorAuthorizeHandler(c *core.WebContext) (any,
|
|||||||
|
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
||||||
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
||||||
@@ -336,6 +340,7 @@ func (a *AuthorizationsApi) TwoFactorAuthorizeByRecoveryCodeHandler(c *core.WebC
|
|||||||
|
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
||||||
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
||||||
@@ -366,10 +371,16 @@ func (a *AuthorizationsApi) OAuth2CallbackAuthorizeHandler(c *core.WebContext) (
|
|||||||
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userExternalAuthType := core.UserExternalAuthType(credential.Provider)
|
var tokenContext models.OAuth2CallbackTokenContext
|
||||||
|
err = json.Unmarshal([]byte(c.GetTokenContext()), &tokenContext)
|
||||||
|
|
||||||
if !userExternalAuthType.IsValid() {
|
if err != nil {
|
||||||
log.Warnf(c, "[authorizations.OAuth2CallbackAuthorizeHandler] provider \"%s\" is invalid", credential.Provider)
|
log.Warnf(c, "[authorizations.OAuth2CallbackAuthorizeHandler] parse token context failed, because %s", err.Error())
|
||||||
|
return nil, errs.ErrOperationFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tokenContext.ExternalAuthType.IsValid() {
|
||||||
|
log.Warnf(c, "[authorizations.OAuth2CallbackAuthorizeHandler] external auth type \"%s\" is invalid", tokenContext.ExternalAuthType)
|
||||||
return nil, errs.ErrInvalidOAuth2Provider
|
return nil, errs.ErrInvalidOAuth2Provider
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,13 +429,9 @@ func (a *AuthorizationsApi) OAuth2CallbackAuthorizeHandler(c *core.WebContext) (
|
|||||||
|
|
||||||
userExternalAuth := &models.UserExternalAuth{
|
userExternalAuth := &models.UserExternalAuth{
|
||||||
Uid: user.Uid,
|
Uid: user.Uid,
|
||||||
ExternalAuthType: userExternalAuthType,
|
ExternalAuthType: tokenContext.ExternalAuthType,
|
||||||
}
|
ExternalUsername: tokenContext.ExternalUsername,
|
||||||
|
ExternalEmail: tokenContext.ExternalEmail,
|
||||||
if a.CurrentConfig().OAuth2UserIdentifier == settings.OAuth2UserIdentifierEmail {
|
|
||||||
userExternalAuth.ExternalEmail = user.Email
|
|
||||||
} else if a.CurrentConfig().OAuth2UserIdentifier == settings.OAuth2UserIdentifierUsername {
|
|
||||||
userExternalAuth.ExternalUsername = user.Username
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = a.userExternalAuths.CreateUserExternalAuth(c, userExternalAuth)
|
err = a.userExternalAuths.CreateUserExternalAuth(c, userExternalAuth)
|
||||||
@@ -436,7 +443,7 @@ func (a *AuthorizationsApi) OAuth2CallbackAuthorizeHandler(c *core.WebContext) (
|
|||||||
|
|
||||||
log.Infof(c, "[authorizations.OAuth2CallbackAuthorizeHandler] user external auth has been created for user \"uid:%d\"", user.Uid)
|
log.Infof(c, "[authorizations.OAuth2CallbackAuthorizeHandler] user external auth has been created for user \"uid:%d\"", user.Uid)
|
||||||
} else if oldTokenClaims.Type == core.USER_TOKEN_TYPE_OAUTH2_CALLBACK {
|
} else if oldTokenClaims.Type == core.USER_TOKEN_TYPE_OAUTH2_CALLBACK {
|
||||||
_, err = a.userExternalAuths.GetUserExternalAuthByUid(c, uid, userExternalAuthType)
|
_, err = a.userExternalAuths.GetUserExternalAuthByUid(c, uid, tokenContext.ExternalAuthType)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[authorizations.OAuth2CallbackAuthorizeHandler] failed to get user external auth for user \"uid:%d\", because %s", uid, err.Error())
|
log.Errorf(c, "[authorizations.OAuth2CallbackAuthorizeHandler] failed to get user external auth for user \"uid:%d\", because %s", uid, err.Error())
|
||||||
@@ -461,6 +468,7 @@ func (a *AuthorizationsApi) OAuth2CallbackAuthorizeHandler(c *core.WebContext) (
|
|||||||
|
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
||||||
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -208,7 +209,7 @@ func (a *OAuth2AuthenticationApi) CallbackHandler(c *core.WebContext) (string, *
|
|||||||
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to get user by id %d, because %s", userExternalAuth.Uid, err.Error())
|
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to get user by id %d, because %s", userExternalAuth.Uid, err.Error())
|
||||||
return a.redirectToFailedCallbackPage(c, errs.Or(err, errs.ErrOperationFailed))
|
return a.redirectToFailedCallbackPage(c, errs.Or(err, errs.ErrOperationFailed))
|
||||||
}
|
}
|
||||||
} else if errors.Is(err, errs.ErrUserExternalAuthNotFound) { // user not bound to external auth, try to bind or register new user
|
} else { // errors.Is(err, errs.ErrUserExternalAuthNotFound) // user not bound to external auth, try to bind or register new user
|
||||||
if a.CurrentConfig().OAuth2UserIdentifier == settings.OAuth2UserIdentifierEmail {
|
if a.CurrentConfig().OAuth2UserIdentifier == settings.OAuth2UserIdentifierEmail {
|
||||||
user, err = a.users.GetUserByEmail(c, oauth2UserInfo.Email)
|
user, err = a.users.GetUserByEmail(c, oauth2UserInfo.Email)
|
||||||
} else if a.CurrentConfig().OAuth2UserIdentifier == settings.OAuth2UserIdentifierUsername {
|
} else if a.CurrentConfig().OAuth2UserIdentifier == settings.OAuth2UserIdentifierUsername {
|
||||||
@@ -280,19 +281,39 @@ func (a *OAuth2AuthenticationApi) CallbackHandler(c *core.WebContext) (string, *
|
|||||||
}
|
}
|
||||||
|
|
||||||
if userExternalAuth == nil {
|
if userExternalAuth == nil {
|
||||||
token, _, err := a.tokens.CreateOAuth2CallbackRequireVerifyToken(c, user)
|
tokenContext, err := json.Marshal(&models.OAuth2CallbackTokenContext{
|
||||||
|
ExternalAuthType: userExternalAuthType,
|
||||||
|
ExternalUsername: oauth2UserInfo.UserName,
|
||||||
|
ExternalEmail: oauth2UserInfo.Email,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to create oauth 2.0 callback verify token for user \"uid:%d\", because %s", user.Uid, err.Error())
|
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to marshal oauth 2.0 callback verify token context, because %s", err.Error())
|
||||||
|
return a.redirectToFailedCallbackPage(c, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
|
|
||||||
|
token, _, err := a.tokens.CreateOAuth2CallbackRequireVerifyToken(c, user, string(tokenContext))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to create oauth 2.0 callback verify token, because %s", err.Error())
|
||||||
return a.redirectToFailedCallbackPage(c, errs.ErrTokenGenerating)
|
return a.redirectToFailedCallbackPage(c, errs.ErrTokenGenerating)
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.redirectToVerifyCallbackPage(c, platform, userExternalAuthType, user.Username, token)
|
return a.redirectToVerifyCallbackPage(c, platform, userExternalAuthType, user.Username, token)
|
||||||
} else {
|
} else {
|
||||||
token, _, err := a.tokens.CreateOAuth2CallbackToken(c, user)
|
tokenContext, err := json.Marshal(&models.OAuth2CallbackTokenContext{
|
||||||
|
ExternalAuthType: userExternalAuthType,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to create oauth 2.0 callback token for user \"uid:%d\", because %s", user.Uid, err.Error())
|
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to marshal oauth 2.0 callback token context, because %s", err.Error())
|
||||||
|
return a.redirectToFailedCallbackPage(c, errs.ErrOperationFailed)
|
||||||
|
}
|
||||||
|
|
||||||
|
token, _, err := a.tokens.CreateOAuth2CallbackToken(c, user, string(tokenContext))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(c, "[oauth2_authentications.CallbackHandler] failed to create oauth 2.0 callback token, because %s", err.Error())
|
||||||
return a.redirectToFailedCallbackPage(c, errs.ErrTokenGenerating)
|
return a.redirectToFailedCallbackPage(c, errs.ErrTokenGenerating)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -136,7 +136,7 @@ func (a *TokensApi) TokenRevokeCurrentHandler(c *core.WebContext) (any, *errs.Er
|
|||||||
return false, errs.ErrTokenIsEmpty
|
return false, errs.ErrTokenIsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
_, claims, err := a.tokens.ParseToken(c, tokenString)
|
_, claims, _, err := a.tokens.ParseToken(c, tokenString)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Or(err, errs.NewIncompleteOrIncorrectSubmissionError(err))
|
return nil, errs.Or(err, errs.NewIncompleteOrIncorrectSubmissionError(err))
|
||||||
@@ -344,6 +344,7 @@ func (a *TokensApi) TokenRefreshHandler(c *core.WebContext) (any, *errs.Error) {
|
|||||||
|
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
userApplicationCloudSettings, err := a.userAppCloudSettings.GetUserApplicationCloudSettingsByUid(c, user.Uid)
|
||||||
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
var applicationCloudSettingSlice *models.ApplicationCloudSettingSlice = nil
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ func (a *TwoFactorAuthorizationsApi) TwoFactorEnableConfirmHandler(c *core.WebCo
|
|||||||
|
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
log.Infof(c, "[twofactor_authorizations.TwoFactorEnableConfirmHandler] user \"uid:%d\" token refreshed, new token will be expired at %d", user.Uid, claims.ExpiresAt)
|
log.Infof(c, "[twofactor_authorizations.TwoFactorEnableConfirmHandler] user \"uid:%d\" token refreshed, new token will be expired at %d", user.Uid, claims.ExpiresAt)
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ func (a *UsersApi) UserRegisterHandler(c *core.WebContext) (any, *errs.Error) {
|
|||||||
authResp.Token = token
|
authResp.Token = token
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
log.Infof(c, "[users.UserRegisterHandler] user \"uid:%d\" has logined, token will be expired at %d", user.Uid, claims.ExpiresAt)
|
log.Infof(c, "[users.UserRegisterHandler] user \"uid:%d\" has logined, token will be expired at %d", user.Uid, claims.ExpiresAt)
|
||||||
|
|
||||||
@@ -205,6 +206,7 @@ func (a *UsersApi) UserEmailVerifyHandler(c *core.WebContext) (any, *errs.Error)
|
|||||||
|
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
log.Infof(c, "[users.UserEmailVerifyHandler] user \"uid:%d\" token created, new token will be expired at %d", user.Uid, claims.ExpiresAt)
|
log.Infof(c, "[users.UserEmailVerifyHandler] user \"uid:%d\" token created, new token will be expired at %d", user.Uid, claims.ExpiresAt)
|
||||||
}
|
}
|
||||||
@@ -588,6 +590,7 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
|
|||||||
resp.NewToken = token
|
resp.NewToken = token
|
||||||
c.SetTextualToken(token)
|
c.SetTextualToken(token)
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext("")
|
||||||
|
|
||||||
log.Infof(c, "[users.UserUpdateProfileHandler] user \"uid:%d\" token refreshed, new token will be expired at %d", user.Uid, claims.ExpiresAt)
|
log.Infof(c, "[users.UserUpdateProfileHandler] user \"uid:%d\" token refreshed, new token will be expired at %d", user.Uid, claims.ExpiresAt)
|
||||||
|
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ func (l *UserDataCli) CreateNewUserToken(c *core.CliContext, username string, to
|
|||||||
|
|
||||||
// RevokeUserToken revokes the specified token of the user
|
// RevokeUserToken revokes the specified token of the user
|
||||||
func (l *UserDataCli) RevokeUserToken(c *core.CliContext, token string) error {
|
func (l *UserDataCli) RevokeUserToken(c *core.CliContext, token string) error {
|
||||||
_, claims, err := l.tokens.ParseToken(c, token)
|
_, claims, _, err := l.tokens.ParseToken(c, token)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.CliErrorf(c, "[user_data.RevokeUserToken] failed to parse token, because %s", err.Error())
|
log.CliErrorf(c, "[user_data.RevokeUserToken] failed to parse token, because %s", err.Error())
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
const webContextRequestIdFieldKey = "REQUEST_ID"
|
const webContextRequestIdFieldKey = "REQUEST_ID"
|
||||||
const webContextTextualTokenFieldKey = "TOKEN_STRING"
|
const webContextTextualTokenFieldKey = "TOKEN_STRING"
|
||||||
const webContextTokenClaimsFieldKey = "TOKEN_CLAIMS"
|
const webContextTokenClaimsFieldKey = "TOKEN_CLAIMS"
|
||||||
|
const webContextTokenContextFieldKey = "TOKEN_CONTEXT"
|
||||||
const webContextResponseErrorFieldKey = "RESPONSE_ERROR"
|
const webContextResponseErrorFieldKey = "RESPONSE_ERROR"
|
||||||
|
|
||||||
// AcceptLanguageHeaderName represents the header name of accept language
|
// AcceptLanguageHeaderName represents the header name of accept language
|
||||||
@@ -113,6 +114,22 @@ func (c *WebContext) GetTokenClaims() *UserTokenClaims {
|
|||||||
return claims.(*UserTokenClaims)
|
return claims.(*UserTokenClaims)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTokenContext sets the given user token context to context
|
||||||
|
func (c *WebContext) SetTokenContext(context string) {
|
||||||
|
c.Set(webContextTokenContextFieldKey, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTokenContext returns the current user token context
|
||||||
|
func (c *WebContext) GetTokenContext() string {
|
||||||
|
context, exists := c.Get(webContextTokenContextFieldKey)
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.(string)
|
||||||
|
}
|
||||||
|
|
||||||
// GetCurrentUid returns the current user uid by the current user token
|
// GetCurrentUid returns the current user uid by the current user token
|
||||||
func (c *WebContext) GetCurrentUid() int64 {
|
func (c *WebContext) GetCurrentUid() int64 {
|
||||||
claims := c.GetTokenClaims()
|
claims := c.GetTokenClaims()
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ import (
|
|||||||
|
|
||||||
// Error codes related to user external authentication
|
// Error codes related to user external authentication
|
||||||
var (
|
var (
|
||||||
ErrUserExternalAuthNotFound = NewNormalError(NormalSubcategoryUserExternalAuth, 0, http.StatusBadRequest, "user external auth is not found")
|
ErrUserExternalAuthNotFound = NewNormalError(NormalSubcategoryUserExternalAuth, 0, http.StatusBadRequest, "user external auth is not found")
|
||||||
|
ErrUserExternalAuthAlreadyExists = NewNormalError(NormalSubcategoryUserExternalAuth, 1, http.StatusBadRequest, "user external auth already exists")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func JWTAuthorizationByCookie(c *core.WebContext) {
|
|||||||
|
|
||||||
// JWTTwoFactorAuthorization verifies whether current request is valid by 2fa passcode
|
// JWTTwoFactorAuthorization verifies whether current request is valid by 2fa passcode
|
||||||
func JWTTwoFactorAuthorization(c *core.WebContext) {
|
func JWTTwoFactorAuthorization(c *core.WebContext) {
|
||||||
claims, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_HEADER)
|
claims, tokenContext, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_HEADER)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.PrintJsonErrorResult(c, err)
|
utils.PrintJsonErrorResult(c, err)
|
||||||
@@ -51,12 +51,13 @@ func JWTTwoFactorAuthorization(c *core.WebContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext(tokenContext)
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// JWTEmailVerifyAuthorization verifies whether current request is email verification
|
// JWTEmailVerifyAuthorization verifies whether current request is email verification
|
||||||
func JWTEmailVerifyAuthorization(c *core.WebContext) {
|
func JWTEmailVerifyAuthorization(c *core.WebContext) {
|
||||||
claims, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_ARGUMENT)
|
claims, tokenContext, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_ARGUMENT)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.PrintJsonErrorResult(c, errs.ErrEmailVerifyTokenIsInvalidOrExpired)
|
utils.PrintJsonErrorResult(c, errs.ErrEmailVerifyTokenIsInvalidOrExpired)
|
||||||
@@ -70,12 +71,13 @@ func JWTEmailVerifyAuthorization(c *core.WebContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext(tokenContext)
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// JWTResetPasswordAuthorization verifies whether current request is password reset
|
// JWTResetPasswordAuthorization verifies whether current request is password reset
|
||||||
func JWTResetPasswordAuthorization(c *core.WebContext) {
|
func JWTResetPasswordAuthorization(c *core.WebContext) {
|
||||||
claims, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_ARGUMENT)
|
claims, tokenContext, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_ARGUMENT)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.PrintJsonErrorResult(c, errs.ErrPasswordResetTokenIsInvalidOrExpired)
|
utils.PrintJsonErrorResult(c, errs.ErrPasswordResetTokenIsInvalidOrExpired)
|
||||||
@@ -89,12 +91,13 @@ func JWTResetPasswordAuthorization(c *core.WebContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext(tokenContext)
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// JWTMCPAuthorization verifies whether current request is valid by jwt mcp token in header
|
// JWTMCPAuthorization verifies whether current request is valid by jwt mcp token in header
|
||||||
func JWTMCPAuthorization(c *core.WebContext) {
|
func JWTMCPAuthorization(c *core.WebContext) {
|
||||||
claims, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_HEADER)
|
claims, tokenContext, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_HEADER)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.PrintJsonErrorResult(c, err)
|
utils.PrintJsonErrorResult(c, err)
|
||||||
@@ -108,12 +111,13 @@ func JWTMCPAuthorization(c *core.WebContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext(tokenContext)
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// JWTOAuth2CallbackAuthorization verifies whether current request is OAuth 2.0 callback
|
// JWTOAuth2CallbackAuthorization verifies whether current request is OAuth 2.0 callback
|
||||||
func JWTOAuth2CallbackAuthorization(c *core.WebContext) {
|
func JWTOAuth2CallbackAuthorization(c *core.WebContext) {
|
||||||
claims, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_HEADER)
|
claims, tokenContext, err := getTokenClaims(c, TOKEN_SOURCE_TYPE_HEADER)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.PrintJsonErrorResult(c, errs.ErrTokenExpired)
|
utils.PrintJsonErrorResult(c, errs.ErrTokenExpired)
|
||||||
@@ -127,11 +131,12 @@ func JWTOAuth2CallbackAuthorization(c *core.WebContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext(tokenContext)
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func jwtAuthorization(c *core.WebContext, source TokenSourceType) {
|
func jwtAuthorization(c *core.WebContext, source TokenSourceType) {
|
||||||
claims, err := getTokenClaims(c, source)
|
claims, tokenContext, err := getTokenClaims(c, source)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.PrintJsonErrorResult(c, err)
|
utils.PrintJsonErrorResult(c, err)
|
||||||
@@ -151,31 +156,32 @@ func jwtAuthorization(c *core.WebContext, source TokenSourceType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.SetTokenClaims(claims)
|
c.SetTokenClaims(claims)
|
||||||
|
c.SetTokenContext(tokenContext)
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTokenClaims(c *core.WebContext, source TokenSourceType) (*core.UserTokenClaims, *errs.Error) {
|
func getTokenClaims(c *core.WebContext, source TokenSourceType) (*core.UserTokenClaims, string, *errs.Error) {
|
||||||
token, claims, err := parseToken(c, source)
|
token, claims, tokenContext, err := parseToken(c, source)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf(c, "[authorization.getTokenClaims] failed to parse token, because %s", err.Error())
|
log.Warnf(c, "[authorization.getTokenClaims] failed to parse token, because %s", err.Error())
|
||||||
return nil, errs.Or(err, errs.ErrUnauthorizedAccess)
|
return nil, "", errs.Or(err, errs.ErrUnauthorizedAccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.Valid {
|
if !token.Valid {
|
||||||
log.Warnf(c, "[authorization.getTokenClaims] token is invalid")
|
log.Warnf(c, "[authorization.getTokenClaims] token is invalid")
|
||||||
return nil, errs.ErrCurrentInvalidToken
|
return nil, "", errs.ErrCurrentInvalidToken
|
||||||
}
|
}
|
||||||
|
|
||||||
if claims.Uid <= 0 {
|
if claims.Uid <= 0 {
|
||||||
log.Warnf(c, "[authorization.getTokenClaims] user id in token is invalid")
|
log.Warnf(c, "[authorization.getTokenClaims] user id in token is invalid")
|
||||||
return nil, errs.ErrCurrentInvalidToken
|
return nil, "", errs.ErrCurrentInvalidToken
|
||||||
}
|
}
|
||||||
|
|
||||||
return claims, nil
|
return claims, tokenContext, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseToken(c *core.WebContext, source TokenSourceType) (*jwt.Token, *core.UserTokenClaims, error) {
|
func parseToken(c *core.WebContext, source TokenSourceType) (*jwt.Token, *core.UserTokenClaims, string, error) {
|
||||||
tokenString := ""
|
tokenString := ""
|
||||||
|
|
||||||
if source == TOKEN_SOURCE_TYPE_ARGUMENT {
|
if source == TOKEN_SOURCE_TYPE_ARGUMENT {
|
||||||
@@ -187,7 +193,7 @@ func parseToken(c *core.WebContext, source TokenSourceType) (*jwt.Token, *core.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tokenString == "" {
|
if tokenString == "" {
|
||||||
return nil, nil, errs.ErrTokenIsEmpty
|
return nil, nil, "", errs.ErrTokenIsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
return services.Tokens.ParseToken(c, tokenString)
|
return services.Tokens.ParseToken(c, tokenString)
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ type OAuth2CallbackRequest struct {
|
|||||||
|
|
||||||
// OAuth2CallbackLoginRequest represents all parameters of OAuth 2.0 callback login request
|
// OAuth2CallbackLoginRequest represents all parameters of OAuth 2.0 callback login request
|
||||||
type OAuth2CallbackLoginRequest struct {
|
type OAuth2CallbackLoginRequest struct {
|
||||||
Provider string `json:"provider" binding:"required,notBlank"`
|
|
||||||
Password string `json:"password" binding:"omitempty,min=6,max=128"`
|
Password string `json:"password" binding:"omitempty,min=6,max=128"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,19 @@ type TokenRecord struct {
|
|||||||
TokenType core.TokenType `xorm:"INDEX(IDX_token_record_uid_type_expired_time) TINYINT NOT NULL"`
|
TokenType core.TokenType `xorm:"INDEX(IDX_token_record_uid_type_expired_time) TINYINT NOT NULL"`
|
||||||
Secret string `xorm:"VARCHAR(10) NOT NULL"`
|
Secret string `xorm:"VARCHAR(10) NOT NULL"`
|
||||||
UserAgent string `xorm:"VARCHAR(255)"`
|
UserAgent string `xorm:"VARCHAR(255)"`
|
||||||
|
Context string `xorm:"BLOB"`
|
||||||
CreatedUnixTime int64 `xorm:"PK"`
|
CreatedUnixTime int64 `xorm:"PK"`
|
||||||
ExpiredUnixTime int64 `xorm:"INDEX(IDX_token_record_uid_type_expired_time) INDEX(IDX_token_record_expired_time)"`
|
ExpiredUnixTime int64 `xorm:"INDEX(IDX_token_record_uid_type_expired_time) INDEX(IDX_token_record_expired_time)"`
|
||||||
LastSeenUnixTime int64
|
LastSeenUnixTime int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OAuth2CallbackTokenContext represents the context data of oauth 2.0 callback token
|
||||||
|
type OAuth2CallbackTokenContext struct {
|
||||||
|
ExternalAuthType core.UserExternalAuthType `json:"externalAuthType"`
|
||||||
|
ExternalUsername string `json:"externalUsername"`
|
||||||
|
ExternalEmail string `json:"externalEmail"`
|
||||||
|
}
|
||||||
|
|
||||||
// TokenGenerateMCPRequest represents all parameters of mcp token generation request
|
// TokenGenerateMCPRequest represents all parameters of mcp token generation request
|
||||||
type TokenGenerateMCPRequest struct {
|
type TokenGenerateMCPRequest struct {
|
||||||
Password string `json:"password" binding:"omitempty,min=6,max=128"`
|
Password string `json:"password" binding:"omitempty,min=6,max=128"`
|
||||||
|
|||||||
+25
-22
@@ -73,75 +73,75 @@ func (s *TokenService) GetAllUnexpiredNormalAndMCPTokensByUid(c core.Context, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseToken returns the token model according to token content
|
// ParseToken returns the token model according to token content
|
||||||
func (s *TokenService) ParseToken(c core.Context, token string) (*jwt.Token, *core.UserTokenClaims, error) {
|
func (s *TokenService) ParseToken(c core.Context, token string) (*jwt.Token, *core.UserTokenClaims, string, error) {
|
||||||
return s.parseToken(c, token)
|
return s.parseToken(c, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateTokenViaCli generates a new normal token and saves to database
|
// CreateTokenViaCli generates a new normal token and saves to database
|
||||||
func (s *TokenService) CreateTokenViaCli(c *core.CliContext, user *models.User) (string, *models.TokenRecord, error) {
|
func (s *TokenService) CreateTokenViaCli(c *core.CliContext, user *models.User) (string, *models.TokenRecord, error) {
|
||||||
token, _, tokenRecord, err := s.createToken(c, user, core.USER_TOKEN_TYPE_NORMAL, TokenUserAgentCreatedViaCli, s.CurrentConfig().TokenExpiredTimeDuration)
|
token, _, tokenRecord, err := s.createToken(c, user, core.USER_TOKEN_TYPE_NORMAL, TokenUserAgentCreatedViaCli, "", s.CurrentConfig().TokenExpiredTimeDuration)
|
||||||
return token, tokenRecord, err
|
return token, tokenRecord, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateToken generates a new normal token and saves to database
|
// CreateToken generates a new normal token and saves to database
|
||||||
func (s *TokenService) CreateToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreateToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_NORMAL, s.getUserAgent(c), s.CurrentConfig().TokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_NORMAL, s.getUserAgent(c), "", s.CurrentConfig().TokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRequire2FAToken generates a new token requiring user to verify 2fa passcode and saves to database
|
// CreateRequire2FAToken generates a new token requiring user to verify 2fa passcode and saves to database
|
||||||
func (s *TokenService) CreateRequire2FAToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreateRequire2FAToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_REQUIRE_2FA, s.getUserAgent(c), s.CurrentConfig().TemporaryTokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_REQUIRE_2FA, s.getUserAgent(c), "", s.CurrentConfig().TemporaryTokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateEmailVerifyToken generates a new email verify token and saves to database
|
// CreateEmailVerifyToken generates a new email verify token and saves to database
|
||||||
func (s *TokenService) CreateEmailVerifyToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreateEmailVerifyToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_EMAIL_VERIFY, s.getUserAgent(c), s.CurrentConfig().EmailVerifyTokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_EMAIL_VERIFY, s.getUserAgent(c), "", s.CurrentConfig().EmailVerifyTokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateEmailVerifyTokenWithoutUserAgent generates a new email verify token and saves to database
|
// CreateEmailVerifyTokenWithoutUserAgent generates a new email verify token and saves to database
|
||||||
func (s *TokenService) CreateEmailVerifyTokenWithoutUserAgent(c core.Context, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreateEmailVerifyTokenWithoutUserAgent(c core.Context, user *models.User) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_EMAIL_VERIFY, "", s.CurrentConfig().EmailVerifyTokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_EMAIL_VERIFY, "", "", s.CurrentConfig().EmailVerifyTokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreatePasswordResetToken generates a new password reset token and saves to database
|
// CreatePasswordResetToken generates a new password reset token and saves to database
|
||||||
func (s *TokenService) CreatePasswordResetToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreatePasswordResetToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_PASSWORD_RESET, s.getUserAgent(c), s.CurrentConfig().PasswordResetTokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_PASSWORD_RESET, s.getUserAgent(c), "", s.CurrentConfig().PasswordResetTokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreatePasswordResetTokenWithoutUserAgent generates a new password reset token and saves to database
|
// CreatePasswordResetTokenWithoutUserAgent generates a new password reset token and saves to database
|
||||||
func (s *TokenService) CreatePasswordResetTokenWithoutUserAgent(c core.Context, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreatePasswordResetTokenWithoutUserAgent(c core.Context, user *models.User) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_PASSWORD_RESET, "", s.CurrentConfig().PasswordResetTokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_PASSWORD_RESET, "", "", s.CurrentConfig().PasswordResetTokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMCPToken generates a new MCP token and saves to database
|
// CreateMCPToken generates a new MCP token and saves to database
|
||||||
func (s *TokenService) CreateMCPToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreateMCPToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
||||||
tokenExpiredTimeDuration := time.Unix(tokenMaxExpiredAtUnixTime, 0).Sub(time.Now())
|
tokenExpiredTimeDuration := time.Unix(tokenMaxExpiredAtUnixTime, 0).Sub(time.Now())
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_MCP, s.getUserAgent(c), tokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_MCP, s.getUserAgent(c), "", tokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMCPTokenViaCli generates a new MCP token and saves to database
|
// CreateMCPTokenViaCli generates a new MCP token and saves to database
|
||||||
func (s *TokenService) CreateMCPTokenViaCli(c *core.CliContext, user *models.User) (string, *models.TokenRecord, error) {
|
func (s *TokenService) CreateMCPTokenViaCli(c *core.CliContext, user *models.User) (string, *models.TokenRecord, error) {
|
||||||
tokenExpiredTimeDuration := time.Unix(tokenMaxExpiredAtUnixTime, 0).Sub(time.Now())
|
tokenExpiredTimeDuration := time.Unix(tokenMaxExpiredAtUnixTime, 0).Sub(time.Now())
|
||||||
token, _, tokenRecord, err := s.createToken(c, user, core.USER_TOKEN_TYPE_MCP, TokenUserAgentCreatedViaCli, tokenExpiredTimeDuration)
|
token, _, tokenRecord, err := s.createToken(c, user, core.USER_TOKEN_TYPE_MCP, TokenUserAgentCreatedViaCli, "", tokenExpiredTimeDuration)
|
||||||
return token, tokenRecord, err
|
return token, tokenRecord, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOAuth2CallbackRequireVerifyToken generates a new OAuth 2.0 callback token requiring user to verify and saves to database
|
// CreateOAuth2CallbackRequireVerifyToken generates a new OAuth 2.0 callback token requiring user to verify and saves to database
|
||||||
func (s *TokenService) CreateOAuth2CallbackRequireVerifyToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreateOAuth2CallbackRequireVerifyToken(c *core.WebContext, user *models.User, context string) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_OAUTH2_CALLBACK_REQUIRE_VERIFY, s.getUserAgent(c), s.CurrentConfig().TemporaryTokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_OAUTH2_CALLBACK_REQUIRE_VERIFY, s.getUserAgent(c), context, s.CurrentConfig().TemporaryTokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOAuth2CallbackToken generates a new OAuth 2.0 callback token and saves to database
|
// CreateOAuth2CallbackToken generates a new OAuth 2.0 callback token and saves to database
|
||||||
func (s *TokenService) CreateOAuth2CallbackToken(c *core.WebContext, user *models.User) (string, *core.UserTokenClaims, error) {
|
func (s *TokenService) CreateOAuth2CallbackToken(c *core.WebContext, user *models.User, context string) (string, *core.UserTokenClaims, error) {
|
||||||
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_OAUTH2_CALLBACK, s.getUserAgent(c), s.CurrentConfig().TemporaryTokenExpiredTimeDuration)
|
token, claims, _, err := s.createToken(c, user, core.USER_TOKEN_TYPE_OAUTH2_CALLBACK, s.getUserAgent(c), context, s.CurrentConfig().TemporaryTokenExpiredTimeDuration)
|
||||||
return token, claims, err
|
return token, claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,8 +331,9 @@ func (s *TokenService) GenerateTokenId(tokenRecord *models.TokenRecord) string {
|
|||||||
return fmt.Sprintf("%d:%d:%d", tokenRecord.Uid, tokenRecord.CreatedUnixTime, tokenRecord.UserTokenId)
|
return fmt.Sprintf("%d:%d:%d", tokenRecord.Uid, tokenRecord.CreatedUnixTime, tokenRecord.UserTokenId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TokenService) parseToken(c core.Context, tokenString string) (*jwt.Token, *core.UserTokenClaims, error) {
|
func (s *TokenService) parseToken(c core.Context, tokenString string) (*jwt.Token, *core.UserTokenClaims, string, error) {
|
||||||
claims := &core.UserTokenClaims{}
|
claims := &core.UserTokenClaims{}
|
||||||
|
tokenContext := ""
|
||||||
|
|
||||||
token, err := jwt.ParseWithClaims(tokenString, claims,
|
token, err := jwt.ParseWithClaims(tokenString, claims,
|
||||||
func(token *jwt.Token) (any, error) {
|
func(token *jwt.Token) (any, error) {
|
||||||
@@ -356,6 +357,7 @@ func (s *TokenService) parseToken(c core.Context, tokenString string) (*jwt.Toke
|
|||||||
return nil, errs.ErrTokenExpired
|
return nil, errs.ErrTokenExpired
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tokenContext = tokenRecord.Context
|
||||||
return []byte(tokenRecord.Secret), nil
|
return []byte(tokenRecord.Secret), nil
|
||||||
},
|
},
|
||||||
jwt.WithIssuedAt(),
|
jwt.WithIssuedAt(),
|
||||||
@@ -363,30 +365,30 @@ func (s *TokenService) parseToken(c core.Context, tokenString string) (*jwt.Toke
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, request.ErrNoTokenInRequest) {
|
if errors.Is(err, request.ErrNoTokenInRequest) {
|
||||||
return nil, nil, errs.ErrTokenIsEmpty
|
return nil, nil, "", errs.ErrTokenIsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, jwt.ErrTokenMalformed) || errors.Is(err, jwt.ErrTokenUnverifiable) || errors.Is(err, jwt.ErrTokenSignatureInvalid) {
|
if errors.Is(err, jwt.ErrTokenMalformed) || errors.Is(err, jwt.ErrTokenUnverifiable) || errors.Is(err, jwt.ErrTokenSignatureInvalid) {
|
||||||
log.Warnf(c, "[tokens.parseToken] token is invalid, because %s", err.Error())
|
log.Warnf(c, "[tokens.parseToken] token is invalid, because %s", err.Error())
|
||||||
return nil, nil, errs.ErrCurrentInvalidToken
|
return nil, nil, "", errs.ErrCurrentInvalidToken
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, jwt.ErrTokenExpired) {
|
if errors.Is(err, jwt.ErrTokenExpired) {
|
||||||
return nil, nil, errs.ErrCurrentTokenExpired
|
return nil, nil, "", errs.ErrCurrentTokenExpired
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, jwt.ErrTokenUsedBeforeIssued) {
|
if errors.Is(err, jwt.ErrTokenUsedBeforeIssued) {
|
||||||
log.Warnf(c, "[tokens.parseToken] token is invalid, because issue time is later than now")
|
log.Warnf(c, "[tokens.parseToken] token is invalid, because issue time is later than now")
|
||||||
return nil, nil, errs.ErrCurrentInvalidToken
|
return nil, nil, "", errs.ErrCurrentInvalidToken
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil, err
|
return nil, nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return token, claims, err
|
return token, claims, tokenContext, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TokenService) createToken(c core.Context, user *models.User, tokenType core.TokenType, userAgent string, expiryDate time.Duration) (string, *core.UserTokenClaims, *models.TokenRecord, error) {
|
func (s *TokenService) createToken(c core.Context, user *models.User, tokenType core.TokenType, userAgent string, context string, expiryDate time.Duration) (string, *core.UserTokenClaims, *models.TokenRecord, error) {
|
||||||
var err error
|
var err error
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
@@ -395,6 +397,7 @@ func (s *TokenService) createToken(c core.Context, user *models.User, tokenType
|
|||||||
UserTokenId: s.getUserTokenId(),
|
UserTokenId: s.getUserTokenId(),
|
||||||
TokenType: tokenType,
|
TokenType: tokenType,
|
||||||
UserAgent: userAgent,
|
UserAgent: userAgent,
|
||||||
|
Context: context,
|
||||||
CreatedUnixTime: now.Unix(),
|
CreatedUnixTime: now.Unix(),
|
||||||
ExpiredUnixTime: now.Add(expiryDate).Unix(),
|
ExpiredUnixTime: now.Add(expiryDate).Unix(),
|
||||||
LastSeenUnixTime: now.Unix(),
|
LastSeenUnixTime: now.Unix(),
|
||||||
|
|||||||
@@ -92,7 +92,15 @@ func (s *UserExternalAuthService) CreateUserExternalAuth(c core.Context, userExt
|
|||||||
userExternalAuth.CreatedUnixTime = time.Now().Unix()
|
userExternalAuth.CreatedUnixTime = time.Now().Unix()
|
||||||
|
|
||||||
return s.UserDB().DoTransaction(c, func(sess *xorm.Session) error {
|
return s.UserDB().DoTransaction(c, func(sess *xorm.Session) error {
|
||||||
_, err := sess.Insert(userExternalAuth)
|
exists, err := sess.Where("uid=? AND external_auth_type=?", userExternalAuth.Uid, userExternalAuth.ExternalAuthType).Limit(1).Exist(&models.UserExternalAuth{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if exists {
|
||||||
|
return errs.ErrUserExternalAuthAlreadyExists
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = sess.Insert(userExternalAuth)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Le fichier d'image pour la reconnaissance IA est vide",
|
"image for AI recognition is empty": "Le fichier d'image pour la reconnaissance IA est vide",
|
||||||
"exceed the maximum size of image file for AI recognition": "L'image téléchargée pour la reconnaissance IA dépasse la taille de fichier maximale autorisée",
|
"exceed the maximum size of image file for AI recognition": "L'image téléchargée pour la reconnaissance IA dépasse la taille de fichier maximale autorisée",
|
||||||
"no transaction information detected": "Aucune information de transaction détectée",
|
"no transaction information detected": "Aucune information de transaction détectée",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "AI 인식을 위한 이미지 파일이 비어 있습니다.",
|
"image for AI recognition is empty": "AI 인식을 위한 이미지 파일이 비어 있습니다.",
|
||||||
"exceed the maximum size of image file for AI recognition": "AI 인식을 위한 업로드된 이미지가 허용된 최대 파일 크기를 초과합니다.",
|
"exceed the maximum size of image file for AI recognition": "AI 인식을 위한 업로드된 이미지가 허용된 최대 파일 크기를 초과합니다.",
|
||||||
"no transaction information detected": "거래 정보가 감지되지 않았습니다.",
|
"no transaction information detected": "거래 정보가 감지되지 않았습니다.",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "ไฟล์รูปภาพสำหรับการจดจำด้วย AI ว่างเปล่า",
|
"image for AI recognition is empty": "ไฟล์รูปภาพสำหรับการจดจำด้วย AI ว่างเปล่า",
|
||||||
"exceed the maximum size of image file for AI recognition": "ไฟล์รูปภาพสำหรับการจดจำด้วย AI เกินขนาดสูงสุดที่อนุญาต",
|
"exceed the maximum size of image file for AI recognition": "ไฟล์รูปภาพสำหรับการจดจำด้วย AI เกินขนาดสูงสุดที่อนุญาต",
|
||||||
"no transaction information detected": "ไม่พบข้อมูลธุรกรรม",
|
"no transaction information detected": "ไม่พบข้อมูลธุรกรรม",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
+2
-1
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
"image for AI recognition is empty": "Image for AI recognition file is empty",
|
||||||
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
"exceed the maximum size of image file for AI recognition": "The uploaded image for AI recognition exceeds the maximum allowed file size",
|
||||||
"no transaction information detected": "No transaction information detected",
|
"no transaction information detected": "No transaction information detected",
|
||||||
"user external auth is not found": "User external authentication is not found",
|
"user external auth is not found": "User external authentication data not found",
|
||||||
|
"user external auth already exists": "User external authentication data already exists, please unlink it first",
|
||||||
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
"oauth2 not enabled": "OAuth 2.0 is not enabled",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
"oauth2 auto registration not enabled": "OAuth 2.0 auto registration is not enabled",
|
||||||
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
"invalid oauth2 login request": "Invalid OAuth 2.0 login request",
|
||||||
|
|||||||
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "用于AI识别的图片为空",
|
"image for AI recognition is empty": "用于AI识别的图片为空",
|
||||||
"exceed the maximum size of image file for AI recognition": "用于AI识别的图片超出了允许的最大文件大小",
|
"exceed the maximum size of image file for AI recognition": "用于AI识别的图片超出了允许的最大文件大小",
|
||||||
"no transaction information detected": "没有检测到交易信息",
|
"no transaction information detected": "没有检测到交易信息",
|
||||||
"user external auth is not found": "用户外部认证信息不存在",
|
"user external auth is not found": "找不到用户外部认证数据",
|
||||||
|
"user external auth already exists": "用户外部认证数据已存在,请先解绑",
|
||||||
"oauth2 not enabled": "OAuth 2.0 没有启用",
|
"oauth2 not enabled": "OAuth 2.0 没有启用",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 自动注册没有启用",
|
"oauth2 auto registration not enabled": "OAuth 2.0 自动注册没有启用",
|
||||||
"invalid oauth2 login request": "无效的 OAuth 2.0 登录请求",
|
"invalid oauth2 login request": "无效的 OAuth 2.0 登录请求",
|
||||||
|
|||||||
@@ -1241,7 +1241,8 @@
|
|||||||
"image for AI recognition is empty": "用於AI識別的圖片檔案為空",
|
"image for AI recognition is empty": "用於AI識別的圖片檔案為空",
|
||||||
"exceed the maximum size of image file for AI recognition": "用於AI識別的圖片超出了允許的最大檔案大小",
|
"exceed the maximum size of image file for AI recognition": "用於AI識別的圖片超出了允許的最大檔案大小",
|
||||||
"no transaction information detected": "沒有檢測到交易資訊",
|
"no transaction information detected": "沒有檢測到交易資訊",
|
||||||
"user external auth is not found": "使用者外部驗證資訊不存在",
|
"user external auth is not found": "找不到使用者外部驗證資料",
|
||||||
|
"user external auth already exists": "使用者外部驗證資料已存在,請先解除連結",
|
||||||
"oauth2 not enabled": "OAuth 2.0 未啟用",
|
"oauth2 not enabled": "OAuth 2.0 未啟用",
|
||||||
"oauth2 auto registration not enabled": "OAuth 2.0 自動註冊未啟用",
|
"oauth2 auto registration not enabled": "OAuth 2.0 自動註冊未啟用",
|
||||||
"invalid oauth2 login request": "無效的 OAuth 2.0 登入請求",
|
"invalid oauth2 login request": "無效的 OAuth 2.0 登入請求",
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
export interface OAuth2CallbackLoginRequest {
|
export interface OAuth2CallbackLoginRequest {
|
||||||
readonly provider?: string;
|
|
||||||
readonly password?: string;
|
readonly password?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -191,11 +191,10 @@ export const useRootStore = defineStore('root', () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function authorizeOAuth2({ provider, password, token }: { provider: string, password?: string, token: string }): Promise<AuthResponse> {
|
function authorizeOAuth2({ password, token }: { password?: string, token: string }): Promise<AuthResponse> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
services.authorizeOAuth2({
|
services.authorizeOAuth2({
|
||||||
req: {
|
req: {
|
||||||
provider,
|
|
||||||
password
|
password
|
||||||
},
|
},
|
||||||
token
|
token
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<v-card variant="flat" class="w-100 mt-0 px-4 pt-12" max-width="500">
|
<v-card variant="flat" class="w-100 mt-0 px-4 pt-12" max-width="500">
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<h4 class="text-h4 mb-2">{{ oauth2LoginDisplayName }}</h4>
|
<h4 class="text-h4 mb-2">{{ oauth2LoginDisplayName }}</h4>
|
||||||
<p class="mb-0" v-if="!error && platform && provider && token && !userName">{{ tt('Logging in...') }}</p>
|
<p class="mb-0" v-if="!error && platform && token && !userName">{{ tt('Logging in...') }}</p>
|
||||||
<p class="mb-0" v-else-if="!error && userName">{{ tt('format.misc.oauth2bindTip', { providerName: oauth2ProviderDisplayName, userName: userName }) }}</p>
|
<p class="mb-0" v-else-if="!error && userName">{{ tt('format.misc.oauth2bindTip', { providerName: oauth2ProviderDisplayName, userName: userName }) }}</p>
|
||||||
<p class="mb-0" v-else-if="error">{{ te({ error }) }}</p>
|
<p class="mb-0" v-else-if="error">{{ te({ error }) }}</p>
|
||||||
<p class="mb-0" v-else>{{ tt('An error occurred') }}</p>
|
<p class="mb-0" v-else>{{ tt('An error occurred') }}</p>
|
||||||
@@ -113,7 +113,6 @@ import { KnownErrorCode } from '@/consts/api.ts';
|
|||||||
import { navigateToHomePage } from '@/lib/web.ts';
|
import { navigateToHomePage } from '@/lib/web.ts';
|
||||||
import {
|
import {
|
||||||
isUserVerifyEmailEnabled,
|
isUserVerifyEmailEnabled,
|
||||||
getOAuth2Provider,
|
|
||||||
getOIDCCustomDisplayNames
|
getOIDCCustomDisplayNames
|
||||||
} from '@/lib/server_settings.ts';
|
} from '@/lib/server_settings.ts';
|
||||||
|
|
||||||
@@ -135,7 +134,12 @@ const props = defineProps<{
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const { tt, te, getLocalizedOAuth2ProviderName, getLocalizedOAuth2LoginText } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
te,
|
||||||
|
getLocalizedOAuth2ProviderName,
|
||||||
|
getLocalizedOAuth2LoginText
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const rootStore = useRootStore();
|
const rootStore = useRootStore();
|
||||||
|
|
||||||
@@ -149,8 +153,8 @@ const {
|
|||||||
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||||
|
|
||||||
const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType.Dark);
|
const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType.Dark);
|
||||||
const oauth2ProviderDisplayName = computed<string>(() => getLocalizedOAuth2ProviderName(getOAuth2Provider(), getOIDCCustomDisplayNames()));
|
const oauth2ProviderDisplayName = computed<string>(() => getLocalizedOAuth2ProviderName(props.provider ?? '', getOIDCCustomDisplayNames()));
|
||||||
const oauth2LoginDisplayName = computed<string>(() => getLocalizedOAuth2LoginText(getOAuth2Provider(), getOIDCCustomDisplayNames()));
|
const oauth2LoginDisplayName = computed<string>(() => getLocalizedOAuth2LoginText(props.provider ?? '', getOIDCCustomDisplayNames()));
|
||||||
|
|
||||||
const error = computed<ErrorResponse | undefined>(() => {
|
const error = computed<ErrorResponse | undefined>(() => {
|
||||||
if (props.errorCode && props.errorMessage) {
|
if (props.errorCode && props.errorMessage) {
|
||||||
@@ -196,7 +200,6 @@ function verifyAndLogin(): void {
|
|||||||
logining.value = true;
|
logining.value = true;
|
||||||
|
|
||||||
rootStore.authorizeOAuth2({
|
rootStore.authorizeOAuth2({
|
||||||
provider: props.provider || '',
|
|
||||||
password: password.value,
|
password: password.value,
|
||||||
token: props.token || ''
|
token: props.token || ''
|
||||||
}).then(authResponse => {
|
}).then(authResponse => {
|
||||||
@@ -217,11 +220,10 @@ function verifyAndLogin(): void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error.value && props.platform && props.provider && props.token && !props.userName) {
|
if (!error.value && props.platform && props.token && !props.userName) {
|
||||||
logining.value = true;
|
logining.value = true;
|
||||||
|
|
||||||
rootStore.authorizeOAuth2({
|
rootStore.authorizeOAuth2({
|
||||||
provider: props.provider,
|
|
||||||
token: props.token
|
token: props.token
|
||||||
}).then(authResponse => {
|
}).then(authResponse => {
|
||||||
logining.value = false;
|
logining.value = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user