diff --git a/frontend/src/components/Modals/Password/index.jsx b/frontend/src/components/Modals/Password/index.jsx
index 6be4b3f6..11da0fc2 100644
--- a/frontend/src/components/Modals/Password/index.jsx
+++ b/frontend/src/components/Modals/Password/index.jsx
@@ -17,6 +17,7 @@ export default function PasswordModal({ mode = "single" }) {
export function usePasswordModal() {
const [auth, setAuth] = useState({
+ loading: true,
required: false,
mode: "single",
});
@@ -24,14 +25,26 @@ export function usePasswordModal() {
useEffect(() => {
async function checkAuthReq() {
if (!window) return;
- const settings = await System.keys();
+ // If the last validity check is still valid
+ // we can skip the loading.
+ if (!System.needsAuthCheck()) {
+ setAuth({
+ loading: false,
+ requiresAuth: false,
+ mode: "multi",
+ });
+ return;
+ }
+
+ const settings = await System.keys();
if (settings?.MultiUserMode) {
const currentToken = window.localStorage.getItem(AUTH_TOKEN);
if (!!currentToken) {
const valid = await System.checkAuth(currentToken);
if (!valid) {
setAuth({
+ loading: false,
requiresAuth: true,
mode: "multi",
});
@@ -40,6 +53,7 @@ export function usePasswordModal() {
return;
} else {
setAuth({
+ loading: false,
requiresAuth: false,
mode: "multi",
});
@@ -47,6 +61,7 @@ export function usePasswordModal() {
}
} else {
setAuth({
+ loading: false,
requiresAuth: true,
mode: "multi",
});
@@ -58,6 +73,7 @@ export function usePasswordModal() {
const requiresAuth = settings?.RequiresAuth || false;
if (!requiresAuth) {
setAuth({
+ loading: false,
requiresAuth: false,
mode: "single",
});
@@ -69,6 +85,7 @@ export function usePasswordModal() {
const valid = await System.checkAuth(currentToken);
if (!valid) {
setAuth({
+ loading: false,
requiresAuth: true,
mode: "single",
});
@@ -76,6 +93,7 @@ export function usePasswordModal() {
return;
} else {
setAuth({
+ loading: false,
requiresAuth: false,
mode: "single",
});
@@ -83,6 +101,7 @@ export function usePasswordModal() {
}
} else {
setAuth({
+ loading: false,
requiresAuth: true,
mode: "single",
});
diff --git a/frontend/src/models/system.js b/frontend/src/models/system.js
index 219690d1..6e74eb2a 100644
--- a/frontend/src/models/system.js
+++ b/frontend/src/models/system.js
@@ -1,4 +1,4 @@
-import { API_BASE } from "../utils/constants";
+import { API_BASE, AUTH_TIMESTAMP } from "../utils/constants";
import { baseHeaders } from "../utils/request";
const System = {
@@ -39,12 +39,22 @@ const System = {
.then((res) => res.localFiles)
.catch(() => null);
},
+ needsAuthCheck: function () {
+ const lastAuthCheck = window.localStorage.getItem(AUTH_TIMESTAMP);
+ if (!lastAuthCheck) return true;
+ const expiresAtMs = Number(lastAuthCheck) + 60 * 5 * 1000; // expires in 5 minutes in ms
+ return Number(new Date()) > expiresAtMs;
+ },
+
checkAuth: async function (currentToken = null) {
- return await fetch(`${API_BASE}/system/check-token`, {
+ const valid = await fetch(`${API_BASE}/system/check-token`, {
headers: baseHeaders(currentToken),
})
.then((res) => res.ok)
.catch(() => false);
+
+ window.localStorage.setItem(AUTH_TIMESTAMP, Number(new Date()));
+ return valid;
},
requestToken: async function (body) {
return await fetch(`${API_BASE}/request-token`, {
diff --git a/frontend/src/pages/Main/index.jsx b/frontend/src/pages/Main/index.jsx
index bfef421f..0a1e508f 100644
--- a/frontend/src/pages/Main/index.jsx
+++ b/frontend/src/pages/Main/index.jsx
@@ -5,10 +5,12 @@ import PasswordModal, {
usePasswordModal,
} from "../../components/Modals/Password";
import { isMobile } from "react-device-detect";
+import { FullScreenLoader } from "../../components/Preloader";
export default function Main() {
- const { requiresAuth, mode } = usePasswordModal();
+ const { loading, requiresAuth, mode } = usePasswordModal();
+ if (loading) return ;
if (requiresAuth !== false) {
return <>{requiresAuth !== null && }>;
}
diff --git a/frontend/src/pages/WorkspaceChat/index.jsx b/frontend/src/pages/WorkspaceChat/index.jsx
index db065cd2..5b466bda 100644
--- a/frontend/src/pages/WorkspaceChat/index.jsx
+++ b/frontend/src/pages/WorkspaceChat/index.jsx
@@ -7,10 +7,12 @@ import PasswordModal, {
usePasswordModal,
} from "../../components/Modals/Password";
import { isMobile } from "react-device-detect";
+import { FullScreenLoader } from "../../components/Preloader";
export default function WorkspaceChat() {
- const { requiresAuth, mode } = usePasswordModal();
+ const { loading, requiresAuth, mode } = usePasswordModal();
+ if (loading) return ;
if (requiresAuth !== false) {
return <>{requiresAuth !== null && }>;
}
diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js
index fe3a2308..602460fd 100644
--- a/frontend/src/utils/constants.js
+++ b/frontend/src/utils/constants.js
@@ -2,3 +2,4 @@ export const API_BASE = import.meta.env.VITE_API_BASE || "/api";
export const AUTH_USER = "anythingllm_user";
export const AUTH_TOKEN = "anythingllm_authToken";
+export const AUTH_TIMESTAMP = "anythingllm_authTimestamp";
diff --git a/server/endpoints/system.js b/server/endpoints/system.js
index 0dceddea..eed85839 100644
--- a/server/endpoints/system.js
+++ b/server/endpoints/system.js
@@ -316,7 +316,7 @@ function systemEndpoints(app) {
updateENV(
{
- AuthToken: '',
+ AuthToken: "",
JWTSecret: process.env.JWT_SECRET ?? v4(),
},
true