forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
1import { useState, useEffect, createContext, useContext } from "react";
2
3export interface User {
4 did: string;
5 handle: string;
6 email?: string;
7}
8
9export interface SessionData {
10 authenticated: boolean;
11 user?: User;
12 accessToken?: string;
13}
14
15// Export context and hook for use in other components
16export const SessionContext = createContext<{
17 session: SessionData | null;
18 isLoading: boolean;
19} | null>(null);
20
21export function useSessionContext() {
22 const context = useContext(SessionContext);
23 if (!context) {
24 throw new Error("useSessionContext must be used within SessionProvider");
25 }
26 return context;
27}
28
29/**
30 * Hook to check session status from the server.
31 *
32 * This replaces the client-side AuthProvider from @slices/react.
33 * Instead of managing OAuth tokens in the browser, we check the
34 * server session which is managed via HTTP-only cookies.
35 */
36export function useSession() {
37 const [session, setSession] = useState<SessionData | null>(null);
38 const [isLoading, setIsLoading] = useState(true);
39
40 useEffect(() => {
41 async function checkSession() {
42 try {
43 const response = await fetch("/api/session", {
44 credentials: "include", // Important: include cookies
45 });
46
47 if (response.ok) {
48 const data = await response.json();
49 setSession(data);
50 } else {
51 setSession({ authenticated: false });
52 }
53 } catch (error) {
54 console.error("Failed to check session:", error);
55 setSession({ authenticated: false });
56 } finally {
57 setIsLoading(false);
58 }
59 }
60
61 checkSession();
62 }, []);
63
64 return { session, isLoading };
65}
66
67/**
68 * Simple logout function that calls the server logout endpoint.
69 */
70export async function logout() {
71 try {
72 await fetch("/logout", {
73 method: "POST",
74 credentials: "include",
75 });
76 // Redirect to login page
77 globalThis.location.href = "/login";
78 } catch (error) {
79 console.error("Logout failed:", error);
80 }
81}