diff --git a/bun.lockb b/bun.lockb deleted file mode 100644 index 160304d..0000000 Binary files a/bun.lockb and /dev/null differ diff --git a/src/App.tsx b/src/App.tsx index 67d0d20..8c53a5e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,7 @@ import { TooltipProvider } from "@/components/ui/tooltip"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Index from "./pages/Index"; +import GiteaOAuthCallback from "./pages/GiteaOAuthCallback"; import NotFound from "./pages/NotFound"; const queryClient = new QueryClient(); @@ -16,6 +17,7 @@ const App = () => ( } /> + } /> {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} } /> diff --git a/src/components/LoginPage.tsx b/src/components/LoginPage.tsx index b7cece3..5d6e3e3 100644 --- a/src/components/LoginPage.tsx +++ b/src/components/LoginPage.tsx @@ -4,7 +4,7 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { toast } from '@/hooks/use-toast'; -import { Lock } from 'lucide-react'; +import { Lock, Github } from 'lucide-react'; interface LoginPageProps { onLogin: (token: string) => void; @@ -62,6 +62,11 @@ const LoginPage = ({ onLogin }: LoginPageProps) => { } }; + const handleGiteaLogin = () => { + // Redirect to the Gitea OAuth endpoint + window.location.href = '/admin/api/login/oauth/gitea'; + }; + return (
@@ -91,6 +96,25 @@ const LoginPage = ({ onLogin }: LoginPageProps) => { {isLoading ? "Signing in..." : "Sign In"} + +
+
+
+
+
+ Or continue with +
+
+ +
diff --git a/src/pages/GiteaOAuthCallback.tsx b/src/pages/GiteaOAuthCallback.tsx new file mode 100644 index 0000000..02678fb --- /dev/null +++ b/src/pages/GiteaOAuthCallback.tsx @@ -0,0 +1,79 @@ +import React, { useEffect } from 'react'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { toast } from '@/hooks/use-toast'; + +const GiteaOAuthCallback = () => { + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + + useEffect(() => { + const handleOAuthCallback = async () => { + // Get the code from the URL parameters + const code = searchParams.get('code'); + + if (!code) { + toast({ + title: "Error", + description: "No authorization code received from Gitea", + variant: "destructive", + }); + navigate('/'); + return; + } + + try { + // Send the code to our backend to exchange for a JWT token + const response = await fetch('/admin/api/login/oauth/gitea/final', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ code }), + }); + + const data = await response.json(); + + if (response.ok && data.token) { + // Store the token in localStorage + localStorage.setItem('adminToken', data.token); + + toast({ + title: "Success", + description: data.message || "Login successful", + }); + + // Redirect to the admin dashboard + window.location.href = '/admin'; + } else { + toast({ + title: "Error", + description: data.error || "Login failed", + variant: "destructive", + }); + navigate('/'); + } + } catch (error) { + toast({ + title: "Error", + description: "Network error. Please try again.", + variant: "destructive", + }); + navigate('/'); + } + }; + + handleOAuthCallback(); + }, [navigate, searchParams]); + + return ( +
+
+
+

Processing Gitea Login

+

Please wait while we complete your authentication...

+
+
+ ); +}; + +export default GiteaOAuthCallback; \ No newline at end of file