diff --git a/client/public/__manus__/version.json b/client/public/__manus__/version.json index 3eead99..b9d6c41 100644 --- a/client/public/__manus__/version.json +++ b/client/public/__manus__/version.json @@ -1,4 +1,4 @@ { - "version": "cf6f7264", - "timestamp": 1776767388974 + "version": "39f91ba6", + "timestamp": 1776769592209 } \ No newline at end of file diff --git a/server/_core/context.ts b/server/_core/context.ts index e4ae108..5fce18f 100644 --- a/server/_core/context.ts +++ b/server/_core/context.ts @@ -1,6 +1,8 @@ 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"]; @@ -13,13 +15,48 @@ export async function createContext( ): Promise { let user: User | null = null; + // 1. Essayer l'authentification Manus OAuth try { user = await sdk.authenticateRequest(opts.req); - } catch (error) { - // Authentication is optional for public procedures. + } 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, diff --git a/todo.md b/todo.md index e10c51e..26de0a9 100644 --- a/todo.md +++ b/todo.md @@ -61,3 +61,6 @@ - [x] Frontend : page Gestion utilisateurs affiche et permet de saisir le username - [x] Mettre à jour le compte adminItinova avec username = adminItinova - [x] Migration BDD recette : ajouter colonne username dans local_users et recréer compte adminItinova + +## Bugs recette +- [ ] BUG: Déconnexion lors de l'import Excel sur le VPS — la session expire et redirige vers /login pendant l'upload