mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-09-19 20:24:32 +02:00
Updated refreshing (#2327)
* clean up + add environment variables * remove log * update * update api settings * somewhat cleaner refresh functionality * fully functional * update settings * validated * remove random logs * remove unneeded paramter + log * move to ee + remove comments * Cleanup unused --------- Co-authored-by: Weves <chrisweaver101@gmail.com>
This commit is contained in:
@@ -58,6 +58,7 @@ ENV NEXT_PUBLIC_DO_NOT_USE_TOGGLE_OFF_DANSWER_POWERED=${NEXT_PUBLIC_DO_NOT_USE_T
|
||||
ARG NEXT_PUBLIC_DISABLE_LOGOUT
|
||||
ENV NEXT_PUBLIC_DISABLE_LOGOUT=${NEXT_PUBLIC_DISABLE_LOGOUT}
|
||||
|
||||
|
||||
RUN npx next build
|
||||
|
||||
# Step 2. Production image, copy all the files and run next
|
||||
|
@@ -91,7 +91,6 @@ import FunctionalHeader from "@/components/chat_search/Header";
|
||||
import { useSidebarVisibility } from "@/components/chat_search/hooks";
|
||||
import { SIDEBAR_TOGGLED_COOKIE_NAME } from "@/components/resizable/constants";
|
||||
import FixedLogo from "./shared_chat_search/FixedLogo";
|
||||
import { getSecondsUntilExpiration } from "@/lib/time";
|
||||
import { SetDefaultModelModal } from "./modal/SetDefaultModelModal";
|
||||
import { DeleteEntityModal } from "../../components/modals/DeleteEntityModal";
|
||||
import { MinimalMarkdown } from "@/components/chat_search/MinimalMarkdown";
|
||||
@@ -1559,7 +1558,6 @@ export function ChatPage({
|
||||
setDocumentSelection((documentSelection) => !documentSelection);
|
||||
setShowDocSidebar(false);
|
||||
};
|
||||
const secondsUntilExpiration = getSecondsUntilExpiration(user);
|
||||
|
||||
interface RegenerationRequest {
|
||||
messageId: number;
|
||||
@@ -1579,7 +1577,7 @@ export function ChatPage({
|
||||
|
||||
return (
|
||||
<>
|
||||
<HealthCheckBanner secondsUntilExpiration={secondsUntilExpiration} />
|
||||
<HealthCheckBanner />
|
||||
{/* ChatPopup is a custom popup that displays a admin-specified message on initial user visit.
|
||||
Only used in the EE version of the app. */}
|
||||
{popup}
|
||||
|
@@ -3,7 +3,6 @@ import "./globals.css";
|
||||
import {
|
||||
fetchEnterpriseSettingsSS,
|
||||
fetchSettingsSS,
|
||||
SettingsError,
|
||||
} from "@/components/settings/lib";
|
||||
import {
|
||||
CUSTOM_ANALYTICS_ENABLED,
|
||||
@@ -11,7 +10,7 @@ import {
|
||||
} from "@/lib/constants";
|
||||
import { SettingsProvider } from "@/components/settings/SettingsProvider";
|
||||
import { Metadata } from "next";
|
||||
import { buildClientUrl } from "@/lib/utilsSS";
|
||||
import { buildClientUrl, fetchSS } from "@/lib/utilsSS";
|
||||
import { Inter } from "next/font/google";
|
||||
import Head from "next/head";
|
||||
import { EnterpriseSettings } from "./admin/settings/interfaces";
|
||||
|
@@ -3,7 +3,6 @@ import {
|
||||
getAuthTypeMetadataSS,
|
||||
getCurrentUserSS,
|
||||
} from "@/lib/userSS";
|
||||
import { getSecondsUntilExpiration } from "@/lib/time";
|
||||
import { redirect } from "next/navigation";
|
||||
import { HealthCheckBanner } from "@/components/health/healthcheck";
|
||||
import { ApiKeyModal } from "@/components/llm/ApiKeyModal";
|
||||
@@ -179,11 +178,10 @@ export default async function Home() {
|
||||
const agenticSearchEnabled = agenticSearchToggle
|
||||
? agenticSearchToggle.value.toLocaleLowerCase() == "true" || false
|
||||
: false;
|
||||
const secondsUntilExpiration = getSecondsUntilExpiration(user);
|
||||
|
||||
return (
|
||||
<>
|
||||
<HealthCheckBanner secondsUntilExpiration={secondsUntilExpiration} />
|
||||
<HealthCheckBanner />
|
||||
{shouldShowWelcomeModal && <WelcomeModal user={user} />}
|
||||
<InstantSSRAutoRefresh />
|
||||
|
||||
|
@@ -3,29 +3,95 @@
|
||||
import { errorHandlingFetcher, RedirectError } from "@/lib/fetcher";
|
||||
import useSWR from "swr";
|
||||
import { Modal } from "../Modal";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getSecondsUntilExpiration } from "@/lib/time";
|
||||
import { User } from "@/lib/types";
|
||||
|
||||
export const HealthCheckBanner = ({
|
||||
secondsUntilExpiration,
|
||||
}: {
|
||||
secondsUntilExpiration?: number | null;
|
||||
}) => {
|
||||
export const HealthCheckBanner = () => {
|
||||
const { error } = useSWR("/api/health", errorHandlingFetcher);
|
||||
const [expired, setExpired] = useState(false);
|
||||
const [secondsUntilExpiration, setSecondsUntilExpiration] = useState<
|
||||
number | null
|
||||
>(null);
|
||||
const { data: user, mutate: mutateUser } = useSWR<User>(
|
||||
"/api/me",
|
||||
errorHandlingFetcher
|
||||
);
|
||||
|
||||
if (secondsUntilExpiration !== null && secondsUntilExpiration !== undefined) {
|
||||
setTimeout(
|
||||
() => {
|
||||
setExpired(true);
|
||||
},
|
||||
secondsUntilExpiration * 1000 - 200
|
||||
);
|
||||
}
|
||||
const updateExpirationTime = async () => {
|
||||
const updatedUser = await mutateUser();
|
||||
|
||||
if (updatedUser) {
|
||||
const seconds = getSecondsUntilExpiration(updatedUser);
|
||||
setSecondsUntilExpiration(seconds);
|
||||
console.debug(`Updated seconds until expiration:! ${seconds}`);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
updateExpirationTime();
|
||||
}, [user]);
|
||||
|
||||
useEffect(() => {
|
||||
if (true) {
|
||||
let refreshTimeoutId: NodeJS.Timeout;
|
||||
let expireTimeoutId: NodeJS.Timeout;
|
||||
|
||||
const refreshToken = async () => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
"/api/enterprise-settings/refresh-token",
|
||||
{
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
console.debug("Token refresh successful");
|
||||
// Force revalidation of user data
|
||||
|
||||
await mutateUser(undefined, { revalidate: true });
|
||||
updateExpirationTime();
|
||||
} catch (error) {
|
||||
console.error("Error refreshing token:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const scheduleRefreshAndExpire = () => {
|
||||
if (secondsUntilExpiration !== null) {
|
||||
const timeUntilRefresh = (secondsUntilExpiration + 0.5) * 1000;
|
||||
refreshTimeoutId = setTimeout(refreshToken, timeUntilRefresh);
|
||||
|
||||
const timeUntilExpire = (secondsUntilExpiration + 10) * 1000;
|
||||
expireTimeoutId = setTimeout(() => {
|
||||
console.debug("Session expired. Setting expired state to true.");
|
||||
setExpired(true);
|
||||
}, timeUntilExpire);
|
||||
}
|
||||
};
|
||||
|
||||
scheduleRefreshAndExpire();
|
||||
|
||||
return () => {
|
||||
clearTimeout(refreshTimeoutId);
|
||||
clearTimeout(expireTimeoutId);
|
||||
};
|
||||
}
|
||||
}, [secondsUntilExpiration, user]);
|
||||
|
||||
if (!error && !expired) {
|
||||
return null;
|
||||
}
|
||||
|
||||
console.debug(
|
||||
`Rendering HealthCheckBanner. Error: ${error}, Expired: ${expired}`
|
||||
);
|
||||
|
||||
if (error instanceof RedirectError || expired) {
|
||||
return (
|
||||
<Modal
|
||||
|
@@ -101,6 +101,7 @@ export function getSecondsUntilExpiration(
|
||||
if (!userInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { oidc_expiry, current_token_created_at, current_token_expiry_length } =
|
||||
userInfo;
|
||||
|
||||
|
@@ -10,6 +10,7 @@ const eePaths = [
|
||||
"/admin/whitelabeling",
|
||||
"/admin/performance/custom-analytics",
|
||||
];
|
||||
|
||||
const eePathsForMatcher = eePaths.map((path) => `${path}/:path*`);
|
||||
|
||||
export async function middleware(request: NextRequest) {
|
||||
|
Reference in New Issue
Block a user