fix email login
This commit is contained in:
parent
2a60e35fc5
commit
e2c31e4620
@ -1,7 +1,8 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { signIn, getProviders } from "next-auth/react"
|
||||
import { useState, useEffect } from "react"
|
||||
import { signIn, getProviders, useSession } from "next-auth/react"
|
||||
import { useRouter, useSearchParams } from "next/navigation"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
@ -14,6 +15,38 @@ export default function SignInPage() {
|
||||
const [email, setEmail] = useState("")
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [message, setMessage] = useState("")
|
||||
const { data: session, status } = useSession()
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
|
||||
// 检查用户是否已登录,如果已登录则重定向
|
||||
useEffect(() => {
|
||||
if (status === "authenticated" && session) {
|
||||
const callbackUrl = searchParams.get("callbackUrl") || "/"
|
||||
router.push(callbackUrl)
|
||||
}
|
||||
}, [status, session, router, searchParams])
|
||||
|
||||
// 如果正在加载会话状态,显示loading
|
||||
if (status === "loading") {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50">
|
||||
<Card className="w-full max-w-md">
|
||||
<CardContent className="flex items-center justify-center p-6">
|
||||
<div className="text-center">
|
||||
<div className="w-8 h-8 bg-gray-200 rounded-full animate-pulse mx-auto mb-2"></div>
|
||||
<p className="text-sm text-muted-foreground">正在检查登录状态...</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// 如果已经登录,不显示登录表单(虽然会重定向,但防止闪烁)
|
||||
if (status === "authenticated") {
|
||||
return null
|
||||
}
|
||||
|
||||
const handleEmailSignIn = async (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
@ -41,7 +74,8 @@ export default function SignInPage() {
|
||||
const handleGoogleSignIn = async () => {
|
||||
setIsLoading(true)
|
||||
try {
|
||||
await signIn("google", { callbackUrl: "/" })
|
||||
const callbackUrl = searchParams.get("callbackUrl") || "/"
|
||||
await signIn("google", { callbackUrl })
|
||||
} catch (error) {
|
||||
setMessage("Google登录失败,请重试")
|
||||
setIsLoading(false)
|
||||
|
75
auth.ts
75
auth.ts
@ -11,6 +11,7 @@ export const { auth, handlers, signIn, signOut } = NextAuth({
|
||||
Google({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID!,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
||||
allowDangerousEmailAccountLinking: true,
|
||||
}),
|
||||
Nodemailer({
|
||||
server: {
|
||||
@ -28,13 +29,77 @@ export const { auth, handlers, signIn, signOut } = NextAuth({
|
||||
signIn: "/auth/signin",
|
||||
error: "/auth/error",
|
||||
},
|
||||
events: {
|
||||
async linkAccount({ user, account, profile }) {
|
||||
if (profile?.email && user.id) {
|
||||
await db.user.update({
|
||||
where: { id: user.id },
|
||||
data: {
|
||||
email: profile.email,
|
||||
name: profile.name || user.name,
|
||||
image: (profile as any)?.picture || user.image,
|
||||
emailVerified: (profile as any)?.email_verified ? new Date() : null,
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
callbacks: {
|
||||
async signIn({ user, account, profile, email, credentials }) {
|
||||
if (!user.email) return false
|
||||
|
||||
if (account?.provider === "nodemailer") {
|
||||
return true
|
||||
}
|
||||
|
||||
if (account?.provider === "google" && user.email) {
|
||||
const existingUser = await db.user.findUnique({
|
||||
where: { email: user.email },
|
||||
include: { accounts: true },
|
||||
})
|
||||
|
||||
if (existingUser) {
|
||||
const hasGoogleAccount = existingUser.accounts.some(
|
||||
acc => acc.provider === "google"
|
||||
)
|
||||
|
||||
if (!hasGoogleAccount) {
|
||||
await db.account.create({
|
||||
data: {
|
||||
userId: existingUser.id,
|
||||
type: account.type,
|
||||
provider: account.provider,
|
||||
providerAccountId: account.providerAccountId,
|
||||
refresh_token: account.refresh_token as string | null,
|
||||
access_token: account.access_token as string | null,
|
||||
expires_at: account.expires_at,
|
||||
token_type: account.token_type,
|
||||
scope: account.scope,
|
||||
id_token: account.id_token as string | null,
|
||||
session_state: account.session_state as string | null,
|
||||
},
|
||||
})
|
||||
|
||||
await db.user.update({
|
||||
where: { id: existingUser.id },
|
||||
data: {
|
||||
name: profile?.name || existingUser.name,
|
||||
image: (profile as any)?.picture || existingUser.image,
|
||||
emailVerified: (profile as any)?.email_verified ? new Date() : existingUser.emailVerified,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
async session({ token, session }) {
|
||||
if (token) {
|
||||
session.user.id = token.id
|
||||
session.user.name = token.name
|
||||
session.user.email = token.email
|
||||
session.user.image = token.picture
|
||||
session.user.id = token.id as string
|
||||
session.user.name = token.name as string
|
||||
session.user.email = token.email as string
|
||||
session.user.image = token.picture as string
|
||||
}
|
||||
|
||||
return session
|
||||
@ -42,7 +107,7 @@ export const { auth, handlers, signIn, signOut } = NextAuth({
|
||||
async jwt({ user, token }) {
|
||||
const dbUser = await db.user.findFirst({
|
||||
where: {
|
||||
email: token.email,
|
||||
email: token.email!,
|
||||
},
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user