Add MFA required error handling and update login response structure

This commit is contained in:
Max 2025-10-10 11:14:52 +08:00
parent 2569634ca2
commit 4a94460377
5 changed files with 23 additions and 16 deletions

View file

@ -112,6 +112,7 @@ var (
ErrInvalidClientMetadata = &ErrorResponse{Code: "invalid_client_metadata", ErrorDescription: "The client metadata is invalid or contains unsupported values."} ErrInvalidClientMetadata = &ErrorResponse{Code: "invalid_client_metadata", ErrorDescription: "The client metadata is invalid or contains unsupported values."}
ErrInvalidSoftwareStatement = &ErrorResponse{Code: "invalid_software_statement", ErrorDescription: "The software statement is invalid or cannot be verified."} ErrInvalidSoftwareStatement = &ErrorResponse{Code: "invalid_software_statement", ErrorDescription: "The software statement is invalid or cannot be verified."}
ErrUnapprovedSoftware = &ErrorResponse{Code: "unapproved_software", ErrorDescription: "The software statement represents software that has been replaced or is otherwise invalid."} ErrUnapprovedSoftware = &ErrorResponse{Code: "unapproved_software", ErrorDescription: "The software statement represents software that has been replaced or is otherwise invalid."}
ErrMFARequired = &ErrorResponse{Code: "mfa_required", ErrorDescription: "Multi-factor authentication is required to access this resource."}
// Configuration and service errors // Configuration and service errors
ErrInvalidConfiguration = types.ErrInvalidConfiguration ErrInvalidConfiguration = types.ErrInvalidConfiguration

View file

@ -135,6 +135,16 @@ func LoginThirdParty(providerID string, userinfo *oauthtypes.OIDCUserInfo, ip st
return nil, err return nil, err
} }
// If MFA Enabled, should return MFA required response
mfaEnabled, err := userProvider.IsMFAEnabled(ctx, userID)
if err != nil {
return nil, err
}
if mfaEnabled {
return nil, response.ErrMFARequired
}
return LoginByUserID(userID, ip) return LoginByUserID(userID, ip)
} }
@ -197,6 +207,8 @@ func LoginByUserID(userid string, ip string) (*LoginResponse, error) {
mfaEnabled := toBool(user["mfa_enabled"]) mfaEnabled := toBool(user["mfa_enabled"])
return &LoginResponse{ return &LoginResponse{
UserID: userid,
Subject: subject,
AccessToken: accessToken, AccessToken: accessToken,
IDToken: oidcToken, IDToken: oidcToken,
RefreshToken: refreshToken, RefreshToken: refreshToken,

View file

@ -176,6 +176,14 @@ func authback(c *gin.Context) {
// LoginThirdParty(providerID, userInfo) // LoginThirdParty(providerID, userInfo)
loginResponse, err := LoginThirdParty(providerID, userInfo, userIPAddress(c)) loginResponse, err := LoginThirdParty(providerID, userInfo, userIPAddress(c))
if err != nil { if err != nil {
// Redirect to MFA required page
if err == response.ErrMFARequired {
response.RespondWithError(c, response.StatusUnauthorized, response.ErrMFARequired)
return
}
// Other errors
errorResp := &response.ErrorResponse{ errorResp := &response.ErrorResponse{
Code: response.ErrInvalidRequest.Code, Code: response.ErrInvalidRequest.Code,
ErrorDescription: "Failed to login: " + err.Error(), ErrorDescription: "Failed to login: " + err.Error(),

View file

@ -163,6 +163,8 @@ type OIDCAddress = oauthtypes.OIDCAddress
// LoginResponse represents the response for login // LoginResponse represents the response for login
type LoginResponse struct { type LoginResponse struct {
UserID string `json:"user_id,omitempty"`
Subject string `json:"subject,omitempty"`
AccessToken string `json:"access_token"` AccessToken string `json:"access_token"`
IDToken string `json:"id_token,omitempty"` IDToken string `json:"id_token,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"` RefreshToken string `json:"refresh_token,omitempty"`

View file

@ -264,22 +264,6 @@ func attachThirdParty(group *gin.RouterGroup, oauth types.OAuth) {
} }
// getTeamConfig returns the team configuration
func getTeamConfig(c *gin.Context) {
locale := c.Query("locale")
if locale == "" {
locale = "en" // default locale
}
config := GetTeamConfig(locale)
if config == nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Team configuration not found"})
return
}
c.JSON(http.StatusOK, config)
}
func placeholder(c *gin.Context) { func placeholder(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Hello, World!"}) c.JSON(http.StatusOK, gin.H{"message": "Hello, World!"})
} }