Fixed Codex

This commit is contained in:
decolua
2026-02-21 14:36:06 +07:00
parent f2025cc776
commit adf57aa0c9
18 changed files with 1419 additions and 1627 deletions
+76 -11
View File
@@ -3,6 +3,43 @@
import { Suspense, useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
const OAUTH_SESSION_KEY = "oauth_pending_auth";
/**
* Direct exchange: callback page calls exchange API itself
* when relay to opener fails (e.g. HMR reload destroyed listeners)
*/
async function directExchange(code, state) {
try {
const raw = localStorage.getItem(OAUTH_SESSION_KEY);
if (!raw) return false;
const session = JSON.parse(raw);
// Expired (5 min)
if (Date.now() - session.timestamp > 300000) {
localStorage.removeItem(OAUTH_SESSION_KEY);
return false;
}
const res = await fetch(`/api/oauth/${session.provider}/exchange`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
code,
redirectUri: session.redirectUri,
codeVerifier: session.codeVerifier,
state,
}),
});
const data = await res.json();
localStorage.removeItem(OAUTH_SESSION_KEY);
return res.ok && data.success;
} catch {
return false;
}
}
/**
* OAuth Callback Page Content
*/
@@ -24,7 +61,7 @@ function CallbackContent() {
fullUrl: window.location.href,
};
let sent = false;
let relayed = false;
// Check if this callback is from expected origin/port
const expectedOrigins = [
@@ -35,8 +72,8 @@ function CallbackContent() {
// Method 1: postMessage to opener (popup mode)
if (window.opener) {
try {
window.opener.postMessage({ type: "oauth_callback", data: callbackData }, "*"); // Allow any origin for local dev
sent = true;
window.opener.postMessage({ type: "oauth_callback", data: callbackData }, "*");
relayed = true;
} catch (e) {
console.log("postMessage failed:", e);
}
@@ -47,7 +84,7 @@ function CallbackContent() {
const channel = new BroadcastChannel("oauth_callback");
channel.postMessage(callbackData);
channel.close();
sent = true;
relayed = true;
} catch (e) {
console.log("BroadcastChannel failed:", e);
}
@@ -55,25 +92,53 @@ function CallbackContent() {
// Method 3: localStorage event (fallback)
try {
localStorage.setItem("oauth_callback", JSON.stringify({ ...callbackData, timestamp: Date.now() }));
sent = true;
relayed = true;
} catch (e) {
console.log("localStorage failed:", e);
}
if (sent && (code || error)) {
// Use setTimeout to avoid synchronous setState in effect
if (!(code || error)) {
setTimeout(() => setStatus("manual"), 0);
return;
}
if (error) {
setTimeout(() => {
setStatus("success");
// Auto close after 1.5 seconds
setTimeout(() => {
window.close();
// If can't close (not a popup), show success message
setTimeout(() => setStatus("done"), 500);
}, 1500);
}, 0);
} else {
setTimeout(() => setStatus("manual"), 0);
return;
}
// Try direct exchange FIRST (before relay may be lost to HMR)
// Then relay as backup for normal flow
const handleExchange = async () => {
const pending = localStorage.getItem(OAUTH_SESSION_KEY);
if (pending) {
// Direct exchange - works even if opener was destroyed by HMR
const ok = await directExchange(code, state);
if (ok) {
setStatus("success");
setTimeout(() => {
window.close();
setTimeout(() => setStatus("done"), 500);
}, 1500);
return;
}
}
// Fallback: relay succeeded and OAuthModal handled it
setStatus("success");
setTimeout(() => {
window.close();
setTimeout(() => setStatus("done"), 500);
}, 1500);
};
handleExchange();
}, [searchParams]);
return (