import { createMiddleware } from "hono/factory";
import { getCookie } from "hono/cookie";
import { eq, gt } from "drizzle-orm";
import { db } from "../db";
import { sessions, users } from "../db/schema";
import type { User } from "../db/schema";
import { sessionCache } from "../lib/cache";
export type AuthEnv = {
Variables: {
user: User | null;
};
};
export const softAuth = createMiddleware<AuthEnv>(async (c, next) => {
const token = getCookie(c, "session");
if (!token) {
c.set("user", null);
return next();
}
const cachedUser = sessionCache.get(token) as User | null | undefined;
if (cachedUser !== undefined) {
c.set("user", cachedUser);
return next();
}
try {
const [session] = await db
.select()
.from(sessions)
.where(eq(sessions.token, token))
.limit(1);
if (!session || new Date(session.expiresAt) < new Date()) {
sessionCache.set(token, null as any);
c.set("user", null);
return next();
}
const [user] = await db
.select()
.from(users)
.where(eq(users.id, session.userId))
.limit(1);
sessionCache.set(token, (user || null) as any);
c.set("user", user || null);
} catch {
c.set("user", null);
}
return next();
});
export const requireAuth = createMiddleware<AuthEnv>(async (c, next) => {
const token = getCookie(c, "session");
if (!token) {
return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
}
try {
const [session] = await db
.select()
.from(sessions)
.where(eq(sessions.token, token))
.limit(1);
if (!session || new Date(session.expiresAt) < new Date()) {
return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
}
const [user] = await db
.select()
.from(users)
.where(eq(users.id, session.userId))
.limit(1);
if (!user) {
return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
}
c.set("user", user);
} catch {
return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
}
return next();
});
|