Unified · Split
| @@ -1148,13 +1148,9 @@ func (h *Handler) RequestGeminiCLIToken(c *gin.Context) { · 1147 unmodified lines | ||
| 1148 | 1148 | } |
| 1149 | 1149 | |
| 1150 | 1150 | ifToken["token_uri"] = "https://oauth2.googleapis.com/token" |
| 1151 | − ifToken["client_id"] = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com" | |
| 1152 | − ifToken["client_secret"] = "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" | |
| 1153 | − ifToken["scopes"] = []string{ | |
| 1154 | − "https://www.googleapis.com/auth/cloud-platform", | |
| 1155 | − "https://www.googleapis.com/auth/userinfo.email", | |
| 1156 | − "https://www.googleapis.com/auth/userinfo.profile", | |
| 1157 | − } | |
| 1151 | + ifToken["client_id"] = geminiAuth.ClientID | |
| 1152 | + ifToken["client_secret"] = geminiAuth.ClientSecret | |
| 1153 | + ifToken["scopes"] = geminiAuth.Scopes | |
| 1158 | 1154 | ifToken["universe_domain"] = "googleapis.com" |
| 1159 | 1155 | |
| 1160 | 1156 | ts := geminiAuth.GeminiTokenStorage{ |
| @@ -1478,20 +1474,29 @@ func (h *Handler) RequestAntigravityToken(c *gin.Context) { · 317 unmodified lines | ||
| 1478 | 1474 | return |
| 1479 | 1475 | } |
| 1480 | 1476 | |
| 1481 | − email := "" | |
| 1482 | − if strings.TrimSpace(tokenResp.AccessToken) != "" { | |
| 1483 | − fetchedEmail, errInfo := authSvc.FetchUserInfo(ctx, tokenResp.AccessToken) | |
| 1484 | − if errInfo != nil { | |
| 1485 | − log.Errorf("Failed to fetch user info: %v", errInfo) | |
| 1486 | − SetOAuthSessionError(state, "Failed to fetch user info") | |
| 1487 | − return | |
| 1488 | − } | |
| 1489 | − email = strings.TrimSpace(fetchedEmail) | |
| 1477 | + accessToken := strings.TrimSpace(tokenResp.AccessToken) | |
| 1478 | + if accessToken == "" { | |
| 1479 | + log.Error("antigravity: token exchange returned empty access token") | |
| 1480 | + SetOAuthSessionError(state, "Failed to exchange token") | |
| 1481 | + return | |
| 1482 | + } | |
| 1483 | + | |
| 1484 | + email, errInfo := authSvc.FetchUserInfo(ctx, accessToken) | |
| 1485 | + if errInfo != nil { | |
| 1486 | + log.Errorf("Failed to fetch user info: %v", errInfo) | |
| 1487 | + SetOAuthSessionError(state, "Failed to fetch user info") | |
| 1488 | + return | |
| 1489 | + } | |
| 1490 | + email = strings.TrimSpace(email) | |
| 1491 | + if email == "" { | |
| 1492 | + log.Error("antigravity: user info returned empty email") | |
| 1493 | + SetOAuthSessionError(state, "Failed to fetch user info") | |
| 1494 | + return | |
| 1490 | 1495 | } |
| 1491 | 1496 | |
| 1492 | 1497 | projectID := "" |
| 1493 | − if strings.TrimSpace(tokenResp.AccessToken) != "" { | |
| 1494 | − fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, tokenResp.AccessToken) | |
| 1498 | + if accessToken != "" { | |
| 1499 | + fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, accessToken) | |
| 1495 | 1500 | if errProject != nil { |
| 1496 | 1501 | log.Warnf("antigravity: failed to fetch project ID: %v", errProject) |
| 1497 | 1502 | } else { |
| @@ -100,18 +100,19 @@ func (o *AntigravityAuth) ExchangeCodeForTokens(ctx context.Context, code, redir · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | // FetchUserInfo retrieves user email from Google |
| 102 | 102 | func (o *AntigravityAuth) FetchUserInfo(ctx context.Context, accessToken string) (string, error) { |
| 103 | − if strings.TrimSpace(accessToken) == "" { | |
| 104 | − return "", nil | |
| 103 | + accessToken = strings.TrimSpace(accessToken) | |
| 104 | + if accessToken == "" { | |
| 105 | + return "", fmt.Errorf("antigravity userinfo: missing access token") | |
| 105 | 106 | } |
| 106 | 107 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, UserInfoEndpoint, nil) |
| 107 | 108 | if err != nil { |
| 108 | − return "", err | |
| 109 | + return "", fmt.Errorf("antigravity userinfo: create request: %w", err) | |
| 109 | 110 | } |
| 110 | 111 | req.Header.Set("Authorization", "Bearer "+accessToken) |
| 111 | 112 | |
| 112 | 113 | resp, errDo := o.httpClient.Do(req) |
| 113 | 114 | if errDo != nil { |
| 114 | − return "", errDo | |
| 115 | + return "", fmt.Errorf("antigravity userinfo: execute request: %w", errDo) | |
| 115 | 116 | } |
| 116 | 117 | defer func() { |
| 117 | 118 | if errClose := resp.Body.Close(); errClose != nil { |
| @@ -120,13 +121,25 @@ func (o *AntigravityAuth) FetchUserInfo(ctx context.Context, accessToken string) · 2 unmodified lines | ||
| 120 | 121 | }() |
| 121 | 122 | |
| 122 | 123 | if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices { |
| 123 | − return "", nil | |
| 124 | + bodyBytes, errRead := io.ReadAll(io.LimitReader(resp.Body, 8<<10)) | |
| 125 | + if errRead != nil { | |
| 126 | + return "", fmt.Errorf("antigravity userinfo: read response: %w", errRead) | |
| 127 | + } | |
| 128 | + body := strings.TrimSpace(string(bodyBytes)) | |
| 129 | + if body == "" { | |
| 130 | + return "", fmt.Errorf("antigravity userinfo: request failed: status %d", resp.StatusCode) | |
| 131 | + } | |
| 132 | + return "", fmt.Errorf("antigravity userinfo: request failed: status %d: %s", resp.StatusCode, body) | |
| 124 | 133 | } |
| 125 | 134 | var info userInfo |
| 126 | 135 | if errDecode := json.NewDecoder(resp.Body).Decode(&info); errDecode != nil { |
| 127 | − return "", errDecode | |
| 136 | + return "", fmt.Errorf("antigravity userinfo: decode response: %w", errDecode) | |
| 137 | + } | |
| 138 | + email := strings.TrimSpace(info.Email) | |
| 139 | + if email == "" { | |
| 140 | + return "", fmt.Errorf("antigravity userinfo: response missing email") | |
| 128 | 141 | } |
| 129 | − return info.Email, nil | |
| 142 | + return email, nil | |
| 130 | 143 | } |
| 131 | 144 | |
| 132 | 145 | // FetchProjectID retrieves the project ID for the authenticated user via loadCodeAssist |
| @@ -153,17 +153,24 @@ waitForCallback: · 152 unmodified lines | ||
| 153 | 153 | return nil, fmt.Errorf("antigravity: token exchange failed: %w", errToken) |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | − email := "" | |
| 157 | − if tokenResp.AccessToken != "" { | |
| 158 | − if fetchedEmail, errInfo := authSvc.FetchUserInfo(ctx, tokenResp.AccessToken); errInfo == nil && strings.TrimSpace(fetchedEmail) != "" { | |
| 159 | − email = strings.TrimSpace(fetchedEmail) | |
| 160 | − } | |
| 156 | + accessToken := strings.TrimSpace(tokenResp.AccessToken) | |
| 157 | + if accessToken == "" { | |
| 158 | + return nil, fmt.Errorf("antigravity: token exchange returned empty access token") | |
| 159 | + } | |
| 160 | + | |
| 161 | + email, errInfo := authSvc.FetchUserInfo(ctx, accessToken) | |
| 162 | + if errInfo != nil { | |
| 163 | + return nil, fmt.Errorf("antigravity: fetch user info failed: %w", errInfo) | |
| 164 | + } | |
| 165 | + email = strings.TrimSpace(email) | |
| 166 | + if email == "" { | |
| 167 | + return nil, fmt.Errorf("antigravity: empty email returned from user info") | |
| 161 | 168 | } |
| 162 | 169 | |
| 163 | 170 | // Fetch project ID via loadCodeAssist (same approach as Gemini CLI) |
| 164 | 171 | projectID := "" |
| 165 | − if tokenResp.AccessToken != "" { | |
| 166 | − fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, tokenResp.AccessToken) | |
| 172 | + if accessToken != "" { | |
| 173 | + fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, accessToken) | |
| 167 | 174 | if errProject != nil { |
| 168 | 175 | log.Warnf("antigravity: failed to fetch project ID: %v", errProject) |
| 169 | 176 | } else { |