Skip to content

Commit f19586c

Browse files
authored
fix anthropic console auth (sst#2049)
1 parent 5d12cad commit f19586c

File tree

10 files changed

+121
-24
lines changed

10 files changed

+121
-24
lines changed

bun.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"name": "@opencode/cloud-app",
1616
"dependencies": {
1717
"@ibm/plex": "6.4.1",
18+
"@openauthjs/openauth": "0.0.0-20250322224806",
1819
"@solidjs/meta": "^0.29.4",
1920
"@solidjs/router": "^0.15.0",
2021
"@solidjs/start": "^1.1.0",

cloud/app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
},
1010
"dependencies": {
1111
"@ibm/plex": "6.4.1",
12+
"@openauthjs/openauth": "0.0.0-20250322224806",
1213
"@solidjs/meta": "^0.29.4",
1314
"@solidjs/router": "^0.15.0",
1415
"@solidjs/start": "^1.1.0",

cloud/app/src/context/auth.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useSession } from "vinxi/http"
2+
import { createClient } from "@openauthjs/openauth/client"
3+
4+
export const AuthClient = createClient({
5+
clientID: "app",
6+
issuer: "https://auth.dev.opencode.ai",
7+
})
8+
9+
export interface AuthSession {
10+
account: Record<string, {
11+
id: string
12+
email: string
13+
}>
14+
current?: string
15+
}
16+
17+
export function useAuthSession() {
18+
"use server"
19+
20+
return useSession<AuthSession>({
21+
password: "0".repeat(32),
22+
name: "auth"
23+
})
24+
}
25+
26+
27+
export function AuthProvider() {
28+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { APIEvent } from "@solidjs/start/server"
2+
import { AuthClient } from "~/context/auth"
3+
4+
export async function GET(input: APIEvent) {
5+
const result = await AuthClient.authorize(new URL("./callback", input.request.url).toString(), "code")
6+
return Response.redirect(result.url, 302)
7+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { APIEvent } from "@solidjs/start/server"
2+
import { AuthClient, useAuthSession } from "~/context/auth"
3+
4+
export async function GET(input: APIEvent) {
5+
const url = new URL(input.request.url)
6+
const code = url.searchParams.get("code")
7+
if (!code) throw new Error("No code found")
8+
const redirectURI = `${url.origin}${url.pathname}`
9+
console.log({
10+
redirectURI,
11+
code,
12+
})
13+
const result = await AuthClient.exchange(code, `${url.origin}${url.pathname}`)
14+
if (result.err) {
15+
throw new Error(result.err.message)
16+
}
17+
const decoded = AuthClient.decode(result.tokens.access, {} as any)
18+
if (decoded.err) throw new Error(decoded.err.message)
19+
const session = await useAuthSession()
20+
const id = decoded.subject.properties.accountID
21+
await session.update((value) => {
22+
return {
23+
...value,
24+
account: {
25+
[id]: {
26+
id,
27+
email: decoded.subject.properties.email,
28+
},
29+
},
30+
current: id,
31+
}
32+
})
33+
return {
34+
result,
35+
}
36+
}

cloud/app/src/routes/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export default function Home() {
5151
<a href="/docs">Get Started</a>
5252
</div>
5353
<div data-slot="right">
54-
<button data-copy data-slot="command" data-command="curl -fsSL https://opencode.ai/install | bash">
54+
<button data-copy data-slot="command">
5555
<span>
5656
<span>curl -fsSL&nbsp;</span>
5757
<span data-slot="protocol">https://</span>

packages/opencode/src/cli/cmd/auth.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,20 @@ export const AuthLoginCommand = cmd({
176176
spinner.stop("Failed to authorize", 1)
177177
}
178178
if (result.type === "success") {
179-
await Auth.set(provider, {
180-
type: "oauth",
181-
refresh: result.refresh,
182-
access: result.access,
183-
expires: result.expires,
184-
})
179+
if ("refresh" in result) {
180+
await Auth.set(provider, {
181+
type: "oauth",
182+
refresh: result.refresh,
183+
access: result.access,
184+
expires: result.expires,
185+
})
186+
}
187+
if ("key" in result) {
188+
await Auth.set(provider, {
189+
type: "api",
190+
key: result.key,
191+
})
192+
}
185193
spinner.stop("Login successful")
186194
}
187195
}
@@ -197,12 +205,20 @@ export const AuthLoginCommand = cmd({
197205
prompts.log.error("Failed to authorize")
198206
}
199207
if (result.type === "success") {
200-
await Auth.set(provider, {
201-
type: "oauth",
202-
refresh: result.refresh,
203-
access: result.access,
204-
expires: result.expires,
205-
})
208+
if ("refresh" in result) {
209+
await Auth.set(provider, {
210+
type: "oauth",
211+
refresh: result.refresh,
212+
access: result.access,
213+
expires: result.expires,
214+
})
215+
}
216+
if ("key" in result) {
217+
await Auth.set(provider, {
218+
type: "api",
219+
key: result.key,
220+
})
221+
}
206222
prompts.log.success("Login successful")
207223
}
208224
}

packages/opencode/src/cli/cmd/opentui/opentui.ts

Whitespace-only changes.

packages/opencode/src/plugin/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export namespace Plugin {
2626
const plugins = [...(config.plugin ?? [])]
2727
if (!Flag.OPENCODE_DISABLE_DEFAULT_PLUGINS) {
2828
plugins.push("opencode-copilot-auth")
29-
plugins.push("opencode-anthropic-auth")
29+
plugins.push("opencode-anthropic-auth@0.0.2")
3030
}
3131
for (let plugin of plugins) {
3232
log.info("loading plugin", { path: plugin })

packages/plugin/src/index.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ export interface Hooks {
3232
| {
3333
method: "auto"
3434
callback(): Promise<
35-
| {
35+
| ({
3636
type: "success"
37-
refresh: string
38-
access: string
39-
expires: number
40-
}
37+
} & (
38+
| {
39+
refresh: string
40+
access: string
41+
expires: number
42+
}
43+
| { key: string }
44+
))
4145
| {
4246
type: "failed"
4347
}
@@ -46,12 +50,16 @@ export interface Hooks {
4650
| {
4751
method: "code"
4852
callback(code: string): Promise<
49-
| {
53+
| ({
5054
type: "success"
51-
refresh: string
52-
access: string
53-
expires: number
54-
}
55+
} & (
56+
| {
57+
refresh: string
58+
access: string
59+
expires: number
60+
}
61+
| { key: string }
62+
))
5563
| {
5664
type: "failed"
5765
}

0 commit comments

Comments
 (0)