casualroom/apps/fenghuo/web/app/[locale]/test/page.tsx

195 lines
7.9 KiB
TypeScript
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
);
}