Currently, I am referring to the tRPC documentation for guidance on creating a server side caller. But I'm facing a challenge in dynamically setting the value when incorporating it into my NextJS 13 pages.
In my context.ts file, you will find the following code snippet:
import { cookies } from "next/headers";
import * as jose from "jose";
import jwt from "jsonwebtoken";
import { inferAsyncReturnType } from "@trpc/server";
interface ContextUser {
id: number;
username: string;
token: string;
}
export async function createContext() {
async function getUserFromCookie(): Promise<ContextUser | null> {
var token = cookies().get("jwt");
if (!token?.value) return null;
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
try {
await jose.jwtVerify(token.value, secret);
} catch (error) {
return null;
}
const jwtPayload = jwt.decode(token.value) as any;
return {
id: jwtPayload.nameid,
username: jwtPayload.unique_name,
token: token.value,
};
}
const user = await getUserFromCookie();
return {
user,
};
}
export type Context = inferAsyncReturnType<typeof createContext>;
I have implemented middleware to verify the user and exported an authorized procedure:
import { TRPCError, initTRPC } from "@trpc/server";
import { Context } from "./context";
const t = initTRPC.context<Context>().create();
export const router = t.router;
export const publicProcedure = t.procedure;
const authorised = t.middleware(async ({ ctx, next }) => {
if (!ctx.user) throw new TRPCError({ code: "UNAUTHORIZED" });
return next();
});
export const authorisedProcedure = t.procedure.use(authorised);
In my server.ts file, I export a server client in the following manner:
import { appRouter } from "@/server";
export const trpcServerClient = appRouter.createCaller({
user: { id: 1, username: "foo", token: "bar" },
});
Upon calling a procedure using the trpcServerClient
with a valid cookie, although the token is observable within createContext
, it appears that the context is not properly set-in the procedure, where ctx
remains as
user: { id: 1, username: "foo", token: "bar" }
.
My confusion lies in how one can dynamically configure the context while utilizing a server client, especially given the requirement to input a value for the context in the createCaller
function?