diff --git a/electron.vite.config.ts b/electron.vite.config.ts index bd45020f..d90ddbd8 100644 --- a/electron.vite.config.ts +++ b/electron.vite.config.ts @@ -1,4 +1,3 @@ -import { existsSync, readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; import { dirname, resolve } from "node:path"; import { defineConfig, externalizeDepsPlugin } from "electron-vite"; @@ -6,27 +5,9 @@ import react from "@vitejs/plugin-react"; const __dirname = dirname(fileURLToPath(import.meta.url)); -/** - * The Composio integration key is compiled into the main-process bundle so - * no credential file ever ships with the app. It lives in cred.txt at the - * repository root (first line "Composio apikey: ak_..."), committed on - * purpose — private repo, and every checkout must build a configured app. - * A checkout without the file builds an app whose connector features report - * the integration as unconfigured. Rotation = update cred.txt, rebuild. - */ -function composioApiKeyForBuild(): string { - const credPath = resolve(__dirname, "cred.txt"); - if (!existsSync(credPath)) return ""; - const firstLine = readFileSync(credPath, "utf8").split("\n")[0] ?? ""; - return firstLine.split(":").slice(1).join(":").trim(); -} - export default defineConfig({ main: { plugins: [externalizeDepsPlugin()], - define: { - __COMPOSIO_API_KEY__: JSON.stringify(composioApiKeyForBuild()), - }, resolve: { alias: { "@shared": resolve(__dirname, "src/shared"), diff --git a/src/main/env.d.ts b/src/main/env.d.ts deleted file mode 100644 index f4ff5f5e..00000000 --- a/src/main/env.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Build-time constants injected by electron.vite.config.ts (`define`). - * Vitest runs without the bundler, so the identifier may not exist at - * runtime — always read it through a `typeof` guard. - */ -declare const __COMPOSIO_API_KEY__: string | undefined; diff --git a/src/main/services/composio/composio-credentials.ts b/src/main/services/composio/composio-credentials.ts index 3d1b8466..4b3004e9 100644 --- a/src/main/services/composio/composio-credentials.ts +++ b/src/main/services/composio/composio-credentials.ts @@ -1,13 +1,12 @@ /** - * The Composio integration key ships inside the compiled main-process - * bundle: electron.vite.config.ts reads cred.txt at the repository root - * during build and injects the key as __COMPOSIO_API_KEY__. - * No credential file is packaged, nothing is persisted to the database, and - * the key is never user-visible or configurable. Rotating the key means - * updating cred.txt and rebuilding. + * The Composio integration key is hardcoded on purpose: the repo is private + * and every checkout must build a configured app, with no credential file or + * build-time injection involved. Rotating the key = editing this constant. */ +const COMPOSIO_API_KEY = "***REMOVED***"; + export function composioApiKey(): string | null { - return normalizeComposioApiKey(typeof __COMPOSIO_API_KEY__ === "string" ? __COMPOSIO_API_KEY__ : ""); + return normalizeComposioApiKey(COMPOSIO_API_KEY); } /** Null for blank input so callers surface "not configured" explicitly. */ diff --git a/tests/unit/composio-credentials.test.ts b/tests/unit/composio-credentials.test.ts index 143011d7..11644c18 100644 --- a/tests/unit/composio-credentials.test.ts +++ b/tests/unit/composio-credentials.test.ts @@ -11,9 +11,7 @@ describe("composio credential resolution", () => { expect(normalizeComposioApiKey(" ")).toBeNull(); }); - test("without the build-time injection the key is null", () => { - // Vitest runs without the electron-vite define — the same shape as a - // build from a checkout that has no cred.txt. - expect(composioApiKey()).toBeNull(); + test("the hardcoded key resolves in every build", () => { + expect(composioApiKey()).toBe("***REMOVED***"); }); });