import express from "express"; import bcrypt from "bcrypt"; import jwt from "jsonwebtoken"; import passport from "passport"; import session from "express-session"; import { Strategy as GoogleStrategy } from "passport-google-oauth20"; import { Strategy as FacebookStrategy } from "passport-facebook"; import dotenv from "dotenv"; import { pool } from "../db.js"; dotenv.config(); const router = express.Router(); /* -------------------- SESSIONS -------------------- */ router.use( session({ secret: process.env.SESSION_SECRET || "secret_key", resave: false, saveUninitialized: true, }) ); router.use(passport.initialize()); router.use(passport.session()); passport.serializeUser((user, done) => done(null, user)); passport.deserializeUser((user, done) => done(null, user)); /* -------------------- GOOGLE STRATEGY -------------------- */ passport.use( new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: "/api/auth/google/callback", }, async (accessToken, refreshToken, profile, done) => { try { const email = profile.emails?.[0]?.value; if (!email) return done(null, false); // Vérifie si l’utilisateur existe déjà let result = await pool.query("SELECT * FROM users WHERE email=$1", [email]); if (!result.rows.length) { // Crée un nouvel utilisateur await pool.query("INSERT INTO users(email, password) VALUES($1,$2)", [ email, null, ]); result = await pool.query("SELECT * FROM users WHERE email=$1", [email]); } return done(null, result.rows[0]); } catch (err) { console.error("Erreur Google auth:", err); return done(err, null); } } ) ); /* -------------------- FACEBOOK STRATEGY -------------------- */ passport.use( new FacebookStrategy( { clientID: process.env.FACEBOOK_APP_ID, clientSecret: process.env.FACEBOOK_APP_SECRET, callbackURL: "/api/auth/facebook/callback", profileFields: ["id", "displayName", "emails"], }, async (accessToken, refreshToken, profile, done) => { try { const email = profile.emails?.[0]?.value; if (!email) return done(null, false); let result = await pool.query("SELECT * FROM users WHERE email=$1", [email]); if (!result.rows.length) { await pool.query("INSERT INTO users(email, password) VALUES($1,$2)", [ email, null, ]); result = await pool.query("SELECT * FROM users WHERE email=$1", [email]); } return done(null, result.rows[0]); } catch (err) { console.error("Erreur Facebook auth:", err); return done(err, null); } } ) ); /* -------------------- ROUTES CLASSIQUES -------------------- */ // Inscription manuelle router.post("/register", async (req, res) => { const { email, password } = req.body; if (!email || !password) return res.status(400).json({ message: "Champs requis" }); const hashed = await bcrypt.hash(password, 10); try { await pool.query("INSERT INTO users(email, password) VALUES($1,$2)", [ email, hashed, ]); res.status(201).json({ message: "Utilisateur créé" }); } catch (e) { res.status(400).json({ error: "Email déjà utilisé" }); } }); // Connexion manuelle router.post("/login", async (req, res) => { const { email, password } = req.body; const result = await pool.query("SELECT * FROM users WHERE email=$1", [email]); if (!result.rows.length) return res.status(400).json({ message: "Utilisateur introuvable" }); const match = await bcrypt.compare(password, result.rows[0].password); if (!match) return res.status(401).json({ message: "Mot de passe incorrect" }); const token = jwt.sign( { id: result.rows[0].id, email }, process.env.JWT_SECRET, { expiresIn: "2h" } ); res.json({ token }); }); /* -------------------- ROUTES GOOGLE -------------------- */ router.get("/google", passport.authenticate("google", { scope: ["email", "profile"] })); router.get( "/google/callback", passport.authenticate("google", { failureRedirect: "/login" }), (req, res) => { const token = jwt.sign({ email: req.user.email }, process.env.JWT_SECRET, { expiresIn: "2h", }); res.json({ message: "Connexion via Google réussie", token }); } ); /* -------------------- ROUTES FACEBOOK -------------------- */ router.get("/facebook", passport.authenticate("facebook", { scope: ["email"] })); router.get( "/facebook/callback", passport.authenticate("facebook", { failureRedirect: "/login" }), (req, res) => { const token = jwt.sign({ email: req.user.email }, process.env.JWT_SECRET, { expiresIn: "2h", }); res.json({ message: "Connexion via Facebook réussie", token }); } ); export default router;