diff --git a/controllers/application/login/loginController.js b/controllers/application/login/loginController.js index 2c2015c..a14f46e 100644 --- a/controllers/application/login/loginController.js +++ b/controllers/application/login/loginController.js @@ -1,6 +1,7 @@ const UserModel = require('../../../models/UserModel') const { check, validationResult } = require('express-validator') const { default: axios } = require('axios') +const { OTP_VALID_MS } = require('../../../utils/otpExpiry') const loginValidationRules = () => { return [ check('mobile') @@ -34,18 +35,22 @@ const loginUser = async (req, res, next) => { } const otp = generateOTP() + const otpSentAt = new Date() // eslint-disable-next-line no-unused-vars const user = await UserModel.findOneAndUpdate( { mobile }, - { $set: { mobile, otp } }, + { $set: { mobile, otp: String(otp), otpSentAt } }, { upsert: true, new: true, lean: true } ) - // زمانبندی تنظیم مقدار otp به null پس از 10 دقیقه setTimeout(() => { - UserModel.findOneAndUpdate({ mobile }, { $set: { otp: null } }, { new: true }) + UserModel.findOneAndUpdate( + { mobile }, + { $set: { otp: null, otpSentAt: null } }, + { new: true } + ) .then(() => {}) .catch(error => console.error('Error setting OTP to null:', error)) - }, 5 * 60 * 1000) + }, OTP_VALID_MS) const data = JSON.stringify({ mobile, templateId: '930719', diff --git a/controllers/application/login/verifyController.js b/controllers/application/login/verifyController.js index abff53c..1ef37aa 100644 --- a/controllers/application/login/verifyController.js +++ b/controllers/application/login/verifyController.js @@ -1,5 +1,6 @@ const UserModel = require('../../../models/UserModel') const TokenService = require('../../../services/TokenService') +const { isOtpExpired } = require('../../../utils/otpExpiry') // const jwt = require('jsonwebtoken') const verifyUser = async (req, res, next) => { @@ -20,7 +21,15 @@ const verifyUser = async (req, res, next) => { }) } const token = TokenService.sign({ id: user._id }) - if (user.otp === otp) { + + if (!user.otp || isOtpExpired(user)) { + return res.status(422).json({ + error: true, + message: 'کد تایید منقضی شده است. لطفاً دوباره درخواست ارسال کد دهید' + }) + } + + if (String(user.otp) === String(otp)) { // if (user.user_name === null) { // return res.json({ // message: 'کد تایید صحیح بود', diff --git a/controllers/application/register/registerController.js b/controllers/application/register/registerController.js index 836d82d..02af194 100644 --- a/controllers/application/register/registerController.js +++ b/controllers/application/register/registerController.js @@ -1,6 +1,7 @@ const { default: axios } = require('axios') const UserModel = require('../../../models/UserModel') const { check, validationResult } = require('express-validator') +const { OTP_VALID_MS } = require('../../../utils/otpExpiry') // const { Token, VerificationCode } = require('sms-ir') const registerValidationRules = () => { @@ -36,17 +37,22 @@ const registerUser = async (req, res, next) => { } const otp = generateOTP() + const otpSentAt = new Date() // eslint-disable-next-line no-unused-vars const user = await UserModel.findOneAndUpdate( { mobile }, - { $set: { mobile, otp } }, + { $set: { mobile, otp: String(otp), otpSentAt } }, { upsert: true, new: true, lean: true } ) setTimeout(() => { - UserModel.findOneAndUpdate({ mobile }, { $set: { otp: null } }, { new: true }) + UserModel.findOneAndUpdate( + { mobile }, + { $set: { otp: null, otpSentAt: null } }, + { new: true } + ) .then(() => {}) .catch(error => console.error('Error setting OTP to null:', error)) - }, 5 * 60 * 1000) + }, OTP_VALID_MS) const data = JSON.stringify({ mobile, templateId: '930719', diff --git a/controllers/application/register/verifyController.js b/controllers/application/register/verifyController.js index e5b8cf1..c1a2d54 100644 --- a/controllers/application/register/verifyController.js +++ b/controllers/application/register/verifyController.js @@ -1,5 +1,6 @@ const UserModel = require('../../../models/UserModel') const TokenService = require('../../../services/TokenService') +const { isOtpExpired } = require('../../../utils/otpExpiry') // const jwt = require('jsonwebtoken') const verifyUser = async (req, res, next) => { @@ -25,7 +26,14 @@ const verifyUser = async (req, res, next) => { (!user.password) { step = 'password' } else if (!user.first_name) { step = 'first_name' } else if (!user.user_type) { step = 'user_type' } else { step = 'profile_image' } - if (user.otp === otp) { + if (!user.otp || isOtpExpired(user)) { + return res.status(422).json({ + error: true, + message: 'کد تایید منقضی شده است. لطفاً دوباره درخواست ارسال کد دهید' + }) + } + + if (String(user.otp) === String(otp)) { return res.json({ message: 'کد تایید صحیح بود', token, diff --git a/controllers/application/verify/setProfileImageController.js b/controllers/application/verify/setProfileImageController.js index 7b4ac95..c32e9a9 100644 --- a/controllers/application/verify/setProfileImageController.js +++ b/controllers/application/verify/setProfileImageController.js @@ -33,7 +33,7 @@ const setProfileImage = async (req, res, next) => { } // ذخیره فایل عکس پروفایل - const uploadDir = path.join(__dirname, '../../../../storage/profiles') + const uploadDir = path.join(__dirname, '../../../storage/profiles') if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }) } @@ -78,7 +78,7 @@ const updateProfileImage = async (req, res, next) => { }) } - const uploadDir = path.join(__dirname, '../../../../storage/profiles') + const uploadDir = path.join(__dirname, '../../../storage/profiles') if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }) diff --git a/index.js b/index.js index c9096a9..dcde565 100644 --- a/index.js +++ b/index.js @@ -98,14 +98,22 @@ const io = require('socket.io')(http, { app.use(express.json({ limit: '1000mb' })); app.use(express.urlencoded({ limit: '1000mb', extended: true })); -app.use('/storage', express.static(path.join(__dirname, 'storage'))); +// مسیرهای مشخص قبل از /storage عمومی — پروفایل از هر دو محل (قدیم و جدید) سرو می‌شود app.use('/storage/profiles', express.static(path.join(__dirname, '../storage/profiles'))); +app.use('/storage/profiles', express.static(path.join(__dirname, 'storage/profiles'))); app.use('/storage/carts', express.static(path.join(__dirname, '../storage/carts'))); +app.use('/storage/carts', express.static(path.join(__dirname, 'storage/carts'))); +app.use('/storage/posts', express.static(path.join(__dirname, 'storage/posts'))); app.use('/storage/posts', express.static(path.join(__dirname, '../storage/posts'))); app.use('/storage/messages', express.static(path.join(__dirname, '../storage/messages'))); +app.use('/storage/messages', express.static(path.join(__dirname, 'storage/messages'))); app.use('/storage/tickets', express.static(path.join(__dirname, '../storage/tickets'))); +app.use('/storage/tickets', express.static(path.join(__dirname, 'storage/tickets'))); app.use('/storage/advertising', express.static(path.join(__dirname, '../storage/advertising'))); +app.use('/storage/advertising', express.static(path.join(__dirname, 'storage/advertising'))); app.use('/storage/services', express.static(path.join(__dirname, '../storage/services'))); +app.use('/storage/services', express.static(path.join(__dirname, 'storage/services'))); +app.use('/storage', express.static(path.join(__dirname, 'storage'))); require('./boot'); diff --git a/models/UserModel.js b/models/UserModel.js index ddf6b87..9e8731b 100644 --- a/models/UserModel.js +++ b/models/UserModel.js @@ -16,6 +16,11 @@ const userSchema = new mongoose.Schema({ maxLength: 6, default: null }, + otpSentAt: { + type: Date, + required: false, + default: null + }, user_name: { type: String, required: false, diff --git a/utils/otpExpiry.js b/utils/otpExpiry.js index ff4e30a..f30e7fe 100644 --- a/utils/otpExpiry.js +++ b/utils/otpExpiry.js @@ -1,4 +1,4 @@ -const OTP_VALID_MS = 5 * 60 * 1000 +const OTP_VALID_MS = 3 * 60 * 1000 const isOtpExpired = (user) => { if (!user?.otp) return true