Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

auth.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

auth.tsBlame91 lines · 1 contributor
06d5ffeClaude1/**
2 * Auth middleware — reads session cookie, injects user into context.
3 */
4
5import { createMiddleware } from "hono/factory";
6import { getCookie } from "hono/cookie";
7import { eq, gt } from "drizzle-orm";
8import { db } from "../db";
9import { sessions, users } from "../db/schema";
10import type { User } from "../db/schema";
11
12export type AuthEnv = {
13 Variables: {
14 user: User | null;
15 };
16};
17
18/**
19 * Soft auth — sets c.get("user") to the current user or null.
20 * Does NOT block unauthenticated requests.
21 */
22export const softAuth = createMiddleware<AuthEnv>(async (c, next) => {
23 const token = getCookie(c, "session");
24 if (!token) {
25 c.set("user", null);
26 return next();
27 }
28
29 try {
30 const [session] = await db
31 .select()
32 .from(sessions)
33 .where(eq(sessions.token, token))
34 .limit(1);
35
36 if (!session || new Date(session.expiresAt) < new Date()) {
37 c.set("user", null);
38 return next();
39 }
40
41 const [user] = await db
42 .select()
43 .from(users)
44 .where(eq(users.id, session.userId))
45 .limit(1);
46
47 c.set("user", user || null);
48 } catch {
49 c.set("user", null);
50 }
51
52 return next();
53});
54
55/**
56 * Hard auth — redirects to /login if not authenticated.
57 */
58export const requireAuth = createMiddleware<AuthEnv>(async (c, next) => {
59 const token = getCookie(c, "session");
60 if (!token) {
61 return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
62 }
63
64 try {
65 const [session] = await db
66 .select()
67 .from(sessions)
68 .where(eq(sessions.token, token))
69 .limit(1);
70
71 if (!session || new Date(session.expiresAt) < new Date()) {
72 return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
73 }
74
75 const [user] = await db
76 .select()
77 .from(users)
78 .where(eq(users.id, session.userId))
79 .limit(1);
80
81 if (!user) {
82 return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
83 }
84
85 c.set("user", user);
86 } catch {
87 return c.redirect(`/login?redirect=${encodeURIComponent(c.req.path)}`);
88 }
89
90 return next();
91});