0

I'm implementing authentication middleware in a Next.js (v13+) application using NextAuth.js, and I'm encountering an error when trying to validate the session token. The error occurs in the oidc-token-hash dependency, but I can't identify what's causing it.

Error Details

TypeError: Cannot read properties of undefined (reading 'substring')
    at [project]/node_modules/oidc-token-hash/lib/shake256.js [middleware-edge]
    ...

Current Implementation

Here's my middleware code (simplified for clarity):

// middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";
import type { UserRole } from "@prisma/client";
import { refreshSession } from "@/lib/auth/session";
import { validateCsrfToken } from "@/lib/auth/csrf";

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  if (shouldSkipMiddleware(pathname)) {
    return NextResponse.next();
  }

  // Debugging: Log request details
  console.log(`Processing ${request.method} ${pathname}`);

  let token;
  try {
    token = await getToken({
      req: request,
      secret: process.env.NEXTAUTH_SECRET,
    });

    console.log("Token:", token ? "Exists" : "Null");
    if (token) {
      console.log("Token details:", {
        sub: token.sub,
        role: token.role,
        exp: token.exp,
        status: token.status,
      });
    }
  } catch (error) {
    console.error("Token validation error:", error);
    return redirectToLogin(request, pathname, "TokenError");
  }

  if (!token) {
    console.log("No token - redirecting to login");
    return redirectToLogin(request, pathname, "NoSession");
  }

  if (!token.sub) {
    console.log("Token missing sub - redirecting to login");
    return redirectToLogin(request, pathname, "InvalidSession");
  }
  // Handle authenticated users trying to access auth routes
  if (authRoutes.has(pathname)) {
    return redirectToRoleDashboard(token.role as UserRole, request);
  }

  // Check for session expiration
  if (typeof token.exp === "number" && isSessionExpired(token.exp)) {
    return redirectToLogin(request, pathname, "SessionExpired");
  }

  // Try refreshing session
  try {
    await refreshSession(token.id);
  } catch (error) {
    console.error("Session validation failed:", error);
    return redirectToLogin(request, pathname, "SessionError");
  }

  // Unverified account
  if (token.status !== "VERIFIED") {
    return redirectToVerification(request, pathname);
  }

  // Password reset required
  if (token.resetRequired && pathname !== "/auth/reset-password") {
    return redirectToPasswordReset(request, pathname);
  }

  // CSRF check for sensitive POSTs
  if (request.method === "POST" && sensitiveRoutes.has(pathname)) {
    const csrfValid = await validateCsrfToken(request);
    if (!csrfValid) {
      return new NextResponse("Invalid CSRF token", { status: 403 });
    }
  }
  // Role-based routing
  return handleRoleBasedRouting(token.role as UserRole, pathname, request);
}

Full Error Stack

TypeError: Cannot read properties of undefined (reading 'substring')
    at [project]/node_modules/oidc-token-hash/lib/shake256.js [middleware-edge] (ecmascript) (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/node_modules_0dd80849._.js:1699:40)
    at <unknown> (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:709:27)
    at runModuleExecutionHooks (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:755:9)
    at instantiateModule (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:707:9)
    at getOrInstantiateModuleFromParent (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:640:12)
    at commonJsRequire (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:158:20)
    at [project]/node_modules/oidc-token-hash/lib/index.js [middleware-edge] (ecmascript) (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/node_modules_0dd80849._.js:1712:40)
    at <unknown> (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:709:27)
    at runModuleExecutionHooks (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:755:9)
    at instantiateModule (file:///Users/noeal/Desktop/recruitment-platform/web-app/.next/server/edge/chunks/edge-wrapper_4928c16f.js:707:9)

What I've Tried

  1. Verified NEXTAUTH_SECRET is properly set in environment variables
  2. Added extensive error logging and try-catch blocks
  3. Confirmed the session cookie exists in the request
  4. Updated all dependencies (next-auth, next, etc.)

Additional Information

  • Next.js version: 15.2.4
  • NextAuth.js version: 4.24.11
  • Authentication Provider: Credentials provider with Prisma adapter
  • Session Strategy: JWT
  • Reproduction: The error occurs when accessing all routes

Questions

  1. What could be causing the substring error in oidc-token-hash?
  2. Is there a configuration issue with how I'm using getToken in middleware?
  3. Could this be related to JWT vs. database session strategy?
  4. Are there known compatibility issues between these package versions?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.