diff --git a/.replit b/.replit index 7b00032..518307b 100644 --- a/.replit +++ b/.replit @@ -18,6 +18,10 @@ externalPort = 80 localPort = 35357 externalPort = 3002 +[[ports]] +localPort = 37659 +externalPort = 4200 + [[ports]] localPort = 40537 externalPort = 3000 diff --git a/client/src/pages/pages.tsx b/client/src/pages/pages.tsx index 792e6f6..ebe9e2d 100644 --- a/client/src/pages/pages.tsx +++ b/client/src/pages/pages.tsx @@ -1,6 +1,6 @@ import { useState } from "react"; import { useQuery, useMutation } from "@tanstack/react-query"; -import { Plus, Facebook, Instagram, Trash2, RefreshCw, Edit } from "lucide-react"; +import { Plus, Facebook, Instagram, Trash2, RefreshCw, Edit, Bug, Code } from "lucide-react"; import Sidebar from "@/components/sidebar"; import TopBar from "@/components/topbar"; import { Button } from "@/components/ui/button"; @@ -73,6 +73,25 @@ export default function PagesManagement() { !open && setEditingPage(null)} /> +
+ + +
+ {isLoading ? (
{[1, 2, 3].map((i) => ( diff --git a/replit.md b/replit.md index 50e51ee..80479af 100644 --- a/replit.md +++ b/replit.md @@ -37,6 +37,9 @@ Preferred communication style: Simple, everyday language. - sameSite: 'lax' pour prévention CSRF - Durée de session: 7 jours - Secret de session via variable d'environnement `SESSION_SECRET` +- Store de session: + - **Production**: PostgreSQL via connect-pg-simple (table `session` auto-créée) + - **Développement**: MemoryStore (par défaut) **Protection des routes**: - Backend: Middleware `requireAuth` pour routes utilisateur, `requireAdmin` pour routes admin @@ -94,7 +97,9 @@ Preferred communication style: Simple, everyday language. - Scheduler service running every minute to check for pending posts - Automated post publication to social media platforms -**Session Management**: Stateless authentication with session cookies (connect-pg-simple for PostgreSQL session store) +**Session Management**: +- Développement: MemoryStore (sessions en mémoire) +- Production: connect-pg-simple (sessions persistées dans PostgreSQL, table `session`) **Key Architectural Patterns**: - Service layer pattern (OpenRouterService, CloudinaryService, SchedulerService) diff --git a/server/index.ts b/server/index.ts index 0b1ff63..bf61ba0 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1,5 +1,7 @@ import express, { type Request, Response, NextFunction } from "express"; import session from "express-session"; +import connectPgSimple from "connect-pg-simple"; +import pg from "pg"; import passport from "./auth"; import { registerRoutes } from "./routes"; import { setupVite, serveStatic, log } from "./vite"; @@ -7,6 +9,7 @@ import { schedulerService } from "./services/scheduler"; import { ensureAdminUserExists } from "./init-admin"; const app = express(); +const PgSession = connectPgSimple(session); declare module 'http' { interface IncomingMessage { @@ -28,7 +31,19 @@ if (!process.env.SESSION_SECRET) { // Déterminer si on utilise HTTPS basé sur APP_URL const isHttps = process.env.APP_URL?.startsWith('https://') || false; +// Configuration du store de session pour production +const sessionStore = process.env.NODE_ENV === 'production' && process.env.DATABASE_URL + ? new PgSession({ + pool: new pg.Pool({ + connectionString: process.env.DATABASE_URL, + }), + tableName: 'session', + createTableIfMissing: true, + }) + : undefined; // MemoryStore par défaut en dev + app.use(session({ + store: sessionStore, secret: process.env.SESSION_SECRET || 'your-secret-key-change-me', resave: false, saveUninitialized: false,