返回 DeepSeek-Reasonix
auth.ts
根目录 / workers / accounts / src / http / auth.ts
1 import type { Context, MiddlewareHandler } from "hono";
2 import type { AppEnv } from "../env";
3 import type { AccountUser } from "../types";
4 import { toAccountUser } from "../types";
5 import { repos } from "../db";
6 import { readSessionToken } from "../auth/cookies";
7 import { ApiError } from "./errors";
8
9 // Non-browser clients (CLI/desktop) and cross-service callers carry the session
10 // in an Authorization header instead of the cookie.
11 export function readBearerToken(c: Context<AppEnv>): string | undefined {
12 const header = c.req.header("authorization");
13 if (!header) return undefined;
14 const token = /^Bearer\s+(.+)$/i.exec(header.trim())?.[1]?.trim();
15 return token || undefined;
16 }
17
18 // Resolves the session (cookie or Bearer token, if any) and stashes the user on
19 // the context. Runs for every request; never rejects.
20 export const loadUser: MiddlewareHandler<AppEnv> = async (c, next) => {
21 const token = readSessionToken(c) ?? readBearerToken(c);
22 let user: AccountUser | null = null;
23 if (token) {
24 const row = await repos(c.env).sessions.resolve(token);
25 if (row) user = toAccountUser(row);
26 }
27 c.set("user", user);
28 await next();
29 };
30
31 // Gate for protected routes. Pairs with currentUser() in handlers.
32 export const requireAuth: MiddlewareHandler<AppEnv> = async (c, next) => {
33 if (!c.get("user")) throw new ApiError(401, "unauthorized", "Sign in to continue.");
34 await next();
35 };
36
37 export function currentUser(c: Context<AppEnv>): AccountUser {
38 const user = c.get("user");
39 if (!user) throw new ApiError(401, "unauthorized", "Sign in to continue.");
40 return user;
41 }
42
42 lines TYPESCRIPT