Files

66 lines
2.0 KiB
TypeScript

import type { CreateExpressContextOptions } from "@trpc/server/adapters/express";
import type { User } from "../../drizzle/schema";
import { sdk } from "./sdk";
import { parse as parseCookieHeader } from "cookie";
import { verifyLocalToken, getLocalUserById, LOCAL_AUTH_COOKIE } from "../localAuth";
export type TrpcContext = {
req: CreateExpressContextOptions["req"];
res: CreateExpressContextOptions["res"];
user: User | null;
};
export async function createContext(
opts: CreateExpressContextOptions
): Promise<TrpcContext> {
let user: User | null = null;
// 1. Essayer l'authentification Manus OAuth
try {
user = await sdk.authenticateRequest(opts.req);
} catch {
user = null;
}
// 2. Si pas d'utilisateur OAuth, essayer le cookie d'auth locale
if (!user) {
try {
const cookieHeader = opts.req.headers.cookie;
if (cookieHeader) {
const cookies = parseCookieHeader(cookieHeader);
const localToken = cookies[LOCAL_AUTH_COOKIE];
if (localToken) {
const payload = await verifyLocalToken(localToken);
if (payload) {
const localUser = await getLocalUserById(payload.userId);
if (localUser && localUser.isActive) {
// Construire un objet User compatible avec le type attendu par tRPC
// On utilise un openId synthétique basé sur l'id local
user = {
id: localUser.id,
openId: `local:${localUser.id}`,
name: localUser.name,
email: localUser.email ?? null,
loginMethod: "local",
role: localUser.role === "admin" ? "admin" : "user",
createdAt: localUser.createdAt,
updatedAt: localUser.updatedAt,
lastSignedIn: localUser.lastSignedIn ?? new Date(),
} as User;
}
}
}
}
} catch (error) {
// Auth locale optionnelle — on ignore les erreurs
user = null;
}
}
return {
req: opts.req,
res: opts.res,
user,
};
}