const express = require("express"); const router = express.Router(); const jwt = require("jsonwebtoken"); const { User } = require("../models"); // Temporary in-memory storage for verification codes // In production, use Redis or a database const verificationCodes = new Map(); // Generate random 6-digit code const generateVerificationCode = () => { return Math.floor(100000 + Math.random() * 900000).toString(); }; // Send verification code router.post("/send-code", async (req, res) => { try { const { phoneNumber } = req.body; if (!phoneNumber) { return res.status(400).json({ message: "Phone number is required" }); } // Generate and store verification code const code = generateVerificationCode(); verificationCodes.set(phoneNumber, { code, createdAt: Date.now(), attempts: 0, }); // TODO: Integrate with SMS service (Twilio, AWS SNS, etc.) // For development, log the code console.log(`Verification code for ${phoneNumber}: ${code}`); res.json({ message: "Verification code sent", // Remove this in production - only for development devCode: code, }); } catch (error) { console.error("Error sending verification code:", error); res.status(500).json({ message: "Failed to send verification code" }); } }); // Verify code and create/login user router.post("/verify-code", async (req, res) => { try { const { phoneNumber, code, firstName, lastName } = req.body; if (!phoneNumber || !code) { return res .status(400) .json({ message: "Phone number and code are required" }); } // Check verification code const storedData = verificationCodes.get(phoneNumber); if (!storedData) { return res.status(400).json({ message: "No verification code found. Please request a new one.", }); } // Check if code expired (10 minutes) if (Date.now() - storedData.createdAt > 10 * 60 * 1000) { verificationCodes.delete(phoneNumber); return res.status(400).json({ message: "Verification code expired. Please request a new one.", }); } // Check attempts if (storedData.attempts >= 3) { verificationCodes.delete(phoneNumber); return res.status(400).json({ message: "Too many failed attempts. Please request a new code.", }); } if (storedData.code !== code) { storedData.attempts++; return res.status(400).json({ message: "Invalid verification code" }); } // Code is valid, remove it verificationCodes.delete(phoneNumber); // Find or create user let user = await User.findOne({ where: { phone: phoneNumber } }); if (!user) { // New user - require firstName and lastName if (!firstName || !lastName) { return res.status(400).json({ message: "First name and last name are required for new users", isNewUser: true, }); } user = await User.create({ phone: phoneNumber, phoneVerified: true, firstName, lastName, authProvider: "phone", // Generate a unique username from phone username: `user_${phoneNumber .replace(/\D/g, "") .slice(-6)}_${Date.now().toString(36)}`, }); } else { // Existing user - update phone verification await user.update({ phoneVerified: true }); } // Generate JWT token const token = jwt.sign( { id: user.id, phone: user.phone }, process.env.JWT_SECRET, { expiresIn: "7d" } ); res.json({ message: "Phone verified successfully", token, user: { id: user.id, username: user.username, firstName: user.firstName, lastName: user.lastName, phone: user.phone, email: user.email, phoneVerified: user.phoneVerified, }, }); } catch (error) { console.error("Error verifying code:", error); res.status(500).json({ message: "Failed to verify code" }); } }); module.exports = router;