const jwt = require('jsonwebtoken'); // Langkah 3-5 OAuth2: tukar code dengan access token, ambil profil, terbitkan JWT sendiri. module.exports = async function handler(req, res) { const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, JWT_SECRET } = process.env; if (!GITHUB_CLIENT_ID || !GITHUB_CLIENT_SECRET || !JWT_SECRET) { res.status(500).json({ error: 'GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET / JWT_SECRET belum diatur di environment' }); return; } const { code, state } = req.query; // state sekali pakai: hapus cookie apa pun hasilnya. const expectedState = req.cookies.oauth_state; res.setHeader('Set-Cookie', 'oauth_state=; HttpOnly; SameSite=Lax; Path=/; Max-Age=0'); if (!code) { res.status(400).json({ error: 'Parameter code tidak ada' }); return; } if (!state || !expectedState || state !== expectedState) { res.status(400).json({ error: 'State tidak valid, ulangi login lewat /auth/login' }); return; } try { const tokenRes = await fetch('https://github.com/login/oauth/access_token', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({ client_id: GITHUB_CLIENT_ID, client_secret: GITHUB_CLIENT_SECRET, code, }), }); const { access_token, error_description } = await tokenRes.json(); if (!access_token) { res.status(401).json({ error: error_description || 'Gagal menukar code dengan access token' }); return; } const userRes = await fetch('https://api.github.com/user', { headers: { Authorization: `Bearer ${access_token}`, Accept: 'application/json' }, }); if (!userRes.ok) { res.status(502).json({ error: 'Gagal mengambil profil dari GitHub' }); return; } const githubUser = await userRes.json(); const token = jwt.sign({ username: githubUser.login }, JWT_SECRET, { expiresIn: '1h' }); res.json({ token }); } catch (err) { console.error('[OAuth error] /auth/callback:', err); res.status(500).json({ error: 'Terjadi kesalahan pada server, silakan coba lagi' }); } };