"use client"; import { createContext, useContext, useEffect, useState } from "react"; import { onAuthStateChanged, signOut as firebaseSignOut, User } from "firebase/auth"; import { auth } from "@/lib/firebase"; import type { UserRole } from "@/lib/types"; interface AuthContextType { user: User | null; loading: boolean; role: UserRole | null; isAdmin: boolean; isOperator: boolean; ownedNodeIds: string[]; signOut: () => Promise; } const AuthContext = createContext({ user: null, loading: true, role: null, isAdmin: false, isOperator: false, ownedNodeIds: [], signOut: async () => {}, }); export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [role, setRole] = useState(null); const [ownedNodeIds, setOwnedNodeIds] = useState([]); useEffect(() => { return onAuthStateChanged(auth, async (u) => { setUser(u); setLoading(false); if (u) { document.cookie = "drb_session=1; path=/; SameSite=Strict"; const result = await u.getIdTokenResult(true); const claims = result.claims; // Derive role: prefer granular "role" claim, fall back to legacy "admin" boolean let effectiveRole: UserRole = "viewer"; if (claims.role === "admin" || claims.admin) { effectiveRole = "admin"; } else if (claims.role === "operator") { effectiveRole = "operator"; } else if (claims.role === "viewer") { effectiveRole = "viewer"; } setRole(effectiveRole); setOwnedNodeIds((claims.owned_node_ids as string[]) ?? []); } else { document.cookie = "drb_session=; path=/; max-age=0"; setRole(null); setOwnedNodeIds([]); } }); }, []); async function signOut() { await firebaseSignOut(auth); document.cookie = "drb_session=; path=/; max-age=0"; } const isAdmin = role === "admin"; const isOperator = role === "operator"; return ( {children} ); } export function useAuth() { return useContext(AuthContext); }