Initial commit

This commit is contained in:
decolua
2026-01-05 09:58:59 +07:00
commit 3857598de4
159 changed files with 14537 additions and 0 deletions
+142
View File
@@ -0,0 +1,142 @@
"use client";
import { Suspense, useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
/**
* OAuth Callback Page Content
*/
function CallbackContent() {
const searchParams = useSearchParams();
const [status, setStatus] = useState("processing");
useEffect(() => {
const code = searchParams.get("code");
const state = searchParams.get("state");
const error = searchParams.get("error");
const errorDescription = searchParams.get("error_description");
const callbackData = {
code,
state,
error,
errorDescription,
fullUrl: window.location.href,
};
let sent = false;
// Check if this callback is from expected origin/port
const expectedOrigins = [
window.location.origin, // Same origin (for most providers)
"http://localhost:1455", // Codex specific port
];
// 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;
} catch (e) {
console.log("postMessage failed:", e);
}
}
// Method 2: BroadcastChannel (same origin tabs)
try {
const channel = new BroadcastChannel("oauth_callback");
channel.postMessage(callbackData);
channel.close();
sent = true;
} catch (e) {
console.log("BroadcastChannel failed:", e);
}
// Method 3: localStorage event (fallback)
try {
localStorage.setItem("oauth_callback", JSON.stringify({ ...callbackData, timestamp: Date.now() }));
sent = true;
} catch (e) {
console.log("localStorage failed:", e);
}
if (sent && (code || error)) {
// Use setTimeout to avoid synchronous setState in effect
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);
}
}, [searchParams]);
return (
<div className="min-h-screen flex items-center justify-center bg-bg">
<div className="text-center p-8 max-w-md">
{status === "processing" && (
<>
<div className="size-16 mx-auto mb-4 rounded-full bg-primary/10 flex items-center justify-center">
<span className="material-symbols-outlined text-3xl text-primary animate-spin">progress_activity</span>
</div>
<h1 className="text-xl font-semibold mb-2">Processing...</h1>
<p className="text-text-muted">Please wait while we complete the authorization.</p>
</>
)}
{(status === "success" || status === "done") && (
<>
<div className="size-16 mx-auto mb-4 rounded-full bg-green-100 dark:bg-green-900/30 flex items-center justify-center">
<span className="material-symbols-outlined text-3xl text-green-600">check_circle</span>
</div>
<h1 className="text-xl font-semibold mb-2">Authorization Successful!</h1>
<p className="text-text-muted">
{status === "success" ? "This window will close automatically..." : "You can close this tab now."}
</p>
</>
)}
{status === "manual" && (
<>
<div className="size-16 mx-auto mb-4 rounded-full bg-yellow-100 dark:bg-yellow-900/30 flex items-center justify-center">
<span className="material-symbols-outlined text-3xl text-yellow-600">info</span>
</div>
<h1 className="text-xl font-semibold mb-2">Copy This URL</h1>
<p className="text-text-muted mb-4">
Please copy the URL from the address bar and paste it in the application.
</p>
<div className="bg-surface border border-border rounded-lg p-3 text-left">
<code className="text-xs break-all">{typeof window !== "undefined" ? window.location.href : ""}</code>
</div>
</>
)}
</div>
</div>
);
}
/**
* OAuth Callback Page
* Receives callback from OAuth providers and sends data back via multiple methods
*/
export default function CallbackPage() {
return (
<Suspense fallback={
<div className="min-h-screen flex items-center justify-center bg-bg">
<div className="text-center p-8">
<div className="size-16 mx-auto mb-4 rounded-full bg-primary/10 flex items-center justify-center">
<span className="material-symbols-outlined text-3xl text-primary animate-spin">progress_activity</span>
</div>
<p className="text-text-muted">Loading...</p>
</div>
</div>
}>
<CallbackContent />
</Suspense>
);
}