From 93641dea58fb61ae0acd1e9627bf5679c599ed47 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 3 Apr 2026 10:28:07 +0800 Subject: [PATCH] feat(profile): add endpoint to retrieve linked OAuth accounts for the user - Implemented the GinProfileProviders function to fetch and return the current user's linked OAuth accounts. - Added error handling for authentication and provider retrieval, ensuring proper responses for unauthorized access and server errors. - Updated the user routing to include a new GET endpoint for accessing linked OAuth providers. --- openapi/user/profile.go | 43 +++++++++++++++++++++++++++++++++++++++++ openapi/user/user.go | 5 +++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/openapi/user/profile.go b/openapi/user/profile.go index c7bc366d..0d17ef02 100644 --- a/openapi/user/profile.go +++ b/openapi/user/profile.go @@ -430,3 +430,46 @@ func buildProfileUpdateRequest(data map[string]interface{}) ProfileUpdateRequest return req } + +// GinProfileProviders returns the current user's linked OAuth accounts +func GinProfileProviders(c *gin.Context) { + authInfo := authorized.GetInfo(c) + if authInfo == nil || authInfo.UserID == "" { + response.RespondWithError(c, response.StatusUnauthorized, &response.ErrorResponse{ + Code: response.ErrInvalidClient.Code, + ErrorDescription: "User not authenticated", + }) + return + } + + provider, err := getUserProvider() + if err != nil { + response.RespondWithError(c, response.StatusInternalServerError, &response.ErrorResponse{ + Code: response.ErrServerError.Code, + ErrorDescription: "Failed to get user provider", + }) + return + } + + accounts, err := provider.GetUserOAuthAccounts(c.Request.Context(), authInfo.UserID) + if err != nil { + log.Error("Failed to get OAuth accounts for user %s: %v", authInfo.UserID, err) + response.RespondWithError(c, response.StatusInternalServerError, &response.ErrorResponse{ + Code: response.ErrServerError.Code, + ErrorDescription: "Failed to retrieve linked accounts", + }) + return + } + + if accounts == nil { + accounts = []maps.MapStrAny{} + } + + for i := range accounts { + if email, ok := accounts[i]["email"].(string); ok && email != "" { + accounts[i]["email"] = MaskEmail(email) + } + } + + response.RespondWithSuccess(c, response.StatusOK, accounts) +} diff --git a/openapi/user/user.go b/openapi/user/user.go index e5f731db..4ea4f201 100644 --- a/openapi/user/user.go +++ b/openapi/user/user.go @@ -250,8 +250,9 @@ func attachSubscription(group *gin.RouterGroup, oauth types.OAuth) { // User profile management func attachProfile(group *gin.RouterGroup, oauth types.OAuth) { - group.GET("/profile", oauth.Guard, GinProfileGet) // Get user profile - group.PUT("/profile", oauth.Guard, GinProfileUpdate) // Update user profile + group.GET("/profile", oauth.Guard, GinProfileGet) // Get user profile + group.PUT("/profile", oauth.Guard, GinProfileUpdate) // Update user profile + group.GET("/profile/providers", oauth.Guard, GinProfileProviders) // Get linked OAuth providers } // User management (CRUD)