|
1 | | -import { createContext, useCallback, useContext, useEffect } from "react"; |
| 1 | +import { createContext, useCallback, useContext, useEffect, useRef } from "react"; |
2 | 2 | import { API_BASE, fetcher, useFetch } from "./api"; |
3 | 3 | import { connect, disconnect } from "./sse"; |
4 | 4 |
|
| 5 | +const AUTH_BROADCAST_CHANNEL = "orca-auth"; |
| 6 | + |
5 | 7 | export interface AuthState { |
6 | 8 | isAuthenticated: boolean; |
7 | 9 | isLoading: boolean; |
@@ -57,6 +59,43 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { |
57 | 59 | return disconnect; |
58 | 60 | }, [isLoading, auth.isAuthenticated, refreshAuth]); |
59 | 61 |
|
| 62 | + const channelRef = useRef<BroadcastChannel | null>(null); |
| 63 | + const prevAuthRef = useRef<boolean | null>(null); |
| 64 | + |
| 65 | + useEffect(() => { |
| 66 | + const channel = new BroadcastChannel(AUTH_BROADCAST_CHANNEL); |
| 67 | + channelRef.current = channel; |
| 68 | + |
| 69 | + channel.addEventListener("message", async (event: MessageEvent<{ type: string }>) => { |
| 70 | + if (event.data.type === "logout") { |
| 71 | + await mutate(undefined, false); |
| 72 | + } else if (event.data.type === "login") { |
| 73 | + await mutate(); |
| 74 | + } |
| 75 | + }); |
| 76 | + |
| 77 | + return () => { |
| 78 | + channel.close(); |
| 79 | + channelRef.current = null; |
| 80 | + }; |
| 81 | + }, [mutate]); |
| 82 | + |
| 83 | + useEffect(() => { |
| 84 | + if (isLoading) { |
| 85 | + return; |
| 86 | + } |
| 87 | + |
| 88 | + if (prevAuthRef.current === null) { |
| 89 | + prevAuthRef.current = auth.isAuthenticated; |
| 90 | + return; |
| 91 | + } |
| 92 | + |
| 93 | + if (prevAuthRef.current !== auth.isAuthenticated) { |
| 94 | + prevAuthRef.current = auth.isAuthenticated; |
| 95 | + channelRef.current?.postMessage({ type: auth.isAuthenticated ? "login" : "logout" }); |
| 96 | + } |
| 97 | + }, [isLoading, auth.isAuthenticated]); |
| 98 | + |
60 | 99 | const logout = useCallback(async () => { |
61 | 100 | await fetch(`${API_BASE}/auth/logout`, { method: "POST" }); |
62 | 101 | await mutate(undefined, false); |
|
0 commit comments