77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
"use client"
|
|
|
|
import { onOpenUrl } from "@tauri-apps/plugin-deep-link"
|
|
import { useEffect } from "react"
|
|
import { useAuthStore } from "@/store/auth"
|
|
import { handleAuthCallback } from "@/utils/auth"
|
|
import { createClient } from "@/utils/supabase/client"
|
|
import { addToast } from "@heroui/react"
|
|
|
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
const { checkSession, setSession, setLoading } = useAuthStore()
|
|
|
|
// 初始化时检查现有会话
|
|
useEffect(() => {
|
|
void checkSession()
|
|
}, [checkSession])
|
|
|
|
// 监听 deep-link 认证回调
|
|
useEffect(() => {
|
|
const unlisten = onOpenUrl(async (urls) => {
|
|
if (urls.length === 0) return
|
|
|
|
const url = urls[0]
|
|
if (!url.startsWith("cstb://auth")) return
|
|
|
|
setLoading(true)
|
|
try {
|
|
const session = await handleAuthCallback(url)
|
|
if (session) {
|
|
setSession(session)
|
|
addToast({
|
|
title: "登录成功",
|
|
description: `欢迎回来,${session.user.email || session.user.id}`,
|
|
})
|
|
} else {
|
|
addToast({
|
|
title: "登录失败",
|
|
description: "无法验证登录信息,请重试",
|
|
|
|
severity: "danger",
|
|
})
|
|
}
|
|
} catch (error) {
|
|
console.error("Auth callback error:", error)
|
|
addToast({
|
|
title: "登录失败",
|
|
description: error instanceof Error ? error.message : "未知错误",
|
|
severity: "danger",
|
|
})
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
})
|
|
|
|
return () => {
|
|
void unlisten.then((fn) => fn())
|
|
}
|
|
}, [setSession, setLoading])
|
|
|
|
// 监听 Supabase 认证状态变化
|
|
useEffect(() => {
|
|
const supabase = createClient()
|
|
const {
|
|
data: { subscription },
|
|
} = supabase.auth.onAuthStateChange((_event, session) => {
|
|
setSession(session)
|
|
})
|
|
|
|
return () => {
|
|
subscription.unsubscribe()
|
|
}
|
|
}, [setSession])
|
|
|
|
return <>{children}</>
|
|
}
|
|
|