Skip to content

Commit 85e4d6e

Browse files
authored
Merge branch 'Wei-Shaw:main' into feature/user-fields-enhancement
2 parents 907effd + 5f7e518 commit 85e4d6e

52 files changed

Lines changed: 4116 additions & 549 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

backend/cmd/server/wire.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ func provideCleanup(
8585
services.EmailQueue.Stop()
8686
return nil
8787
}},
88+
{"OAuthService", func() error {
89+
services.OAuth.Stop()
90+
return nil
91+
}},
92+
{"OpenAIOAuthService", func() error {
93+
services.OpenAIOAuth.Stop()
94+
return nil
95+
}},
8896
{"Redis", func() error {
8997
return rdb.Close()
9098
}},

backend/cmd/server/wire_gen.go

Lines changed: 48 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/internal/handler/admin/account_handler.go

Lines changed: 83 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"strconv"
55

66
"sub2api/internal/pkg/claude"
7+
"sub2api/internal/pkg/openai"
78
"sub2api/internal/pkg/response"
89
"sub2api/internal/service"
910

@@ -26,16 +27,18 @@ func NewOAuthHandler(oauthService *service.OAuthService) *OAuthHandler {
2627
type AccountHandler struct {
2728
adminService service.AdminService
2829
oauthService *service.OAuthService
30+
openaiOAuthService *service.OpenAIOAuthService
2931
rateLimitService *service.RateLimitService
3032
accountUsageService *service.AccountUsageService
3133
accountTestService *service.AccountTestService
3234
}
3335

3436
// NewAccountHandler creates a new admin account handler
35-
func NewAccountHandler(adminService service.AdminService, oauthService *service.OAuthService, rateLimitService *service.RateLimitService, accountUsageService *service.AccountUsageService, accountTestService *service.AccountTestService) *AccountHandler {
37+
func NewAccountHandler(adminService service.AdminService, oauthService *service.OAuthService, openaiOAuthService *service.OpenAIOAuthService, rateLimitService *service.RateLimitService, accountUsageService *service.AccountUsageService, accountTestService *service.AccountTestService) *AccountHandler {
3638
return &AccountHandler{
3739
adminService: adminService,
3840
oauthService: oauthService,
41+
openaiOAuthService: openaiOAuthService,
3942
rateLimitService: rateLimitService,
4043
accountUsageService: accountUsageService,
4144
accountTestService: accountTestService,
@@ -232,26 +235,47 @@ func (h *AccountHandler) Refresh(c *gin.Context) {
232235
return
233236
}
234237

235-
// Use OAuth service to refresh token
236-
tokenInfo, err := h.oauthService.RefreshAccountToken(c.Request.Context(), account)
237-
if err != nil {
238-
response.InternalError(c, "Failed to refresh credentials: "+err.Error())
239-
return
240-
}
238+
var newCredentials map[string]any
241239

242-
// Copy existing credentials to preserve non-token settings (e.g., intercept_warmup_requests)
243-
newCredentials := make(map[string]any)
244-
for k, v := range account.Credentials {
245-
newCredentials[k] = v
246-
}
240+
if account.IsOpenAI() {
241+
// Use OpenAI OAuth service to refresh token
242+
tokenInfo, err := h.openaiOAuthService.RefreshAccountToken(c.Request.Context(), account)
243+
if err != nil {
244+
response.InternalError(c, "Failed to refresh credentials: "+err.Error())
245+
return
246+
}
247+
248+
// Build new credentials from token info
249+
newCredentials = h.openaiOAuthService.BuildAccountCredentials(tokenInfo)
247250

248-
// Update token-related fields
249-
newCredentials["access_token"] = tokenInfo.AccessToken
250-
newCredentials["token_type"] = tokenInfo.TokenType
251-
newCredentials["expires_in"] = tokenInfo.ExpiresIn
252-
newCredentials["expires_at"] = tokenInfo.ExpiresAt
253-
newCredentials["refresh_token"] = tokenInfo.RefreshToken
254-
newCredentials["scope"] = tokenInfo.Scope
251+
// Preserve non-token settings from existing credentials
252+
for k, v := range account.Credentials {
253+
if _, exists := newCredentials[k]; !exists {
254+
newCredentials[k] = v
255+
}
256+
}
257+
} else {
258+
// Use Anthropic/Claude OAuth service to refresh token
259+
tokenInfo, err := h.oauthService.RefreshAccountToken(c.Request.Context(), account)
260+
if err != nil {
261+
response.InternalError(c, "Failed to refresh credentials: "+err.Error())
262+
return
263+
}
264+
265+
// Copy existing credentials to preserve non-token settings (e.g., intercept_warmup_requests)
266+
newCredentials = make(map[string]any)
267+
for k, v := range account.Credentials {
268+
newCredentials[k] = v
269+
}
270+
271+
// Update token-related fields
272+
newCredentials["access_token"] = tokenInfo.AccessToken
273+
newCredentials["token_type"] = tokenInfo.TokenType
274+
newCredentials["expires_in"] = tokenInfo.ExpiresIn
275+
newCredentials["expires_at"] = tokenInfo.ExpiresAt
276+
newCredentials["refresh_token"] = tokenInfo.RefreshToken
277+
newCredentials["scope"] = tokenInfo.Scope
278+
}
255279

256280
updatedAccount, err := h.adminService.UpdateAccount(c.Request.Context(), accountID, &service.UpdateAccountInput{
257281
Credentials: newCredentials,
@@ -563,6 +587,46 @@ func (h *AccountHandler) GetAvailableModels(c *gin.Context) {
563587
return
564588
}
565589

590+
// Handle OpenAI accounts
591+
if account.IsOpenAI() {
592+
// For OAuth accounts: return default OpenAI models
593+
if account.IsOAuth() {
594+
response.Success(c, openai.DefaultModels)
595+
return
596+
}
597+
598+
// For API Key accounts: check model_mapping
599+
mapping := account.GetModelMapping()
600+
if len(mapping) == 0 {
601+
response.Success(c, openai.DefaultModels)
602+
return
603+
}
604+
605+
// Return mapped models
606+
var models []openai.Model
607+
for requestedModel := range mapping {
608+
var found bool
609+
for _, dm := range openai.DefaultModels {
610+
if dm.ID == requestedModel {
611+
models = append(models, dm)
612+
found = true
613+
break
614+
}
615+
}
616+
if !found {
617+
models = append(models, openai.Model{
618+
ID: requestedModel,
619+
Object: "model",
620+
Type: "model",
621+
DisplayName: requestedModel,
622+
})
623+
}
624+
}
625+
response.Success(c, models)
626+
return
627+
}
628+
629+
// Handle Claude/Anthropic accounts
566630
// For OAuth and Setup-Token accounts: return default models
567631
if account.IsOAuth() {
568632
response.Success(c, claude.DefaultModels)

0 commit comments

Comments
 (0)