fb / artifacts /api-server /src /lib /auth.ts
sare26's picture
Upload 21 files
ccc21f3 verified
Raw
History Blame Contribute Delete
1.32 kB
import type { Request, Response, NextFunction } from "express";
import { getAuth, clerkClient } from "@clerk/express";
export interface AuthedRequest extends Request {
userId: string;
userEmail: string | null;
}
const emailCache = new Map<string, { email: string | null; ts: number }>();
const CACHE_TTL_MS = 15 * 60 * 1000;
export async function requireAuth(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
const auth = getAuth(req);
const claimUserId =
typeof auth?.sessionClaims?.["userId"] === "string"
? (auth.sessionClaims["userId"] as string)
: null;
const userId: string | null = claimUserId ?? auth?.userId ?? null;
if (!userId) {
res.status(401).json({ error: "Unauthorized" });
return;
}
let email: string | null = null;
const cached = emailCache.get(userId);
if (cached && Date.now() - cached.ts < CACHE_TTL_MS) {
email = cached.email;
} else {
try {
const user = await clerkClient.users.getUser(userId);
email = user.primaryEmailAddress?.emailAddress ?? null;
} catch (err) {
req.log.warn({ err }, "Failed to fetch user from Clerk");
}
emailCache.set(userId, { email, ts: Date.now() });
}
(req as AuthedRequest).userId = userId;
(req as AuthedRequest).userEmail = email;
next();
}