195 lines
7.9 KiB
TypeScript
Executable File
195 lines
7.9 KiB
TypeScript
Executable File
"use client";
|
||
|
||
import { client } from "@/lib/auth-client";
|
||
import { Button } from "@nice/ui/components/button";
|
||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@nice/ui/components/card";
|
||
import { toast } from "@nice/ui/components/sonner";
|
||
import { useState, useEffect } from "react";
|
||
|
||
export default function OIDCTestPage() {
|
||
const [currentUser, setCurrentUser] = useState<any>(null);
|
||
const [discoveryInfo, setDiscoveryInfo] = useState<any>(null);
|
||
const [oauthTestResult, setOauthTestResult] = useState<any>(null);
|
||
const [isLoading, setIsLoading] = useState(true);
|
||
|
||
// 获取 OIDC Discovery 信息
|
||
const handleGetDiscoveryInfo = async () => {
|
||
try {
|
||
const response = await fetch('http://localhost:3001/api/auth/.well-known/openid-configuration');
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||
}
|
||
const info = await response.json();
|
||
setDiscoveryInfo(info);
|
||
toast.success("获取 Discovery 信息成功!");
|
||
} catch (error: any) {
|
||
console.error("获取 Discovery 信息失败:", error);
|
||
toast.error(`获取 Discovery 信息失败: ${error.message || "未知错误"}`);
|
||
}
|
||
};
|
||
|
||
// 测试 Generic OAuth 配置
|
||
const handleTestGenericOAuthConfig = async () => {
|
||
try {
|
||
const result = await client.signIn.oauth2({
|
||
providerId: "fenghuo-oidc",
|
||
callbackURL: "http://localhost:3000/dashboard",
|
||
});
|
||
|
||
if (result.data) {
|
||
setOauthTestResult({ success: true, data: result.data });
|
||
toast.success("OAuth 配置测试成功!");
|
||
} else if (result.error) {
|
||
console.error("OAuth 错误详情:", result.error);
|
||
setOauthTestResult({ success: false, error: result.error });
|
||
toast.error(`OAuth 配置测试失败: ${result.error.message}`);
|
||
}
|
||
} catch (error: any) {
|
||
console.error("OAuth 配置测试失败:", error);
|
||
setOauthTestResult({ success: false, error: { message: error.message } });
|
||
toast.error(`OAuth 配置测试失败: ${error.message || "未知错误"}`);
|
||
}
|
||
};
|
||
|
||
|
||
|
||
// 检查当前会话
|
||
const handleCheckSession = async () => {
|
||
try {
|
||
const session = await client.getSession();
|
||
console.log("当前会话:", session);
|
||
setCurrentUser(session.data);
|
||
toast.success(session.data ? `会话存在: ${session.data.user.email}` : "无活跃会话");
|
||
return session.data;
|
||
} catch (error: any) {
|
||
console.error("检查会话失败:", error);
|
||
toast.error(`检查会话失败: ${error.message}`);
|
||
return null;
|
||
}
|
||
};
|
||
|
||
// 自动检测登录状态
|
||
useEffect(() => {
|
||
const checkSession = async () => {
|
||
try {
|
||
setIsLoading(true);
|
||
const session = await client.getSession();
|
||
setCurrentUser(session.data);
|
||
} catch (error) {
|
||
console.error("自动检查会话失败:", error);
|
||
} finally {
|
||
setIsLoading(false);
|
||
}
|
||
};
|
||
|
||
checkSession();
|
||
}, []);
|
||
|
||
|
||
|
||
// 登出
|
||
const handleSignOut = async () => {
|
||
try {
|
||
await client.signOut();
|
||
setCurrentUser(null);
|
||
toast.success("已登出");
|
||
} catch (error: any) {
|
||
console.error("登出失败:", error);
|
||
toast.error(`登出失败: ${error.message}`);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="container mx-auto p-6 space-y-6">
|
||
<div className="text-center">
|
||
<h1 className="text-3xl font-bold mb-2">OIDC Provider 测试页面</h1>
|
||
<p className="text-muted-foreground">测试 OpenID Connect 相关功能</p>
|
||
<div className="mt-4">
|
||
<Button
|
||
onClick={() => window.open('/sign-in', '_blank')}
|
||
variant="outline"
|
||
className="mr-2"
|
||
>
|
||
打开登录页面
|
||
</Button>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
{/* 当前用户状态 */}
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>当前用户状态</CardTitle>
|
||
<CardDescription>
|
||
{isLoading ? "正在检查登录状态..." : "查看当前登录状态和会话信息"}
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-4">
|
||
<div className="flex gap-4 mb-4">
|
||
<Button onClick={handleCheckSession} variant="outline" disabled={isLoading}>
|
||
刷新会话状态
|
||
</Button>
|
||
{currentUser && (
|
||
<Button onClick={handleSignOut} variant="destructive">
|
||
登出
|
||
</Button>
|
||
)}
|
||
</div>
|
||
|
||
{isLoading ? (
|
||
<div className="bg-gray-50 dark:bg-gray-900/20 p-4 rounded-md">
|
||
<div className="text-sm text-gray-600 dark:text-gray-400">
|
||
🔄 正在检查登录状态...
|
||
</div>
|
||
</div>
|
||
) : currentUser ? (
|
||
<div className="space-y-2">
|
||
<h4 className="font-semibold">当前用户信息:</h4>
|
||
<div className="bg-green-50 dark:bg-green-900/20 p-4 rounded-md">
|
||
<div className="text-sm space-y-1">
|
||
<div><strong>Email:</strong> {currentUser.user?.email}</div>
|
||
<div><strong>Name:</strong> {currentUser.user?.name}</div>
|
||
<div><strong>Username:</strong> {currentUser.user?.username}</div>
|
||
<div><strong>ID:</strong> {currentUser.user?.id}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<div className="bg-yellow-50 dark:bg-yellow-900/20 p-4 rounded-md">
|
||
<div className="text-sm text-yellow-800 dark:text-yellow-200">
|
||
⚠️ 未登录状态 - 请先登录以测试 OIDC 功能
|
||
</div>
|
||
</div>
|
||
)}
|
||
</CardContent>
|
||
</Card>
|
||
|
||
|
||
|
||
{/* OAuth2 登录测试 */}
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>OAuth2 登录测试</CardTitle>
|
||
<CardDescription>
|
||
由于自循环配置问题,OAuth2 测试已暂时禁用。请使用直接的 OIDC 流程测试。
|
||
</CardDescription>
|
||
</CardHeader>
|
||
<CardContent className="space-y-4">
|
||
<div className="text-sm text-muted-foreground mb-4">
|
||
<p><strong>⚠️ 注意:</strong> 自循环 OAuth 配置已禁用以避免状态冲突。</p>
|
||
<p>如需测试 OAuth 流程,请访问 <a href="/debug-oauth" className="text-blue-600 underline">OAuth 调试页面</a>。</p>
|
||
</div>
|
||
<Button
|
||
onClick={() => window.open('/debug-oauth', '_blank')}
|
||
className="w-full"
|
||
variant="outline"
|
||
>
|
||
打开 OAuth 调试页面
|
||
</Button>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
|
||
</div>
|
||
);
|
||
} |