feat(oauth): unify OAuth callback browser pages (#34025)

This commit is contained in:
Aiden Cline
2026-06-26 00:36:40 -05:00
committed by GitHub
parent ce4ccb3d34
commit 927d0fb2b3
9 changed files with 322 additions and 329 deletions
@@ -1,6 +1,7 @@
import type { Hooks, PluginInput } from "@opencode-ai/plugin"
import { OAUTH_DUMMY_KEY } from "../auth"
import { InstallationVersion } from "@opencode-ai/core/installation/version"
import { OauthCallbackPage } from "@opencode-ai/core/oauth/page"
import { createServer } from "http"
import open from "open"
@@ -156,29 +157,6 @@ async function refreshAccessToken(account: string, refreshToken: string) {
return token
}
const HTML_SUCCESS = `<!doctype html>
<html>
<head><title>OpenCode - Snowflake Authorization Successful</title></head>
<body style="font-family: system-ui; display:flex; align-items:center; justify-content:center; height:100vh; margin:0; background:#111; color:#eee;">
<div style="text-align:center; max-width:36rem; padding:2rem;">
<h1 style="color:#7ee787;">Authorization Successful</h1>
<p>You can close this window and return to OpenCode.</p>
</div>
<script>setTimeout(() => window.close(), 1500)</script>
</body>
</html>`
const htmlError = (message: string) => `<!doctype html>
<html>
<head><title>OpenCode - Snowflake Authorization Failed</title></head>
<body style="font-family: system-ui; display:flex; align-items:center; justify-content:center; height:100vh; margin:0; background:#111; color:#eee;">
<div style="text-align:center; max-width:48rem; padding:2rem;">
<h1 style="color:#ff7b72;">Authorization Failed</h1>
<pre style="white-space:pre-wrap; color:#ffb3ad; background:#2a1210; padding:1rem; border-radius:.5rem;">${message}</pre>
</div>
</body>
</html>`
async function startOAuthServer() {
if (oauthServer) return
@@ -203,7 +181,7 @@ async function startOAuthServer() {
pendingOAuth?.reject(new Error(message))
pendingOAuth = undefined
res.writeHead(400, { "Content-Type": "text/html" })
res.end(htmlError(message))
res.end(OauthCallbackPage.error(message, { provider: "Snowflake" }))
return
}
@@ -214,7 +192,7 @@ async function startOAuthServer() {
const message = errorDescription || error
current.reject(new Error(message))
res.writeHead(200, { "Content-Type": "text/html" })
res.end(htmlError(message))
res.end(OauthCallbackPage.error(message, { provider: "Snowflake" }))
return
}
@@ -222,7 +200,7 @@ async function startOAuthServer() {
const message = "Missing authorization code"
current.reject(new Error(message))
res.writeHead(400, { "Content-Type": "text/html" })
res.end(htmlError(message))
res.end(OauthCallbackPage.error(message, { provider: "Snowflake" }))
return
}
@@ -231,7 +209,7 @@ async function startOAuthServer() {
.catch((err) => current.reject(err instanceof Error ? err : new Error(String(err))))
res.writeHead(200, { "Content-Type": "text/html" })
res.end(HTML_SUCCESS)
res.end(OauthCallbackPage.success({ provider: "Snowflake" }))
})
await new Promise<void>((resolve, reject) => {