Files
cdc-project-management/src/context/AuthContext.tsx
T
2026-05-23 11:58:41 -04:00

108 lines
3.0 KiB
TypeScript

import React, {
createContext,
useContext,
useEffect,
useState,
useCallback,
type ReactNode,
} from "react";
import { onAuthStateChanged, signInWithPopup, signOut, type User } from "firebase/auth";
import { auth, googleProvider } from "@/lib/firebase";
const ALLOWED_DOMAIN = "gomezleemarketing.com";
const GERARDO_EMAIL = "gmarrero@gomezleemarketing.com";
function isAllowedEmail(email: string | null | undefined): boolean {
if (!email) return false;
return email.toLowerCase().endsWith(`@${ALLOWED_DOMAIN}`);
}
interface AuthContextValue {
user: User | null;
loading: boolean;
error: string | null;
isGerardo: boolean;
loginWithGoogle: () => Promise<void>;
logout: () => Promise<void>;
}
const AuthContext = createContext<AuthContextValue | null>(null);
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, async (firebaseUser) => {
if (firebaseUser) {
// Validate domain on every session restore (page reload, etc.)
if (!isAllowedEmail(firebaseUser.email)) {
await signOut(auth);
setUser(null);
setError("Solo se permite acceso con correos corporativos de GomezLee Marketing.");
} else {
setUser(firebaseUser);
setError(null);
}
} else {
setUser(null);
}
setLoading(false);
});
return () => unsubscribe();
}, []);
const loginWithGoogle = useCallback(async () => {
setError(null);
try {
const result = await signInWithPopup(auth, googleProvider);
const email = result.user.email?.toLowerCase() ?? "";
if (!isAllowedEmail(email)) {
await signOut(auth);
setUser(null);
setError("Solo se permite acceso con correos corporativos de GomezLee Marketing.");
return;
}
setUser(result.user);
} catch (err: unknown) {
// User closed popup or other cancellable error — don't treat as fatal
if (
err &&
typeof err === "object" &&
"code" in err &&
(err as { code: string }).code === "auth/popup-closed-by-user"
) {
return;
}
console.error("Error al iniciar sesión con Google:", err);
setError("No se pudo iniciar sesión. Intenta de nuevo.");
}
}, []);
const logout = useCallback(async () => {
await signOut(auth);
setUser(null);
setError(null);
}, []);
const isGerardo = !!user && user.email?.toLowerCase() === GERARDO_EMAIL;
return (
<AuthContext.Provider value={{ user, loading, error, isGerardo, loginWithGoogle, logout }}>
{children}
</AuthContext.Provider>
);
}
export function useAuth(): AuthContextValue {
const ctx = useContext(AuthContext);
if (!ctx) {
throw new Error("useAuth debe usarse dentro de <AuthProvider>");
}
return ctx;
}