Big update
This commit is contained in:
parent
8b607dd700
commit
2e6afc460b
474 changed files with 934 additions and 86159 deletions
|
|
@ -26,6 +26,8 @@ const (
|
|||
|
||||
var antigravityOAuthTokenURL = "https://oauth2.googleapis.com/token"
|
||||
|
||||
var codexUsageURL = "https://chatgpt.com/backend-api/wham/usage"
|
||||
|
||||
type apiCallRequest struct {
|
||||
AuthIndexSnake *string `json:"auth_index"`
|
||||
AuthIndexCamel *string `json:"authIndex"`
|
||||
|
|
@ -43,6 +45,83 @@ type apiCallResponse struct {
|
|||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
// CodexQuota fetches the usage payload for one exact Codex credential.
|
||||
func (h *Handler) CodexQuota(c *gin.Context) {
|
||||
var body struct {
|
||||
AuthIndexSnake *string `json:"auth_index"`
|
||||
AuthIndexCamel *string `json:"authIndex"`
|
||||
Method string `json:"method"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
if errBindJSON := c.ShouldBindJSON(&body); errBindJSON != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
|
||||
return
|
||||
}
|
||||
|
||||
authIndex := firstNonEmptyString(body.AuthIndexSnake, body.AuthIndexCamel)
|
||||
if authIndex == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "auth_index is required"})
|
||||
return
|
||||
}
|
||||
if method := strings.ToUpper(strings.TrimSpace(body.Method)); method != "" && method != http.MethodGet {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "only GET is allowed"})
|
||||
return
|
||||
}
|
||||
if requestedURL := strings.TrimSpace(body.URL); requestedURL != "" && requestedURL != codexUsageURL {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "url is not allowed"})
|
||||
return
|
||||
}
|
||||
|
||||
auth := h.authByIndex(authIndex)
|
||||
if auth == nil || !strings.EqualFold(strings.TrimSpace(auth.Provider), "codex") {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Codex auth not found"})
|
||||
return
|
||||
}
|
||||
token := tokenValueForAuth(auth)
|
||||
if token == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Codex auth token not found"})
|
||||
return
|
||||
}
|
||||
|
||||
req, errNewRequest := http.NewRequestWithContext(c.Request.Context(), http.MethodGet, codexUsageURL, nil)
|
||||
if errNewRequest != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to build request"})
|
||||
return
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("User-Agent", "codex_cli_rs/0.76.0 (Debian 13.0.0; x86_64) WindowsTerminal")
|
||||
if accountID, ok := auth.Metadata["account_id"].(string); ok && strings.TrimSpace(accountID) != "" {
|
||||
req.Header.Set("Chatgpt-Account-Id", strings.TrimSpace(accountID))
|
||||
}
|
||||
|
||||
resp, errDo := (&http.Client{
|
||||
Transport: h.apiCallTransport(auth, ""),
|
||||
}).Do(req)
|
||||
if errDo != nil {
|
||||
log.WithError(errDo).Debug("management Codex quota request failed")
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": "request failed"})
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if errClose := resp.Body.Close(); errClose != nil {
|
||||
log.Errorf("Codex quota response body close error: %v", errClose)
|
||||
}
|
||||
}()
|
||||
|
||||
respBody, errReadAll := io.ReadAll(resp.Body)
|
||||
if errReadAll != nil {
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": "failed to read response"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, apiCallResponse{
|
||||
StatusCode: resp.StatusCode,
|
||||
Header: resp.Header,
|
||||
Body: string(respBody),
|
||||
})
|
||||
}
|
||||
|
||||
// APICall makes a generic HTTP request on behalf of the management API caller.
|
||||
// It is protected by the management middleware.
|
||||
//
|
||||
|
|
|
|||
Loading…
Reference in a new issue