212 lines
5.6 KiB
JavaScript
212 lines
5.6 KiB
JavaScript
import React, { createContext, useContext, useState, useEffect } from "react";
|
|
import { supabase } from "@/config/supabase";
|
|
import { message } from "antd";
|
|
import { useNavigate, useSearchParams, useLocation } from "react-router-dom";
|
|
import { supabaseService } from "@/hooks/supabaseService";
|
|
import { v4 as uuidv4 } from "uuid";
|
|
|
|
const AuthContext = createContext({});
|
|
|
|
export const AuthProvider = ({ children }) => {
|
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
const [user, setUser] = useState({});
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
//处理google登录
|
|
const hash = window.location.hash.substring(1);
|
|
const hashParams = new URLSearchParams(hash);
|
|
const accessToken = hashParams.get("access_token");
|
|
const refreshToken = hashParams.get("refresh_token");
|
|
if (accessToken && refreshToken) {
|
|
(async () => {
|
|
const { data, error } = await supabase.auth.setSession({
|
|
access_token: accessToken,
|
|
refresh_token: refreshToken,
|
|
});
|
|
})();
|
|
}
|
|
}, [navigate]);
|
|
|
|
// 监听认证状态变化
|
|
useEffect(() => {
|
|
// 获取初始会话状态
|
|
const initSession = async () => {
|
|
try {
|
|
const {
|
|
data: { session },
|
|
error,
|
|
} = await supabase.auth.getSession();
|
|
|
|
const role = await checkInTeam(session?.user ?? null);
|
|
setUser({ ...session?.user, adminRole: role });
|
|
} catch (error) {
|
|
console.error("Error getting session:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
initSession();
|
|
}, []);
|
|
|
|
// useEffect(() => {
|
|
// const redirectTo = searchParams.get("redirectTo");
|
|
// if (redirectTo) {
|
|
// navigate(redirectTo);
|
|
// }
|
|
// }, [location.pathname]);
|
|
|
|
//检查时候在管理模块团队中,没有就自动加入
|
|
const checkInTeam = async (user) => {
|
|
if (!user) return null;
|
|
try {
|
|
const { data: teamData, error: teamError } = await supabase
|
|
.from("teams")
|
|
.select("*")
|
|
.eq("attributes->>type", "uppetaAdmin")
|
|
.single();
|
|
if (teamData) {
|
|
const { data: teamMembers, error: teamMembersError } = await supabase
|
|
.from("team_membership")
|
|
.select("*")
|
|
.eq("user_id", user.id)
|
|
.eq("team_id", teamData.id)
|
|
.single();
|
|
if (!teamMembers) {
|
|
// 自动加入团队
|
|
const { data: teamMembershipData, error: teamMembershipError } =
|
|
await supabaseService.insert("team_membership", {
|
|
id: uuidv4(),
|
|
user_id: user.id,
|
|
team_id: teamData.id,
|
|
role: "MEMBER",
|
|
is_creator: false,
|
|
});
|
|
return "MEMBER";
|
|
} else {
|
|
return teamMembers.role;
|
|
}
|
|
} else {
|
|
return "MEMBER";
|
|
}
|
|
} catch (error) {
|
|
console.error("Error checking in team:", error);
|
|
return "MEMBER";
|
|
}
|
|
};
|
|
|
|
// 邮箱密码登录
|
|
const login = async (email, password) => {
|
|
try {
|
|
setLoading(true);
|
|
const { data, error } = await supabase.auth.signInWithPassword({
|
|
email,
|
|
password,
|
|
});
|
|
|
|
if (error) {
|
|
message.error(error.message || "登录失败,请稍后重试");
|
|
return;
|
|
}
|
|
setUser(data.user);
|
|
return data;
|
|
} catch (error) {
|
|
message.error(error.message || "登录失败,请稍后重试");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// Google 登录
|
|
const signInWithGoogle = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const redirectTo = searchParams.get("redirectTo");
|
|
const { data, error } = await supabase.auth.signInWithOAuth({
|
|
provider: "google",
|
|
options: {
|
|
redirectTo: `${window.location.origin}/login?redirectTo=${
|
|
redirectTo ?? ""
|
|
}`,
|
|
},
|
|
});
|
|
|
|
if (error) {
|
|
message.error(error.message || "Google 登录失败,请稍后重试");
|
|
return;
|
|
}
|
|
|
|
return data;
|
|
} catch (error) {
|
|
message.error(error.message || "Google 登录失败,请稍后重试");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// 注册
|
|
const register = async (email, password) => {
|
|
try {
|
|
setLoading(true);
|
|
const { data, error } = await supabase.auth.signUp({
|
|
email,
|
|
password,
|
|
options: {
|
|
emailRedirectTo: `${window.location.origin}/auth/callback`,
|
|
},
|
|
});
|
|
|
|
if (error) {
|
|
throw error;
|
|
}
|
|
message.success("注册成功!请查收验证邮件。");
|
|
return data;
|
|
} catch (error) {
|
|
message.error(error.message || "注册失败");
|
|
throw error;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
// 登出
|
|
const logout = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const { error } = await supabase.auth.signOut({
|
|
scope: "local",
|
|
});
|
|
if (error) {
|
|
message.error(error.message || "登出失败,请稍后重试");
|
|
return;
|
|
}
|
|
setUser({});
|
|
message.success("已成功登出");
|
|
navigate(`/login?redirectTo=${location.pathname}`, { replace: true });
|
|
} catch (error) {
|
|
message.error(error.message || "登出失败,请稍后重试");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const value = {
|
|
user,
|
|
loading,
|
|
login,
|
|
logout,
|
|
register,
|
|
signInWithGoogle,
|
|
};
|
|
|
|
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
|
};
|
|
|
|
export const useAuth = () => {
|
|
const context = useContext(AuthContext);
|
|
return context;
|
|
};
|