refactor: use better-auth api for session validation in server middleware and websocket
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
import type { Context, Next } from "hono";
|
||||
import { db } from "../db.js";
|
||||
import { session as sessionTable, user as userTable } from "../schema.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { getCookie } from "hono/cookie";
|
||||
import { auth } from "../auth.js";
|
||||
|
||||
/** Hono Env type for routes protected by sessionMiddleware */
|
||||
export type AuthEnv = {
|
||||
@@ -13,43 +10,13 @@ export type AuthEnv = {
|
||||
};
|
||||
|
||||
export async function sessionMiddleware(c: Context, next: Next) {
|
||||
// Extract session token from cookie (same approach as dashboard WS auth)
|
||||
const rawCookie = getCookie(c, "better-auth.session_token");
|
||||
if (!rawCookie) {
|
||||
const session = await auth.api.getSession({ headers: c.req.raw.headers });
|
||||
|
||||
if (!session) {
|
||||
return c.json({ error: "unauthorized" }, 401);
|
||||
}
|
||||
|
||||
// Token may have a signature appended after a dot — use only the token part
|
||||
const token = rawCookie.split(".")[0];
|
||||
|
||||
// Direct DB lookup (proven to work, unlike auth.api.getSession)
|
||||
const rows = await db
|
||||
.select({
|
||||
sessionId: sessionTable.id,
|
||||
userId: sessionTable.userId,
|
||||
})
|
||||
.from(sessionTable)
|
||||
.where(eq(sessionTable.token, token))
|
||||
.limit(1);
|
||||
|
||||
if (rows.length === 0) {
|
||||
return c.json({ error: "unauthorized" }, 401);
|
||||
}
|
||||
|
||||
const { sessionId, userId } = rows[0];
|
||||
|
||||
// Fetch user info
|
||||
const users = await db
|
||||
.select({ id: userTable.id, name: userTable.name, email: userTable.email })
|
||||
.from(userTable)
|
||||
.where(eq(userTable.id, userId))
|
||||
.limit(1);
|
||||
|
||||
if (users.length === 0) {
|
||||
return c.json({ error: "unauthorized" }, 401);
|
||||
}
|
||||
|
||||
c.set("user", users[0]);
|
||||
c.set("session", { id: sessionId, userId });
|
||||
c.set("user", session.user);
|
||||
c.set("session", session.session);
|
||||
await next();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { ServerWebSocket } from "bun";
|
||||
import { db } from "../db.js";
|
||||
import { session as sessionTable } from "../schema.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { auth } from "../auth.js";
|
||||
import { sessions, type WebSocketData } from "./sessions.js";
|
||||
|
||||
interface DashboardAuthMessage {
|
||||
@@ -36,19 +34,17 @@ export async function handleDashboardMessage(
|
||||
return;
|
||||
}
|
||||
|
||||
// Look up session directly in DB
|
||||
const rows = await db
|
||||
.select({ userId: sessionTable.userId })
|
||||
.from(sessionTable)
|
||||
.where(eq(sessionTable.token, token))
|
||||
.limit(1);
|
||||
// Validate session via better-auth
|
||||
const session = await auth.api.getSession({
|
||||
headers: new Headers({ cookie: `better-auth.session_token=${token}` }),
|
||||
});
|
||||
|
||||
if (rows.length === 0) {
|
||||
if (!session) {
|
||||
ws.send(JSON.stringify({ type: "auth_error", message: "Invalid session" }));
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = rows[0].userId;
|
||||
const userId = session.user.id;
|
||||
|
||||
// Mark connection as authenticated
|
||||
ws.data.authenticated = true;
|
||||
|
||||
Reference in New Issue
Block a user