feat(oauth): unify OAuth callback browser pages (#34025)
This commit is contained in:
@@ -5,7 +5,7 @@ import os from "os"
|
||||
import { setTimeout as sleep } from "node:timers/promises"
|
||||
import { createServer } from "http"
|
||||
import { OpenAIWebSocketPool } from "./ws-pool"
|
||||
import { escapeHtml } from "@/util/html"
|
||||
import { OauthCallbackPage } from "@opencode-ai/core/oauth/page"
|
||||
|
||||
const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann"
|
||||
const ISSUER = "https://auth.openai.com"
|
||||
@@ -138,95 +138,8 @@ async function refreshAccessToken(refreshToken: string, issuer = ISSUER): Promis
|
||||
return response.json()
|
||||
}
|
||||
|
||||
const HTML_SUCCESS = `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenCode - Codex Authorization Successful</title>
|
||||
<style>
|
||||
body {
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background: #131010;
|
||||
color: #f1ecec;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
h1 {
|
||||
color: #f1ecec;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
p {
|
||||
color: #b7b1b1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Authorization Successful</h1>
|
||||
<p>You can close this window and return to OpenCode.</p>
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(() => window.close(), 2000)
|
||||
</script>
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
export const renderOAuthError = (error: string) => `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>OpenCode - Codex Authorization Failed</title>
|
||||
<style>
|
||||
body {
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background: #131010;
|
||||
color: #f1ecec;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
h1 {
|
||||
color: #fc533a;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
p {
|
||||
color: #b7b1b1;
|
||||
}
|
||||
.error {
|
||||
color: #ff917b;
|
||||
font-family: monospace;
|
||||
margin-top: 1rem;
|
||||
padding: 1rem;
|
||||
background: #3c140d;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Authorization Failed</h1>
|
||||
<p>An error occurred during authorization.</p>
|
||||
<div class="error">${escapeHtml(error)}</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>`
|
||||
// Kept as a named export for plugin.codex tests; delegates to the shared branded page.
|
||||
export const renderOAuthError = (error: string) => OauthCallbackPage.error(error, { provider: "ChatGPT" })
|
||||
|
||||
interface PendingOAuth {
|
||||
pkce: PkceCodes
|
||||
@@ -287,7 +200,7 @@ async function startOAuthServer(): Promise<{ port: number; redirectUri: string }
|
||||
.catch((err) => current.reject(err))
|
||||
|
||||
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" })
|
||||
res.end(HTML_SUCCESS)
|
||||
res.end(OauthCallbackPage.success({ provider: "ChatGPT" }))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user