fix: kill session on signOut, .maybeSingle() for 406, remove StrictMode

This commit is contained in:
root 2026-05-26 14:36:50 +00:00
parent cbc6242613
commit 844f052462
2 changed files with 27 additions and 13 deletions

View File

@ -108,7 +108,7 @@ export const fetchUserProfile = async (userId) => {
.from("users") .from("users")
.select("id, email, name, role_id, last_login, roles(name)") .select("id, email, name, role_id, last_login, roles(name)")
.eq("id", userId) .eq("id", userId)
.single(); .maybeSingle();
if (error || !data) return null; if (error || !data) return null;
return { return {
id: data.id, id: data.id,
@ -119,8 +119,21 @@ export const fetchUserProfile = async (userId) => {
}; };
}; };
/** Clear all auth state from storage — called on explicit signOut */
const clearAllAuthStorage = () => {
// Clear Supabase secureStorage keys from sessionStorage
sessionStorage.removeItem("supersam-auth");
sessionStorage.removeItem("supersam-ak");
// Clear local auth cache from localStorage
localStorage.removeItem(STORAGE_KEY);
localStorage.removeItem("construction-auth-role-hint");
};
export const AuthProvider = ({ children }) => { export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(() => { const [user, setUser] = useState(() => {
// Demo mode reads from localStorage; Supabase mode always starts null
// (session restore happens via onAuthStateChange/getSession)
if (hasSupabaseConfig) return null;
const stored = localStorage.getItem(STORAGE_KEY); const stored = localStorage.getItem(STORAGE_KEY);
return stored ? decodeLocalAuth(stored) : null; return stored ? decodeLocalAuth(stored) : null;
}); });
@ -162,6 +175,7 @@ export const AuthProvider = ({ children }) => {
if (error && isStaleRefreshTokenError(error)) { if (error && isStaleRefreshTokenError(error)) {
setUser(null); setUser(null);
setAuthError("Сессия истекла. Войдите заново."); setAuthError("Сессия истекла. Войдите заново.");
clearAllAuthStorage();
void supabase.auth.signOut({ scope: "local" }); void supabase.auth.signOut({ scope: "local" });
return; return;
} }
@ -297,8 +311,10 @@ export const AuthProvider = ({ children }) => {
const signOut = async () => { const signOut = async () => {
if (hasSupabaseConfig && supabase) { if (hasSupabaseConfig && supabase) {
await supabase.auth.signOut(); await supabase.auth.signOut({ scope: "local" });
} }
// Hard clear all auth storage so auto-login is impossible after logout
clearAllAuthStorage();
setUser(null); setUser(null);
setPendingEmail(""); setPendingEmail("");
setIsOtpSent(false); setIsOtpSent(false);

View File

@ -13,13 +13,11 @@ registerPwaServiceWorker();
initErrorLogging(); initErrorLogging();
ReactDOM.createRoot(document.getElementById("root")).render( ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<ThemeProvider> <ThemeProvider>
<AuthProvider> <AuthProvider>
<ErrorBoundary> <ErrorBoundary>
<RouterProvider router={router} /> <RouterProvider router={router} />
</ErrorBoundary> </ErrorBoundary>
</AuthProvider> </AuthProvider>
</ThemeProvider> </ThemeProvider>,
</React.StrictMode>,
); );