146 lines
4.0 KiB
JavaScript
146 lines
4.0 KiB
JavaScript
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;
|