diff --git a/app/_components/FeatureComponents/Sidebar/Parts/SharedItemsList.tsx b/app/_components/FeatureComponents/Sidebar/Parts/SharedItemsList.tsx
index 0e39f408..1d1d3cf0 100644
--- a/app/_components/FeatureComponents/Sidebar/Parts/SharedItemsList.tsx
+++ b/app/_components/FeatureComponents/Sidebar/Parts/SharedItemsList.tsx
@@ -167,6 +167,7 @@ export const SharedItemsList = ({
handleItemClick(e, fullItem)}
data-sidebar-item-selected={isSelected}
className={cn(
diff --git a/app/_components/FeatureComponents/Sidebar/Parts/SidebarItem.tsx b/app/_components/FeatureComponents/Sidebar/Parts/SidebarItem.tsx
index 7f59fc74..ea959380 100644
--- a/app/_components/FeatureComponents/Sidebar/Parts/SidebarItem.tsx
+++ b/app/_components/FeatureComponents/Sidebar/Parts/SidebarItem.tsx
@@ -202,6 +202,7 @@ export const SidebarItem = ({
{
const router = useRouter();
+ const { user } = useAppMode();
const [isConnected, setIsConnected] = useState(false);
const wsRef = useRef(null);
const connectionIdRef = useRef(null);
@@ -70,6 +72,7 @@ export const WebSocketProvider = ({ children }: { children: ReactNode }) => {
const connect = useCallback(() => {
if (!mountedRef.current) return;
+ if (!user) return;
if (wsRef.current?.readyState === WebSocket.OPEN) return;
const isDev = process.env.NODE_ENV === "development";
@@ -111,7 +114,7 @@ export const WebSocketProvider = ({ children }: { children: ReactNode }) => {
};
wsRef.current = ws;
- }, [handleMessage]);
+ }, [handleMessage, user]);
useEffect(() => {
mountedRef.current = true;
diff --git a/app/api/serwist/[path]/route.ts b/app/api/serwist/[path]/route.ts
index b192063b..a8e737f8 100644
--- a/app/api/serwist/[path]/route.ts
+++ b/app/api/serwist/[path]/route.ts
@@ -1,15 +1,10 @@
-import { spawnSync } from "node:child_process";
import { createSerwistRoute } from "@serwist/turbopack";
-const revision = spawnSync("git", ["rev-parse", "HEAD"], {
- encoding: "utf-8",
-}).stdout?.trim() ?? crypto.randomUUID();
-
export const { dynamic, dynamicParams, revalidate, generateStaticParams, GET } =
createSerwistRoute({
- additionalPrecacheEntries: [{ url: "/~offline", revision }],
swSrc: "app/sw.ts",
useNativeEsbuild: true,
nextConfig: {},
maximumFileSizeToCacheInBytes: 6 * 1024 * 1024,
+ globIgnores: ["flags/**"],
});
diff --git a/package.json b/package.json
index c1e34799..908319f0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "jotty.page",
- "version": "1.21.0",
+ "version": "1.21.1",
"private": true,
"scripts": {
"dev": "next dev",
diff --git a/proxy.ts b/proxy.ts
index 88c76218..56e56c86 100644
--- a/proxy.ts
+++ b/proxy.ts
@@ -4,6 +4,43 @@ import { isEnvEnabled, isDebugFlag } from "./app/_utils/env-utils";
const debugProxy = isDebugFlag("proxy");
+const SESSION_CACHE_TTL = 10_000;
+const sessionCache = new Map();
+
+const _checkSession = async (sessionId: string, internalApiUrl: string, cookie: string) => {
+ const cached = sessionCache.get(sessionId);
+ if (cached && Date.now() - cached.ts < SESSION_CACHE_TTL) return cached.valid;
+
+ const sessionCheckUrl = new URL(`${internalApiUrl}/api/auth/check-session`);
+
+ if (debugProxy) {
+ console.log("MIDDLEWARE - Session Check URL:", sessionCheckUrl.href);
+ }
+
+ const res = await fetch(sessionCheckUrl, {
+ headers: { Cookie: cookie },
+ cache: "no-store",
+ });
+
+ if (debugProxy) {
+ console.log("MIDDLEWARE - Session Check Response:");
+ console.log(" status:", res.status);
+ console.log(" statusText:", res.statusText);
+ console.log(" ok:", res.ok);
+ }
+
+ sessionCache.set(sessionId, { valid: res.ok, ts: Date.now() });
+
+ if (sessionCache.size > 1000) {
+ const now = Date.now();
+ sessionCache.forEach((val, key) => {
+ if (now - val.ts > SESSION_CACHE_TTL) sessionCache.delete(key);
+ });
+ }
+
+ return res.ok;
+};
+
export const proxy = async (request: NextRequest) => {
const { pathname } = request.nextUrl;
@@ -61,27 +98,13 @@ export const proxy = async (request: NextRequest) => {
console.log(" → Using:", internalApiUrl);
}
- const sessionCheckUrl = new URL(`${internalApiUrl}/api/auth/check-session`);
-
- if (debugProxy) {
- console.log("MIDDLEWARE - Session Check URL:", sessionCheckUrl.href);
- }
-
- const sessionCheck = await fetch(sessionCheckUrl, {
- headers: {
- Cookie: request.headers.get("Cookie") || "",
- },
- cache: "no-store",
- });
-
- if (debugProxy) {
- console.log("MIDDLEWARE - Session Check Response:");
- console.log(" status:", sessionCheck.status);
- console.log(" statusText:", sessionCheck.statusText);
- console.log(" ok:", sessionCheck.ok);
- }
+ const valid = await _checkSession(
+ sessionId,
+ internalApiUrl,
+ request.headers.get("Cookie") || "",
+ );
- if (!sessionCheck.ok) {
+ if (!valid) {
const redirectResponse = NextResponse.redirect(loginUrl);
redirectResponse.cookies.delete(cookieName);
@@ -102,6 +125,6 @@ export const proxy = async (request: NextRequest) => {
export const config = {
matcher: [
- "/((?!_next/static|_next/image|favicon.ico|site.webmanifest|sw.js|app-icons).*)",
+ "/((?!_next/static|_next/image|favicon.ico|site.webmanifest|sw.js|app-icons|app-screenshots|flags|fonts|images|repo-images|themes|openapi.yaml).*)",
],
};