Your One-Time Password (OTP) is:
diff --git a/app/db/config.js b/app/db/config.js index a16a359..b8bdb29 100644 --- a/app/db/config.js +++ b/app/db/config.js @@ -4,10 +4,15 @@ const dotenv = require('dotenv'); dotenv.config(); +let existingConnection; + const connectDB = async () => { try { - await mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true }); - logger.info('🚀 Connected to MongoDB'); + if (!existingConnection) { + existingConnection = await mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true }); + logger.info('🚀 Connected to MongoDB'); + } + return existingConnection; } catch (error) { console.error(error); logger.error(error); diff --git a/app/index.js b/app/index.js index 59d1f86..33becac 100644 --- a/app/index.js +++ b/app/index.js @@ -2,7 +2,7 @@ const express = require('express'); const cors = require('cors'); const dotenv = require('dotenv'); const connectDB = require('./db/config'); -const middleware = require('./middleware/middleware'); +const {middleware, validateSpamMiddleware} = require('./middleware/middleware'); const { isValidEmail } = require('./utils/validator'); const otpRoutes = require('./routes/otpRoutes'); const logger = require('./utils/logger'); @@ -21,7 +21,7 @@ app.get('/', (req, res) => { res.send('Welcome to OTP service'); }); -app.use('/api', middleware, otpRoutes); +app.use('/api', validateSpamMiddleware, middleware, otpRoutes); app.get('/api/cron', (req, res) => { try { diff --git a/app/middleware/middleware.js b/app/middleware/middleware.js index 0c139b3..9de0912 100644 --- a/app/middleware/middleware.js +++ b/app/middleware/middleware.js @@ -1,5 +1,44 @@ const { isValidEmail } = require("../utils/validator"); const logger = require("../utils/logger"); +const Blocklist = require("../models/blockListModel"); + +const spma_words = process.env.BLOCK_KEYWORDS_RULES.split(',') || []; + +const getIp = async (req) => { + try { + const ipDetails = await fetch("https://ipapi.co/json/"); + const ipDetailsJson = await ipDetails.json(); + return ipDetailsJson.ip; + } catch (error) { + return null; + } +} + +const validateSpamMiddleware = async (req, res, next) => { + const bodyValues = Object.values(req.body); + const bodyText = bodyValues.join(' '); + const ip = await getIp(req); + + const blocklist = await Blocklist.findOne({ + $or: [ + { email: req.body.email ? req.body.email : null }, + { ip: ip } + ] + }, { email: 1, ip: 1, _id: 0 }); + + if (blocklist) { + logger.error('Spam detected'); + return res.status(400).json({ error: 'Spam detected' }); + } + + if (spma_words.some(word => bodyText.includes(word))) { + await Blocklist.create({ ip: ip, email: req.body.email ? req.body.email : null }); + logger.error('Spam detected'); + return res.status(400).json({ error: 'Spam detected' }); + } + + next(); +} const validateEmail = (req, res, next) => { const { email } = req.body; @@ -33,4 +72,7 @@ const middleware = (req, res, next) => { } }; -module.exports = middleware; \ No newline at end of file +module.exports = { + middleware, + validateSpamMiddleware, +} \ No newline at end of file diff --git a/app/models/blockListModel.js b/app/models/blockListModel.js new file mode 100644 index 0000000..5232268 --- /dev/null +++ b/app/models/blockListModel.js @@ -0,0 +1,20 @@ +const mongoose = require('mongoose'); + +const blocklistSchema = new mongoose.Schema({ + ip: { + type: String, + required: [true, 'IP address is required'], + }, + email: { + type: String, + required: [true, 'Email is required'], + }, + createdAt: { + type: Date, + default: Date.now, + }, +}); + +const Blocklist = mongoose.model('Blocklist', blocklistSchema); + +module.exports = Blocklist; \ No newline at end of file diff --git a/app/models/otpModel.js b/app/models/otpModel.js index 5bc9751..1844fed 100644 --- a/app/models/otpModel.js +++ b/app/models/otpModel.js @@ -10,6 +10,10 @@ const otpSchema = new mongoose.Schema({ type: String, required: true, }, + attempts: { + type: Number, + default: 0, + }, createdAt: { type: Date, default: Date.now, @@ -18,4 +22,5 @@ const otpSchema = new mongoose.Schema({ const Otp = mongoose.model('Otp', otpSchema); -module.exports = Otp; \ No newline at end of file +module.exports = Otp; + diff --git a/app/routes/otpRoutes.js b/app/routes/otpRoutes.js index cdeb1e7..ba83427 100644 --- a/app/routes/otpRoutes.js +++ b/app/routes/otpRoutes.js @@ -9,6 +9,9 @@ router.post('/otp/generate', async (req, res) => { try { const { email, type = 'numeric', organization = 'Saurav Hathi', subject = 'One-Time Password (OTP)' } = req.body; + // SPAM_WORDS = madarchod,chutiya,bsdk,bsdk,mc,bc,bhoslund,land,behenchod,motherfucker + const spma_words = process.env.SPAM_WORDS + const otp = await otpController.generateOtp(email, type); await sendMailController(email, otp, organization, subject);