diff --git a/src/app/(oauth)/oauth/authorize/page.tsx b/src/app/(oauth)/oauth/authorize/page.tsx index c10b717..b3cf9cf 100644 --- a/src/app/(oauth)/oauth/authorize/page.tsx +++ b/src/app/(oauth)/oauth/authorize/page.tsx @@ -1,13 +1,14 @@ import { redirect } from "next/navigation"; import { getClientByClientId } from "@/lib/dto/client"; +import { getCurrentUser } from "@/lib/session"; import { Authorizing } from "@/components/auth/authorizing"; -export interface AuthorizeParams extends Record { +export interface AuthorizeParams { + oauth: string; + clientId: string; scope: string; - response_type: string; - client_id: string; - redirect_uri: string; + redirectUri: string; } export default async function AuthorizePage({ @@ -15,51 +16,23 @@ export default async function AuthorizePage({ }: { searchParams: AuthorizeParams; }) { - // 检查必要的参数 - if ( - !searchParams.response_type || - !searchParams.client_id || - !searchParams.redirect_uri - ) { - const errorParams = new URLSearchParams({ - error: "invalid_request", - error_description: "缺少必要的参数", - }); - redirect(`${searchParams.redirect_uri}?${errorParams.toString()}`); + const user = await getCurrentUser(); + if (!user?.id) { + redirect("/login"); } - const client = await getClientByClientId(searchParams.client_id); - - // 检查应用是否存在 + const client = await getClientByClientId(searchParams.clientId); if (!client) { - const errorParams = new URLSearchParams({ - error: "invalid_client", - error_description: "应用不存在", - }); - redirect(`${searchParams.redirect_uri}?${errorParams.toString()}`); - } - - // 检查回调地址是否匹配 - if (client.redirectUri !== searchParams.redirect_uri) { - const errorParams = new URLSearchParams({ - error: "invalid_request", - error_description: "回调地址不匹配", - }); - redirect(`${searchParams.redirect_uri}?${errorParams.toString()}`); - } - - // 检查应用是否被禁用 - if (!client.enabled) { - const errorParams = new URLSearchParams({ - error: "access_denied", - error_description: "此应用已被禁用", - }); - redirect(`${searchParams.redirect_uri}?${errorParams.toString()}`); + return ( +
+
应用不存在
+
+ ); } return ( -
- +
+
); } diff --git a/src/components/auth/authorizing.tsx b/src/components/auth/authorizing.tsx index 071f3af..ccca1ed 100644 --- a/src/components/auth/authorizing.tsx +++ b/src/components/auth/authorizing.tsx @@ -2,74 +2,61 @@ import { useEffect, useState } from "react"; import { useRouter } from "next/navigation"; -import { getDiscourseSSOUrl } from "@/actions/discourse-sso-url"; +import { handleAuthorizeAction } from "@/actions/authorizing"; -import type { AuthorizeParams } from "@/app/(oauth)/oauth/authorize/page"; +import { ErrorCard } from "@/components/auth/error-card"; interface AuthorizingProps { - searchParams: AuthorizeParams; + oauth: string; + clientId: string; + scope: string; + redirectUri: string; } -export function Authorizing({ searchParams }: AuthorizingProps) { - const router = useRouter(); - const [error, setError] = useState(null); +export function Authorizing({ + oauth, + clientId, + scope, + redirectUri, +}: AuthorizingProps) { + const [error, setError] = useState(null); useEffect(() => { - // 立即开始授权 - const doAuth = async () => { - try { - const url = await getDiscourseSSOUrl( - new URLSearchParams(searchParams).toString(), - ); - router.push(url); - } catch (error) { - setError(error); + const authorize = async () => { + const result = await handleAuthorizeAction(oauth, clientId, scope); + if (result.error) { + setError(result.error); + } else if (result.redirectUrl) { + const url = await result.redirectUrl; + window.location.href = url; } }; - doAuth(); - }, [searchParams, router]); + authorize().catch((err) => { + console.error("授权过程出错:", err); + setError("授权过程发生错误,请稍后重试"); + }); + }, [oauth, clientId, scope]); if (error) { return ( -
-
-
- - - -
-

授权异常

-

登录失败,请稍后重试!

- -
+
+
); } return ( -
-
-
-
-
-

正在授权

-

请稍候...

+
+
+
正在处理授权...
+
请稍候,我们正在处理您的授权请求
); diff --git a/src/components/auth/error-card.tsx b/src/components/auth/error-card.tsx new file mode 100644 index 0000000..2a9e607 --- /dev/null +++ b/src/components/auth/error-card.tsx @@ -0,0 +1,68 @@ +import { useRouter } from "next/navigation"; +import { AlertCircle } from "lucide-react"; + +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card"; + +interface ErrorCardProps { + title: string; + description: string; + redirectUri?: string; + error?: string; + errorDescription?: string; +} + +export function ErrorCard({ + title, + description, + redirectUri, + error, + errorDescription, +}: ErrorCardProps) { + const router = useRouter(); + + const handleBack = () => { + if (redirectUri) { + const url = new URL(redirectUri); + if (error) url.searchParams.set("error", error); + if (errorDescription) + url.searchParams.set("error_description", errorDescription); + router.push(url.toString()); + } else { + router.push("/"); + } + }; + + return ( + + +
+
+ +
+
+ + {title} + +
+ +

{description}

+
+ + + +
+ ); +}