jstack
jstack copied to clipboard
(Headers doesn't pass) Jstack Better Auth Incompatibility in Different Server and Client
import { NextRequest, NextResponse } from "next/server";
import { client } from "./lib/client";
import { headers } from "next/headers";
export const middleware = async (req: NextRequest) => {
const { userSession } = await (
await client.user.getUserSession.$get(undefined, {
headers: Object.fromEntries(await headers())
})
).json();
console.log(Object.fromEntries(await headers()));
const response = NextResponse.next();
if (
req.nextUrl.pathname.startsWith("/admin") &&
userSession?.user?.role !== "admin"
) {
return NextResponse.redirect(new URL("/auth/login"));
}
if (
req.nextUrl.pathname === "/auth/login" &&
userSession &&
userSession?.session
) {
return NextResponse.redirect(new URL("/"));
}
return response;
};
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)"
]
};
To pass headers I need to manually define the headers () from nextjs, Without that the headers are completely different.
accept: '*/*',
accept-encoding: 'gzip, deflate, br, zstd',
accept-language: 'en-US,en;q=0.5',
connection: 'keep-alive',
cookie: '__next_hmr_refresh_hash__=726df19e3771ec55715bb6e22717cc483fbb1af8a9eada5e',
dnt: '1',
host: '127.0.0.1:3000',
priority: 'u=4',
referer: 'http://127.0.0.1:3000/',
sec-fetch-dest: 'empty',
sec-fetch-mode: 'cors',
sec-fetch-site: 'same-origin',
sec-gpc: '1',
user-agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0',
x-forwarded-for: '127.0.0.1',
x-forwarded-host: '127.0.0.1:3000',
x-forwarded-port: '3000',
x-forwarded-proto: 'http'
}
await headers()
Headers(8) {
'accept' => '*/*',
'accept-encoding' => 'br, gzip',
'accept-language' => '*',
'cache-control' => 'no-cache',
'host' => '127.0.0.1:8787',
'pragma' => 'no-cache',
'sec-fetch-mode' => 'cors',
'user-agent' => 'node',
[immutable]: false
}
c.req.raw.headers on the procedure.
And also beacuse only the procedure gets the headers I have a prblem with this c.set() because this one has no session
import { AppContext, j } from "./jstack";
import { emailRouter } from "./routers/email-router";
import { adminRouter } from "./routers/admin-router";
import { aiRouter } from "./routers/ai-router";
import { propertyRouter } from "./routers/property-router";
import { mapsRouter } from "./routers/map-router";
import { blogRouter } from "./routers/blog-router";
import { roomRouter } from "./routers/room-router";
import { cors } from "hono/cors";
import * as Sentry from "@sentry/cloudflare";
import { userRouter } from "./routers/user-router";
import { auth } from "./db/auth/config";
import { env } from "hono/adapter";
export const corsMiddleware = cors({
origin: (origin) => origin,
exposeHeaders: ["x-is-superjson", "Content-Length", "X-Kuma-Revision"],
allowHeaders: [
"Content-Type",
"Upgrade-Insecure-Requests",
"Authorization",
"x-is-superjson",
"Access-Control-Allow-Headers",
"X-Requested-With",
"X-Custom-Header"
],
allowMethods: ["POST", "GET", "OPTIONS"],
maxAge: 86400,
credentials: true
});
const api = j
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.router<any, AppContext>()
.basePath("/api")
.use(corsMiddleware)
.onError(j.defaults.errorHandler);
const appRouter = j.mergeRouters(api, {
email: emailRouter,
admin: adminRouter,
ai: aiRouter,
property: propertyRouter,
map: mapsRouter,
blog: blogRouter,
room: roomRouter,
user: userRouter
});
appRouter.all("/auth/*", async (c) => {
const envItems = env(c);
return await auth({ ...envItems }).handler(c.req.raw);
});
appRouter.use("*", async (c, next) => {
const envItems = env(c);
const session = await auth({ ...envItems }).api.getSession({
headers: c.req.raw.headers
});
if (!session) {
c.set("user", null);
c.set("session", null);
return next();
}
c.set("user", session.user);
c.set("session", session.session);
return next();
});
appRouter.on(["POST", "GET"], "/web-callback/*", (c) => {
const { NEXT_PUBLIC_BASE_URL } = env(c);
const url = new URL(c.req.url);
const callbackPath = url.pathname.replace(/^\/api\/web-callback/, "");
return c.redirect(new URL(NEXT_PUBLIC_BASE_URL + callbackPath));
});
export type AppRouter = typeof appRouter;
export default Sentry.withSentry(
() => ({
dsn: "https://2acb62944acc5111edcb23b3c30dcfd0@o4508889302433792.ingest.us.sentry.io/4509021222141952",
// Set tracesSampleRate to 1.0 to capture 100% of spans for tracing.
// Learn more at
// https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate
tracesSampleRate: 1.0
}),
appRouter
);