Fix 404 error when saving user preferences

Routes using withAuth were creating new unauthenticated PocketBase
clients, causing 404 errors when trying to update records. Modified
withAuth to pass the authenticated pb client to handlers so they can
use it for database operations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-12 16:45:55 +00:00
parent df2f52ad50
commit 2408839b8b
17 changed files with 91 additions and 119 deletions

View File

@@ -113,7 +113,12 @@ describe("withAuth", () => {
const response = await wrappedHandler(mockRequest);
expect(response.status).toBe(200);
expect(handler).toHaveBeenCalledWith(mockRequest, mockUser, undefined);
expect(handler).toHaveBeenCalledWith(
mockRequest,
mockUser,
mockPbClient,
undefined,
);
});
it("loads auth from cookies before checking authentication", async () => {
@@ -159,7 +164,7 @@ describe("withAuth", () => {
await wrappedHandler(mockRequest, { params: mockParams });
expect(handler).toHaveBeenCalledWith(mockRequest, mockUser, {
expect(handler).toHaveBeenCalledWith(mockRequest, mockUser, mockPbClient, {
params: mockParams,
});
});

View File

@@ -4,6 +4,7 @@
import { cookies } from "next/headers";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
import type PocketBase from "pocketbase";
import type { User } from "@/types";
@@ -16,24 +17,27 @@ import {
} from "./pocketbase";
/**
* Route handler function type that receives the authenticated user.
* Route handler function type that receives the authenticated user and PocketBase client.
*/
export type AuthenticatedHandler<T = unknown> = (
request: NextRequest,
user: User,
pb: PocketBase,
context?: { params?: T },
) => Promise<NextResponse>;
/**
* Higher-order function that wraps an API route handler with authentication.
* Loads auth from cookies, validates the session, and passes the user to the handler.
* Loads auth from cookies, validates the session, and passes the user and
* authenticated PocketBase client to the handler.
*
* @param handler - The route handler that requires authentication
* @returns A wrapped handler that checks auth before calling the original handler
*
* @example
* ```ts
* export const GET = withAuth(async (request, user) => {
* export const GET = withAuth(async (request, user, pb) => {
* const data = await pb.collection("users").getOne(user.id);
* return NextResponse.json({ email: user.email });
* });
* ```
@@ -66,8 +70,8 @@ export function withAuth<T = unknown>(
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Call the original handler with the user context
return await handler(request, user, context);
// Call the original handler with the user context and authenticated pb client
return await handler(request, user, pb, context);
} catch (error) {
logger.error({ err: error }, "Auth middleware error");
return NextResponse.json(