diff options
| author | Dax <[email protected]> | 2025-08-18 17:12:21 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-18 17:12:21 -0400 |
| commit | f19586cebd77a4d2092e6ff66fb184a1366a9ce4 (patch) | |
| tree | bc1c2f4dbd6e12ed0d4e058c80b16a8071d8f427 | |
| parent | 5d12cadba7d03ca25becd5942cb8a959be1ddf00 (diff) | |
| download | opencode-f19586cebd77a4d2092e6ff66fb184a1366a9ce4.tar.gz opencode-f19586cebd77a4d2092e6ff66fb184a1366a9ce4.zip | |
fix anthropic console auth (#2049)
| -rw-r--r-- | bun.lock | 1 | ||||
| -rw-r--r-- | cloud/app/package.json | 1 | ||||
| -rw-r--r-- | cloud/app/src/context/auth.tsx | 28 | ||||
| -rw-r--r-- | cloud/app/src/routes/auth/authorize.ts | 7 | ||||
| -rw-r--r-- | cloud/app/src/routes/auth/callback.ts | 36 | ||||
| -rw-r--r-- | cloud/app/src/routes/index.tsx | 2 | ||||
| -rw-r--r-- | packages/opencode/src/cli/cmd/auth.ts | 40 | ||||
| -rw-r--r-- | packages/opencode/src/cli/cmd/opentui/opentui.ts | 0 | ||||
| -rw-r--r-- | packages/opencode/src/plugin/index.ts | 2 | ||||
| -rw-r--r-- | packages/plugin/src/index.ts | 28 |
10 files changed, 121 insertions, 24 deletions
@@ -15,6 +15,7 @@ "name": "@opencode/cloud-app", "dependencies": { "@ibm/plex": "6.4.1", + "@openauthjs/openauth": "0.0.0-20250322224806", "@solidjs/meta": "^0.29.4", "@solidjs/router": "^0.15.0", "@solidjs/start": "^1.1.0", diff --git a/cloud/app/package.json b/cloud/app/package.json index 61b3522a7..ba6ab6427 100644 --- a/cloud/app/package.json +++ b/cloud/app/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "@ibm/plex": "6.4.1", + "@openauthjs/openauth": "0.0.0-20250322224806", "@solidjs/meta": "^0.29.4", "@solidjs/router": "^0.15.0", "@solidjs/start": "^1.1.0", diff --git a/cloud/app/src/context/auth.tsx b/cloud/app/src/context/auth.tsx new file mode 100644 index 000000000..bec949568 --- /dev/null +++ b/cloud/app/src/context/auth.tsx @@ -0,0 +1,28 @@ +import { useSession } from "vinxi/http" +import { createClient } from "@openauthjs/openauth/client" + +export const AuthClient = createClient({ + clientID: "app", + issuer: "https://auth.dev.opencode.ai", +}) + +export interface AuthSession { + account: Record<string, { + id: string + email: string + }> + current?: string +} + +export function useAuthSession() { + "use server" + + return useSession<AuthSession>({ + password: "0".repeat(32), + name: "auth" + }) +} + + +export function AuthProvider() { +} diff --git a/cloud/app/src/routes/auth/authorize.ts b/cloud/app/src/routes/auth/authorize.ts new file mode 100644 index 000000000..166466ef8 --- /dev/null +++ b/cloud/app/src/routes/auth/authorize.ts @@ -0,0 +1,7 @@ +import type { APIEvent } from "@solidjs/start/server" +import { AuthClient } from "~/context/auth" + +export async function GET(input: APIEvent) { + const result = await AuthClient.authorize(new URL("./callback", input.request.url).toString(), "code") + return Response.redirect(result.url, 302) +} diff --git a/cloud/app/src/routes/auth/callback.ts b/cloud/app/src/routes/auth/callback.ts new file mode 100644 index 000000000..a561c70d0 --- /dev/null +++ b/cloud/app/src/routes/auth/callback.ts @@ -0,0 +1,36 @@ +import type { APIEvent } from "@solidjs/start/server" +import { AuthClient, useAuthSession } from "~/context/auth" + +export async function GET(input: APIEvent) { + const url = new URL(input.request.url) + const code = url.searchParams.get("code") + if (!code) throw new Error("No code found") + const redirectURI = `${url.origin}${url.pathname}` + console.log({ + redirectURI, + code, + }) + const result = await AuthClient.exchange(code, `${url.origin}${url.pathname}`) + if (result.err) { + throw new Error(result.err.message) + } + const decoded = AuthClient.decode(result.tokens.access, {} as any) + if (decoded.err) throw new Error(decoded.err.message) + const session = await useAuthSession() + const id = decoded.subject.properties.accountID + await session.update((value) => { + return { + ...value, + account: { + [id]: { + id, + email: decoded.subject.properties.email, + }, + }, + current: id, + } + }) + return { + result, + } +} diff --git a/cloud/app/src/routes/index.tsx b/cloud/app/src/routes/index.tsx index 7c7eee13d..da4e23364 100644 --- a/cloud/app/src/routes/index.tsx +++ b/cloud/app/src/routes/index.tsx @@ -51,7 +51,7 @@ export default function Home() { <a href="/docs">Get Started</a> </div> <div data-slot="right"> - <button data-copy data-slot="command" data-command="curl -fsSL https://opencode.ai/install | bash"> + <button data-copy data-slot="command"> <span> <span>curl -fsSL </span> <span data-slot="protocol">https://</span> diff --git a/packages/opencode/src/cli/cmd/auth.ts b/packages/opencode/src/cli/cmd/auth.ts index ab06d5bf3..cf736486a 100644 --- a/packages/opencode/src/cli/cmd/auth.ts +++ b/packages/opencode/src/cli/cmd/auth.ts @@ -176,12 +176,20 @@ export const AuthLoginCommand = cmd({ spinner.stop("Failed to authorize", 1) } if (result.type === "success") { - await Auth.set(provider, { - type: "oauth", - refresh: result.refresh, - access: result.access, - expires: result.expires, - }) + if ("refresh" in result) { + await Auth.set(provider, { + type: "oauth", + refresh: result.refresh, + access: result.access, + expires: result.expires, + }) + } + if ("key" in result) { + await Auth.set(provider, { + type: "api", + key: result.key, + }) + } spinner.stop("Login successful") } } @@ -197,12 +205,20 @@ export const AuthLoginCommand = cmd({ prompts.log.error("Failed to authorize") } if (result.type === "success") { - await Auth.set(provider, { - type: "oauth", - refresh: result.refresh, - access: result.access, - expires: result.expires, - }) + if ("refresh" in result) { + await Auth.set(provider, { + type: "oauth", + refresh: result.refresh, + access: result.access, + expires: result.expires, + }) + } + if ("key" in result) { + await Auth.set(provider, { + type: "api", + key: result.key, + }) + } prompts.log.success("Login successful") } } diff --git a/packages/opencode/src/cli/cmd/opentui/opentui.ts b/packages/opencode/src/cli/cmd/opentui/opentui.ts new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/packages/opencode/src/cli/cmd/opentui/opentui.ts diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts index 8fbd38c67..633dc850e 100644 --- a/packages/opencode/src/plugin/index.ts +++ b/packages/opencode/src/plugin/index.ts @@ -26,7 +26,7 @@ export namespace Plugin { const plugins = [...(config.plugin ?? [])] if (!Flag.OPENCODE_DISABLE_DEFAULT_PLUGINS) { plugins.push("opencode-copilot-auth") - plugins.push("opencode-anthropic-auth") + plugins.push("[email protected]") } for (let plugin of plugins) { log.info("loading plugin", { path: plugin }) diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index 1a6cbf124..a214af110 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -32,12 +32,16 @@ export interface Hooks { | { method: "auto" callback(): Promise< - | { + | ({ type: "success" - refresh: string - access: string - expires: number - } + } & ( + | { + refresh: string + access: string + expires: number + } + | { key: string } + )) | { type: "failed" } @@ -46,12 +50,16 @@ export interface Hooks { | { method: "code" callback(code: string): Promise< - | { + | ({ type: "success" - refresh: string - access: string - expires: number - } + } & ( + | { + refresh: string + access: string + expires: number + } + | { key: string } + )) | { type: "failed" } |
