Skip to content

Commit 2c01f8c

Browse files
committed
feat: Sync auth state across browser tabs
1 parent 87f4c7a commit 2c01f8c

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

frontend/src/lib/auth.tsx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { createContext, useCallback, useContext, useEffect } from "react";
1+
import { createContext, useCallback, useContext, useEffect, useRef } from "react";
22
import { API_BASE, fetcher, useFetch } from "./api";
33
import { connect, disconnect } from "./sse";
44

5+
const AUTH_BROADCAST_CHANNEL = "orca-auth";
6+
57
export interface AuthState {
68
isAuthenticated: boolean;
79
isLoading: boolean;
@@ -57,6 +59,43 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
5759
return disconnect;
5860
}, [isLoading, auth.isAuthenticated, refreshAuth]);
5961

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+
6099
const logout = useCallback(async () => {
61100
await fetch(`${API_BASE}/auth/logout`, { method: "POST" });
62101
await mutate(undefined, false);

0 commit comments

Comments
 (0)