import passport from "passport"; import { Strategy as GitHubStrategy } from "passport-github2"; import { getClient } from "../utils/database.js"; import jwt from "jsonwebtoken"; export async function login(req, res) { passport.authenticate("github", { scope: ["user:email"] })(req, res); } export async function callback(req, res, next) { passport.authenticate("github", { failureRedirect: "https://localhost/login?error=oauth_failed" }, async (err, user) => { if (err) { console.error("OAuth error:", err); return res.redirect("https://localhost/login?error=oauth_error"); } if (!user) { return res.redirect("https://localhost/login?error=oauth_cancelled"); } try { // Extract user information from GitHub profile const githubId = user.id; const username = user.username || user.login; const email = user.emails[0].value || null; const avatarUrl = user.photos && user.photos[0] ? user.photos[0].value : null; const displayName = user.displayName || username; console.log(user); console.log("GitHub user info:", { githubId, username, email, displayName, avatarUrl }); const client = await getClient(); // Check if user already exists by GitHub ID let existingUserQuery = `SELECT * FROM users WHERE github_id = $1`; let existingUserResult = await client.query(existingUserQuery, [githubId]); let dbUser; if (existingUserResult.rows.length > 0) { // User exists, update their information dbUser = existingUserResult.rows[0]; const updateQuery = `UPDATE users SET username = $1, email = $2, picture = $3, is_verified = true, updated_at = NOW() WHERE github_id = $4 RETURNING id, username, email, picture`; const updateResult = await client.query(updateQuery, [ username, email, avatarUrl || "/api/media/profile/default.png", githubId ]); dbUser = updateResult.rows[0]; } else { // Check if username already exists const usernameCheck = await client.query(`SELECT id FROM users WHERE username = $1`, [username]); let finalUsername = username; if (usernameCheck.rows.length > 0) { // Username exists, append GitHub ID to make it unique finalUsername = `${username}_gh${githubId}`; } // Create new user const insertQuery = `INSERT INTO users ( username, email, picture, github_id, password, is_verified ) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, username, email, picture`; const insertResult = await client.query(insertQuery, [ finalUsername, email, avatarUrl || "/api/media/profile/default.png", githubId, null, // No password for OAuth users true // OAuth users are automatically verified ]); dbUser = insertResult.rows[0]; // Create default playlist for new user const playlistQuery = `INSERT INTO playlists (name, owner) VALUES ('A regarder plus tard', $1)`; await client.query(playlistQuery, [dbUser.id]); } client.release(); // Generate JWT token const payload = { id: dbUser.id, username: dbUser.username, }; const token = jwt.sign(payload, process.env.JWT_SECRET); // Redirect to frontend with token and user info const userData = encodeURIComponent(JSON.stringify({ id: dbUser.id, username: dbUser.username, email: dbUser.email, picture: dbUser.picture })); res.redirect(`https://localhost/login/success?token=${token}&user=${userData}`); } catch (error) { console.error("Error processing GitHub OAuth callback:", error); res.redirect("https://localhost/login?error=processing_error"); } })(req, res, next); } export async function getUserInfo(req, res) { try { // This endpoint can be used to get current user info from token const token = req.headers.authorization?.split(" ")[1]; if (!token) { return res.status(401).json({ error: "No token provided" }); } const decoded = jwt.verify(token, process.env.JWT_SECRET); const client = await getClient(); const query = `SELECT id, username, email, picture, github_id, is_verified FROM users WHERE id = $1`; const result = await client.query(query, [decoded.id]); if (!result.rows[0]) { client.release(); return res.status(404).json({ error: "User not found" }); } client.release(); res.status(200).json({ user: result.rows[0] }); } catch (error) { console.error("Error getting user info:", error); res.status(500).json({ error: "Internal server error" }); } }