mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-07-07 05:00:22 +02:00
k
This commit is contained in:
@ -1,6 +0,0 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# Add production endpoints here
|
@ -423,8 +423,7 @@ def get_application() -> FastAPI:
|
||||
# NOTE: needs to be outside of the `if __name__ == "__main__"` block so that the
|
||||
# app is exportable
|
||||
set_is_ee_based_on_env_variable()
|
||||
# Call get_application() to get the actual application instance
|
||||
app = fetch_versioned_implementation(module="onyx.main", attribute="get_application")()
|
||||
app = fetch_versioned_implementation(module="onyx.main", attribute="get_application")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -12,6 +12,7 @@ import { getCurrentUser } from "@/lib/user";
|
||||
import { usePostHog } from "posthog-js/react";
|
||||
import { CombinedSettings } from "@/app/admin/settings/interfaces";
|
||||
import { SettingsContext } from "../settings/SettingsProvider";
|
||||
import { useTokenRefresh } from "@/hooks/useTokenRefresh";
|
||||
|
||||
interface UserContextType {
|
||||
user: User | null;
|
||||
@ -71,12 +72,6 @@ export function UserProvider({
|
||||
mergeUserPreferences(user, settings)
|
||||
);
|
||||
|
||||
// Track last refresh time to avoid unnecessary calls
|
||||
const [lastTokenRefresh, setLastTokenRefresh] = useState<number>(Date.now());
|
||||
|
||||
// Use a ref to track first load
|
||||
const isFirstLoad = useRef(true);
|
||||
|
||||
useEffect(() => {
|
||||
setUpToDateUser(mergeUserPreferences(user, updatedSettings));
|
||||
}, [user, updatedSettings]);
|
||||
@ -97,74 +92,6 @@ export function UserProvider({
|
||||
}
|
||||
}, [posthog, user]);
|
||||
|
||||
// Implement token refresh mechanism
|
||||
useEffect(() => {
|
||||
if (!upToDateUser) return;
|
||||
|
||||
// Refresh token every 10 minutes (600000ms)
|
||||
// This is shorter than the session expiry time to ensure tokens stay valid
|
||||
const REFRESH_INTERVAL = 600000;
|
||||
|
||||
const refreshTokenPeriodically = async () => {
|
||||
try {
|
||||
// Skip time check if this is first load - we always refresh on first load
|
||||
const isTimeToRefresh =
|
||||
isFirstLoad.current ||
|
||||
Date.now() - lastTokenRefresh > REFRESH_INTERVAL - 60000;
|
||||
|
||||
if (!isTimeToRefresh) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset first load flag
|
||||
if (isFirstLoad.current) {
|
||||
isFirstLoad.current = false;
|
||||
}
|
||||
|
||||
const response = await fetch("/api/auth/refresh", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
// Update last refresh time on success
|
||||
setLastTokenRefresh(Date.now());
|
||||
console.debug("Auth token refreshed successfully");
|
||||
} else {
|
||||
console.warn("Failed to refresh auth token:", response.status);
|
||||
// If token refresh fails, try to get current user info
|
||||
await fetchUser();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error refreshing auth token:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Always attempt to refresh on first component mount
|
||||
// This helps ensure tokens are fresh, especially after browser refresh
|
||||
refreshTokenPeriodically();
|
||||
|
||||
// Set up interval for periodic refreshes
|
||||
const intervalId = setInterval(refreshTokenPeriodically, REFRESH_INTERVAL);
|
||||
|
||||
// Also refresh token on window focus, but no more than once per minute
|
||||
const handleVisibilityChange = () => {
|
||||
if (
|
||||
document.visibilityState === "visible" &&
|
||||
Date.now() - lastTokenRefresh > 60000
|
||||
) {
|
||||
refreshTokenPeriodically();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
};
|
||||
}, [upToDateUser, lastTokenRefresh]);
|
||||
|
||||
const fetchUser = async () => {
|
||||
try {
|
||||
const currentUser = await getCurrentUser();
|
||||
@ -173,6 +100,10 @@ export function UserProvider({
|
||||
console.error("Error fetching current user:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Use the custom token refresh hook
|
||||
useTokenRefresh(upToDateUser, fetchUser);
|
||||
|
||||
const updateUserTemperatureOverrideEnabled = async (enabled: boolean) => {
|
||||
try {
|
||||
setUpToDateUser((prevUser) => {
|
||||
|
89
web/src/hooks/useTokenRefresh.ts
Normal file
89
web/src/hooks/useTokenRefresh.ts
Normal file
@ -0,0 +1,89 @@
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import { User } from "@/lib/types";
|
||||
|
||||
/**
|
||||
* Custom hook for handling JWT token refresh
|
||||
*
|
||||
* @param user The current user or null if not logged in
|
||||
* @param onRefreshFail Callback function to execute if token refresh fails
|
||||
* @returns Object containing the last token refresh timestamp
|
||||
*/
|
||||
export function useTokenRefresh(
|
||||
user: User | null,
|
||||
onRefreshFail: () => Promise<void>
|
||||
) {
|
||||
// Track last refresh time to avoid unnecessary calls
|
||||
const [lastTokenRefresh, setLastTokenRefresh] = useState<number>(Date.now());
|
||||
|
||||
// Use a ref to track first load
|
||||
const isFirstLoad = useRef(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
|
||||
// Refresh token every 10 minutes (600000ms)
|
||||
// This is shorter than the session expiry time to ensure tokens stay valid
|
||||
const REFRESH_INTERVAL = 600000;
|
||||
|
||||
const refreshTokenPeriodically = async () => {
|
||||
try {
|
||||
// Skip time check if this is first load - we always refresh on first load
|
||||
const isTimeToRefresh =
|
||||
isFirstLoad.current ||
|
||||
Date.now() - lastTokenRefresh > REFRESH_INTERVAL - 60000;
|
||||
|
||||
if (!isTimeToRefresh) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset first load flag
|
||||
if (isFirstLoad.current) {
|
||||
isFirstLoad.current = false;
|
||||
}
|
||||
|
||||
const response = await fetch("/api/auth/refresh", {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
// Update last refresh time on success
|
||||
setLastTokenRefresh(Date.now());
|
||||
console.debug("Auth token refreshed successfully");
|
||||
} else {
|
||||
console.warn("Failed to refresh auth token:", response.status);
|
||||
// If token refresh fails, try to get current user info
|
||||
await onRefreshFail();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error refreshing auth token:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Always attempt to refresh on first component mount
|
||||
// This helps ensure tokens are fresh, especially after browser refresh
|
||||
refreshTokenPeriodically();
|
||||
|
||||
// Set up interval for periodic refreshes
|
||||
const intervalId = setInterval(refreshTokenPeriodically, REFRESH_INTERVAL);
|
||||
|
||||
// Also refresh token on window focus, but no more than once per minute
|
||||
const handleVisibilityChange = () => {
|
||||
if (
|
||||
document.visibilityState === "visible" &&
|
||||
Date.now() - lastTokenRefresh > 60000
|
||||
) {
|
||||
refreshTokenPeriodically();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
};
|
||||
}, [user, lastTokenRefresh, onRefreshFail]);
|
||||
|
||||
return { lastTokenRefresh };
|
||||
}
|
Reference in New Issue
Block a user