Checkpoint: Fix critique : context.ts vérifie maintenant le cookie veille_local_auth pour les utilisateurs locaux, évitant la déconnexion lors des appels tRPC protégés (import, settings, users)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"version": "cf6f7264",
|
"version": "39f91ba6",
|
||||||
"timestamp": 1776767388974
|
"timestamp": 1776769592209
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { CreateExpressContextOptions } from "@trpc/server/adapters/express";
|
import type { CreateExpressContextOptions } from "@trpc/server/adapters/express";
|
||||||
import type { User } from "../../drizzle/schema";
|
import type { User } from "../../drizzle/schema";
|
||||||
import { sdk } from "./sdk";
|
import { sdk } from "./sdk";
|
||||||
|
import { parse as parseCookieHeader } from "cookie";
|
||||||
|
import { verifyLocalToken, getLocalUserById, LOCAL_AUTH_COOKIE } from "../localAuth";
|
||||||
|
|
||||||
export type TrpcContext = {
|
export type TrpcContext = {
|
||||||
req: CreateExpressContextOptions["req"];
|
req: CreateExpressContextOptions["req"];
|
||||||
@@ -13,13 +15,48 @@ export async function createContext(
|
|||||||
): Promise<TrpcContext> {
|
): Promise<TrpcContext> {
|
||||||
let user: User | null = null;
|
let user: User | null = null;
|
||||||
|
|
||||||
|
// 1. Essayer l'authentification Manus OAuth
|
||||||
try {
|
try {
|
||||||
user = await sdk.authenticateRequest(opts.req);
|
user = await sdk.authenticateRequest(opts.req);
|
||||||
} catch (error) {
|
} catch {
|
||||||
// Authentication is optional for public procedures.
|
|
||||||
user = null;
|
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 {
|
return {
|
||||||
req: opts.req,
|
req: opts.req,
|
||||||
res: opts.res,
|
res: opts.res,
|
||||||
|
|||||||
3
todo.md
3
todo.md
@@ -61,3 +61,6 @@
|
|||||||
- [x] Frontend : page Gestion utilisateurs affiche et permet de saisir le username
|
- [x] Frontend : page Gestion utilisateurs affiche et permet de saisir le username
|
||||||
- [x] Mettre à jour le compte adminItinova avec username = adminItinova
|
- [x] Mettre à jour le compte adminItinova avec username = adminItinova
|
||||||
- [x] Migration BDD recette : ajouter colonne username dans local_users et recréer compte 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
|
||||||
|
|||||||
Reference in New Issue
Block a user