import { Request, Response } from 'express'; import { pool } from '../db/connection'; import { hashPassword, comparePassword, generateToken, generateRandomToken } from '../utils/auth'; export const signup = async (req: Request, res: Response) => { try { const { email, password, first_name, last_name } = req.body; if (!email || !password) { return res.status(400).json({ success: false, message: 'Email and password are required' }); } const existingUser = await pool.query('SELECT id FROM users WHERE email = $1', [email]); if (existingUser.rows.length > 0) { return res.status(409).json({ success: false, message: 'User already exists with this email' }); } const passwordHash = await hashPassword(password); const verificationToken = generateRandomToken(); const result = await pool.query( `INSERT INTO users (email, password_hash, first_name, last_name, verification_token, is_verified) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, email, first_name, last_name, role, subscription_plan, subscription_status, created_at`, [email, passwordHash, first_name, last_name, verificationToken, false] ); const user = result.rows[0]; const token = generateToken({ userId: user.id, email: user.email, role: user.role, subscription_plan: user.subscription_plan }); res.status(201).json({ success: true, token, user: { id: user.id, email: user.email, first_name: user.first_name, last_name: user.last_name, role: user.role, subscription_plan: user.subscription_plan, subscription_status: user.subscription_status, is_verified: false, created_at: user.created_at, updated_at: user.created_at } }); } catch (error) { console.error('Signup error:', error); res.status(500).json({ success: false, message: 'Internal server error' }); } }; export const login = async (req: Request, res: Response) => { try { const { email, password } = req.body; if (!email || !password) { return res.status(400).json({ success: false, message: 'Email and password are required' }); } const result = await pool.query( 'SELECT id, email, password_hash, first_name, last_name, is_verified, role, subscription_plan, subscription_status, created_at, updated_at FROM users WHERE email = $1', [email] ); if (result.rows.length === 0) { return res.status(401).json({ success: false, message: 'Invalid credentials' }); } const user = result.rows[0]; const isValidPassword = await comparePassword(password, user.password_hash); if (!isValidPassword) { return res.status(401).json({ success: false, message: 'Invalid credentials' }); } const token = generateToken({ userId: user.id, email: user.email, role: user.role, subscription_plan: user.subscription_plan }); res.json({ success: true, token, user: { id: user.id, email: user.email, first_name: user.first_name, last_name: user.last_name, is_verified: user.is_verified, role: user.role, subscription_plan: user.subscription_plan, subscription_status: user.subscription_status, created_at: user.created_at, updated_at: user.updated_at } }); } catch (error) { console.error('Login error:', error); res.status(500).json({ success: false, message: 'Internal server error' }); } }; export const resetPassword = async (req: Request, res: Response) => { try { const { email } = req.body; if (!email) { return res.status(400).json({ success: false, message: 'Email is required' }); } const user = await pool.query('SELECT id FROM users WHERE email = $1', [email]); if (user.rows.length === 0) { return res.json({ success: true, message: 'If the email exists, a reset link has been sent' }); } const resetToken = generateRandomToken(); const resetExpires = new Date(Date.now() + 3600000); // 1 hour await pool.query( 'UPDATE users SET reset_password_token = $1, reset_password_expires = $2 WHERE email = $3', [resetToken, resetExpires, email] ); // TODO: Send email with reset link console.log(`Reset token for ${email}: ${resetToken}`); res.json({ success: true, message: 'If the email exists, a reset link has been sent' }); } catch (error) { console.error('Reset password error:', error); res.status(500).json({ success: false, message: 'Internal server error' }); } };