feat(auth): proactive session expiry redirect across all delivery paths

- Split auth config into auth.config.ts (edge-safe, no argon2) and auth-edge.ts
  for middleware use; auth.ts now spreads the shared config
- Middleware wraps with auth() to redirect unauthenticated requests to /auth/signin
  before any page render; passes through /auth/, /api/, /invite/ paths
- SessionGuard client component watches useSession() and redirects on
  status=unauthenticated, closing the SPA navigation gap
- QueryCache + MutationCache in TRPCProvider redirect on UNAUTHORIZED tRPC errors
  without retrying; SessionProvider polls session state every 5 minutes
- Middleware tests updated for async auth wrapper and auth-edge mock

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-04-03 10:42:10 +02:00
parent ed4d4e4640
commit bf8577dbaf
8 changed files with 151 additions and 57 deletions
@@ -0,0 +1,21 @@
"use client";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
// Watches the client-side session state and redirects to /auth/signin
// when the session expires mid-SPA-session (without a full page reload).
// Rendered in the authenticated layout — never visible to the user.
export function SessionGuard() {
const { status } = useSession();
const router = useRouter();
useEffect(() => {
if (status === "unauthenticated") {
router.replace("/auth/signin");
}
}, [status, router]);
return null;
}