diff --git a/open-sse/providers/registry/antigravity.js b/open-sse/providers/registry/antigravity.js index 65f6083a..419a9779 100644 --- a/open-sse/providers/registry/antigravity.js +++ b/open-sse/providers/registry/antigravity.js @@ -1,4 +1,5 @@ import { platform, arch } from "os"; +import { ANTIGRAVITY_OAUTH_CLIENT } from "../shared.js"; export default { id: "antigravity", @@ -10,8 +11,7 @@ export default { ], format: "antigravity", headers: { "User-Agent": `antigravity/1.107.0 ${platform()}/${arch()}` }, - clientId: "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com", - clientSecret: "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" + ...ANTIGRAVITY_OAUTH_CLIENT }, models: [ { id: "gemini-3-flash-agent", name: "Gemini 3.5 Flash (High)" }, diff --git a/open-sse/providers/registry/gemini-cli.js b/open-sse/providers/registry/gemini-cli.js index df1269c4..bd868d3d 100644 --- a/open-sse/providers/registry/gemini-cli.js +++ b/open-sse/providers/registry/gemini-cli.js @@ -1,11 +1,12 @@ +import { GOOGLE_OAUTH_CLIENT } from "../shared.js"; + export default { "id": "gemini-cli", "alias": "gc", "transport": { "baseUrl": "https://cloudcode-pa.googleapis.com/v1internal", "format": "gemini-cli", - "clientId": "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com", - "clientSecret": "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" + ...GOOGLE_OAUTH_CLIENT }, "models": [ { diff --git a/open-sse/providers/registry/gemini.js b/open-sse/providers/registry/gemini.js index be3fbbb4..5fdc7e95 100644 --- a/open-sse/providers/registry/gemini.js +++ b/open-sse/providers/registry/gemini.js @@ -1,11 +1,12 @@ +import { GOOGLE_OAUTH_CLIENT } from "../shared.js"; + export default { "id": "gemini", "alias": "gemini", "transport": { "baseUrl": "https://generativelanguage.googleapis.com/v1beta/models", "format": "gemini", - "clientId": "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com", - "clientSecret": "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" + ...GOOGLE_OAUTH_CLIENT }, "models": [ { diff --git a/open-sse/providers/shared.js b/open-sse/providers/shared.js index e4fad1e1..d31c1856 100644 --- a/open-sse/providers/shared.js +++ b/open-sse/providers/shared.js @@ -46,3 +46,15 @@ export const CLAUDE_CLI_SPOOF_HEADERS = { // Shared baseUrls export const KIMI_CODING_BASE_URL = "https://api.kimi.com/coding/v1/messages"; + +// Antigravity OAuth client credentials (public CLI client — duplicated in usage.js + src/lib/oauth) +export const ANTIGRAVITY_OAUTH_CLIENT = { + clientId: "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com", + clientSecret: "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" +}; + +// Gemini (Google) OAuth client credentials (public CLI client — shared by gemini, gemini-cli, src/lib/oauth) +export const GOOGLE_OAUTH_CLIENT = { + clientId: "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com", + clientSecret: "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" +}; diff --git a/open-sse/services/usage.js b/open-sse/services/usage.js index 9425f09d..e994b9bc 100644 --- a/open-sse/services/usage.js +++ b/open-sse/services/usage.js @@ -5,6 +5,7 @@ import { CLIENT_METADATA, getPlatformUserAgent } from "../config/appConstants.js"; import { proxyAwareFetch } from "../utils/proxyFetch.js"; import { resolveDefaultProfileArn } from "../config/kiroConstants.js"; +import { ANTIGRAVITY_OAUTH_CLIENT } from "../providers/shared.js"; // GitHub API config const GITHUB_CONFIG = { @@ -40,8 +41,7 @@ const ANTIGRAVITY_CONFIG = { quotaApiUrl: "https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels", loadProjectApiUrl: "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist", tokenUrl: "https://oauth2.googleapis.com/token", - clientId: "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com", - clientSecret: "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", + ...ANTIGRAVITY_OAUTH_CLIENT, userAgent: getPlatformUserAgent(), }; diff --git a/src/lib/oauth/constants/oauth.js b/src/lib/oauth/constants/oauth.js index dc825b30..66ab7134 100644 --- a/src/lib/oauth/constants/oauth.js +++ b/src/lib/oauth/constants/oauth.js @@ -2,6 +2,7 @@ * OAuth Configuration Constants */ import { platform, arch } from "os"; +import { ANTIGRAVITY_OAUTH_CLIENT, GOOGLE_OAUTH_CLIENT } from "open-sse/providers/shared.js"; /** * Get the platform enum value based on the current OS. @@ -42,8 +43,7 @@ export const CODEX_CONFIG = { // Gemini (Google) OAuth Configuration (Standard OAuth2) export const GEMINI_CONFIG = { - clientId: "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com", - clientSecret: "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", + ...GOOGLE_OAUTH_CLIENT, authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth", tokenUrl: "https://oauth2.googleapis.com/token", userInfoUrl: "https://www.googleapis.com/oauth2/v1/userinfo", @@ -94,8 +94,7 @@ export const IFLOW_CONFIG = { // Antigravity OAuth Configuration (Standard OAuth2 with Google) export const ANTIGRAVITY_CONFIG = { - clientId: "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com", - clientSecret: "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", + ...ANTIGRAVITY_OAUTH_CLIENT, authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth", tokenUrl: "https://oauth2.googleapis.com/token", userInfoUrl: "https://www.googleapis.com/oauth2/v1/userinfo", diff --git a/tests/unit/antigravity-oauth-client.test.js b/tests/unit/antigravity-oauth-client.test.js new file mode 100644 index 00000000..a43bd8ff --- /dev/null +++ b/tests/unit/antigravity-oauth-client.test.js @@ -0,0 +1,49 @@ +// Guards the deduped Antigravity OAuth client: same values across all 3 sources after refactor. +import { describe, it, expect } from "vitest"; + +const EXPECTED = { + clientId: "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com", + clientSecret: "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", +}; +const GOOGLE = { + clientId: "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com", + clientSecret: "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", +}; + +describe("antigravity oauth client (deduped)", () => { + it("shared source holds the canonical credentials", async () => { + const { ANTIGRAVITY_OAUTH_CLIENT } = await import("../../open-sse/providers/shared.js"); + expect(ANTIGRAVITY_OAUTH_CLIENT).toEqual(EXPECTED); + }); + + it("registry transport keeps clientId/clientSecret", async () => { + const ag = (await import("../../open-sse/providers/registry/antigravity.js")).default; + expect(ag.transport.clientId).toBe(EXPECTED.clientId); + expect(ag.transport.clientSecret).toBe(EXPECTED.clientSecret); + }); + + it("google client shared by gemini + gemini-cli", async () => { + const { GOOGLE_OAUTH_CLIENT } = await import("../../open-sse/providers/shared.js"); + expect(GOOGLE_OAUTH_CLIENT).toEqual(GOOGLE); + const gemini = (await import("../../open-sse/providers/registry/gemini.js")).default; + const gc = (await import("../../open-sse/providers/registry/gemini-cli.js")).default; + expect(gemini.transport.clientSecret).toBe(GOOGLE.clientSecret); + expect(gc.transport.clientSecret).toBe(GOOGLE.clientSecret); + }); + + // Vitest can't resolve the `@/` alias used inside oauth.js (pre-existing infra gap), + // so guard the refactor textually: it must spread the shared client + keep other fields. + it("src oauth.js imports shared client + keeps full shape", async () => { + const { readFileSync } = await import("node:fs"); + const { fileURLToPath } = await import("node:url"); + const { dirname, join } = await import("node:path"); + const here = dirname(fileURLToPath(import.meta.url)); + const src = readFileSync(join(here, "../../src/lib/oauth/constants/oauth.js"), "utf8"); + expect(src).toContain('import { ANTIGRAVITY_OAUTH_CLIENT, GOOGLE_OAUTH_CLIENT } from "open-sse/providers/shared.js"'); + expect(src).toContain("...ANTIGRAVITY_OAUTH_CLIENT"); + expect(src).toContain("...GOOGLE_OAUTH_CLIENT"); + expect(src).toContain('authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth"'); + expect(src).not.toContain(EXPECTED.clientSecret); // antigravity secret no longer hardcoded here + expect(src).not.toContain(GOOGLE.clientSecret); // gemini secret no longer hardcoded here + }); +});