Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions packages/ui-mac/src/main/alpha-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { join } from "node:path"
import { safeStorage, shell, type BrowserWindow } from "electron"
import type { AuthMode, AuthState } from "../preload/types"
import { getLogger } from "./logging"
import { ALPHA_ENDPOINTS, ALPHA_PATHS } from "../shared/alpha-config"

type StoredAuth = {
mode: AuthMode
Expand All @@ -42,11 +43,12 @@ const CLIENT_ID = "alpha-code"
const REDIRECT_URI = "alpha-code://auth/callback"
const AUTH_FILE = "alpha-auth.json"

// Endpoints default to alphacodeone.com (subdomain split) and are env-overridable for dev/staging.
// ALPHA_WEB_URL = alpha-web (C, identity authority — login/token); ALPHA_PLATFORM_URL =
// alpha-platform (B, model proxy at /v1 + MCP gateway at /mcp).
const webBase = () => (process.env.ALPHA_WEB_URL ?? "https://auth.alphacodeone.com").replace(/\/+$/, "")
const platformBase = () => (process.env.ALPHA_PLATFORM_URL ?? "https://api.alphacodeone.com").replace(/\/+$/, "")
// Endpoint defaults live in shared/alpha-config (single source of truth — change a domain THERE,
// not here). This layer only adds the env overrides for dev/staging: ALPHA_WEB_URL = alpha-web
// (C, identity authority — login/token); ALPHA_PLATFORM_URL = alpha-platform (B, model proxy /v1 +
// MCP gateway /mcp).
const webBase = () => (process.env.ALPHA_WEB_URL ?? ALPHA_ENDPOINTS.web).replace(/\/+$/, "")
const platformBase = () => (process.env.ALPHA_PLATFORM_URL ?? ALPHA_ENDPOINTS.platform).replace(/\/+$/, "")

let userDataPath = ""
let getWindow: () => BrowserWindow | null = () => null
Expand Down Expand Up @@ -133,9 +135,9 @@ export function applyAuthEnv() {
const token = devToken || (loggedInPlatform ? stored.accessToken : undefined)
const base = platformBase()
if (!token || !base) return
if (!process.env.ALPHA_BASE_URL) process.env.ALPHA_BASE_URL = `${base}/v1`
if (!process.env.ALPHA_BASE_URL) process.env.ALPHA_BASE_URL = `${base}${ALPHA_PATHS.modelProxy}`
if (!process.env.ALPHA_API_KEY) process.env.ALPHA_API_KEY = token
if (!process.env.ALPHA_CLOUD_MCP_URL) process.env.ALPHA_CLOUD_MCP_URL = `${base}/mcp`
if (!process.env.ALPHA_CLOUD_MCP_URL) process.env.ALPHA_CLOUD_MCP_URL = `${base}${ALPHA_PATHS.mcpGateway}`
if (!process.env.ALPHA_CLOUD_TOKEN) process.env.ALPHA_CLOUD_TOKEN = token
}

Expand Down Expand Up @@ -168,7 +170,7 @@ export async function startAuth(): Promise<void> {
const challenge = base64url(createHash("sha256").update(verifier).digest())
const state = randomUUID()
pkce = { verifier, state }
const url = new URL(`${webBase()}/auth/authorize`)
const url = new URL(`${webBase()}${ALPHA_PATHS.authorize}`)
url.searchParams.set("response_type", "code")
url.searchParams.set("client_id", CLIENT_ID)
url.searchParams.set("redirect_uri", REDIRECT_URI)
Expand Down Expand Up @@ -227,7 +229,7 @@ async function completeAuth(parsed: URL) {
}

async function exchangeCode(code: string, verifier: string): Promise<TokenResponse> {
const res = await fetch(`${webBase()}/auth/token`, {
const res = await fetch(`${webBase()}${ALPHA_PATHS.token}`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
Expand Down
3 changes: 2 additions & 1 deletion packages/ui-mac/src/renderer/sidebar/alpha-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Icon } from "@opencode-ai/ui/v2/icon"
import { useTheme } from "@opencode-ai/ui/theme/context"
import { t } from "../i18n"
import { Mark } from "../logo-alpha"
import { ALPHA_ENDPOINTS, ALPHA_PATHS } from "../../shared/alpha-config"
import { base64UrlDecode, homeHref, newSessionHref, projectLabel, sessionHref } from "./route"
import {
clearHiddenProjects,
Expand Down Expand Up @@ -107,7 +108,7 @@ export function AlphaSidebar(props: { server: Accessor<ServerInfo | undefined> }
{ k: "dark", l: "深色" },
{ k: "system", l: "系统" },
] as const
const billingUrl = "https://auth.alphacodeone.com/billing"
const billingUrl = `${ALPHA_ENDPOINTS.web}${ALPHA_PATHS.billing}`

const MenuCommon = () => (
<>
Expand Down
27 changes: 27 additions & 0 deletions packages/ui-mac/src/shared/alpha-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Single source of truth for alpha's backend endpoint defaults. Change a domain HERE — not in
// individual pages/modules. Main-process callers layer env overrides on top (ALPHA_WEB_URL /
// ALPHA_PLATFORM_URL) for dev/staging; the renderer imports these defaults directly (it has no
// process.env). Pure constants only — NO electron/node imports — so both the main and renderer
// bundles can import this module.

export const ALPHA_ENDPOINTS = {
/** alpha-web (C): identity / login / token / billing portal. */
web: "https://auth.tidelabs.click",
/** alpha-platform (B): model proxy (/v1) + MCP gateway (/mcp). */
platform: "https://api.tidelabs.click",
} as const

// Path segments appended to the hosts above — the full alpha↔backend URL contract in one place.
// Change a route here (e.g. /v1 → /openai/v1) instead of editing inline template strings.
export const ALPHA_PATHS = {
/** web: OAuth authorize page. */
authorize: "/auth/authorize",
/** web: PKCE code → token exchange. */
token: "/auth/token",
/** web: billing portal. */
billing: "/billing",
/** platform: model proxy base → ALPHA_BASE_URL. */
modelProxy: "/v1",
/** platform: MCP tool gateway → ALPHA_CLOUD_MCP_URL. */
mcpGateway: "/mcp",
} as const
Loading