This commit is contained in:
Manus Sandbox
2025-11-19 08:34:55 -05:00
parent 4d2ed3d5d8
commit 1313a45879
10 changed files with 11 additions and 962 deletions

View File

@@ -1,9 +1,8 @@
import type { CreateExpressContextOptions } from "@trpc/server/adapters/express";
import type { User } from "../../drizzle/schema";
import { verifyToken } from "./auth";
import { getUserById, getUserByOpenId } from "../db";
import { getUserById } from "../db";
import { COOKIE_NAME } from "@shared/const";
import { sdk } from "./sdk";
export type TrpcContext = {
req: CreateExpressContextOptions["req"];
@@ -29,18 +28,12 @@ export async function createContext(
}
if (token) {
// Essayer d'abord l'authentification locale (JWT avec userId)
try {
const decoded = verifyToken(token);
if (decoded && decoded.userId) {
user = await getUserById(decoded.userId) || null;
}
} catch (localAuthError) {
// Si l'authentification locale échoue, essayer OAuth
const session = await sdk.verifySession(token);
if (session && session.openId) {
user = await getUserByOpenId(session.openId) || null;
}
// Vérifier et décoder le token
const decoded = verifyToken(token);
if (decoded) {
// Récupérer l'utilisateur depuis la base de données
user = await getUserById(decoded.userId) || null;
}
}
} catch (error) {

View File

@@ -44,20 +44,7 @@ export function registerOAuthRoutes(app: Express) {
const cookieOptions = getSessionCookieOptions(req);
res.cookie(COOKIE_NAME, sessionToken, { ...cookieOptions, maxAge: ONE_YEAR_MS });
// Décoder le state pour obtenir l'URL de redirection
let redirectUrl = "/";
try {
redirectUrl = Buffer.from(state, 'base64').toString('utf-8');
// Si c'est une URL complète, extraire seulement le path
if (redirectUrl.startsWith('http')) {
const url = new URL(redirectUrl);
redirectUrl = url.pathname;
}
} catch (error) {
console.warn("[OAuth] Failed to decode state, redirecting to /", error);
}
res.redirect(302, redirectUrl);
res.redirect(302, "/");
} catch (error) {
console.error("[OAuth] Callback failed", error);
res.status(500).json({ error: "OAuth callback failed" });

View File

@@ -95,86 +95,6 @@ export async function getUserById(id: number) {
return result.length > 0 ? result[0] : undefined;
}
/**
* Récupère un utilisateur par son openId (OAuth)
*/
export async function getUserByOpenId(openId: string) {
const db = await getDb();
if (!db) {
console.warn("[Database] Cannot get user: database not available");
return undefined;
}
const result = await db.select().from(users).where(eq(users.openId, openId)).limit(1);
return result.length > 0 ? result[0] : undefined;
}
/**
* Crée ou met à jour un utilisateur OAuth
*/
export async function upsertUser(user: InsertUser): Promise<void> {
if (!user.openId && !user.email) {
throw new Error("User openId or email is required for upsert");
}
const db = await getDb();
if (!db) {
console.warn("[Database] Cannot upsert user: database not available");
return;
}
try {
const values: InsertUser = {
openId: user.openId,
email: user.email || '',
};
const updateSet: Record<string, unknown> = {};
const textFields = ["name", "email"] as const;
type TextField = (typeof textFields)[number];
const assignNullable = (field: TextField) => {
const value = user[field];
if (value === undefined) return;
const normalized = value ?? null;
values[field] = normalized;
updateSet[field] = normalized;
};
textFields.forEach(assignNullable);
if (user.lastSignedIn !== undefined) {
values.lastSignedIn = user.lastSignedIn;
updateSet.lastSignedIn = user.lastSignedIn;
}
if (user.role !== undefined) {
values.role = user.role;
updateSet.role = user.role;
} else if (user.openId === ENV.ownerOpenId) {
values.role = 'admin';
updateSet.role = 'admin';
}
if (!values.lastSignedIn) {
values.lastSignedIn = new Date();
}
if (Object.keys(updateSet).length === 0) {
updateSet.lastSignedIn = new Date();
}
// Utiliser openId comme clé unique pour OAuth
if (user.openId) {
await db.insert(users).values(values).onDuplicateKeyUpdate({
set: updateSet,
});
}
} catch (error) {
console.error("[Database] Failed to upsert user:", error);
throw error;
}
}
/**
* Met à jour le dernier login d'un utilisateur
*/