const { setJson, getJson } = require('../config/redis'); const { generateOTP } = require('../otpgenerator'); const { generateToken } = require('../util/jwt'); const authService = require('../services/auth.service.js'); const customerController = require('../controllers/customer_details.controller.js'); const { logger } = require('../util/logger'); const axios = require('axios'); const templates = require('../util/sms_template'); // Send OTP async function SendOtp(req, res) { const { username, mobileNumber, type, amount, beneficiary, ifsc, acctFrom, acctTo, ref, date, userOtp, PreferName, } = req.body; if (!mobileNumber || !type) { return res .status(400) .json({ error: 'Mobile number and type are required' }); } try { let message; let otp = null; // Pick template based on type switch (type) { case 'LOGIN_OTP': otp = generateOTP(6); message = templates.LOGIN_OTP(otp, username); break; case 'IMPS': otp = generateOTP(6); message = templates.IMPS(otp); break; case 'NEFT': otp = generateOTP(6); message = templates.NEFT(otp, amount, beneficiary); break; case 'RTGS': otp = generateOTP(6); message = templates.RTGS(otp, amount, beneficiary); break; case 'BENEFICIARY_ADD': otp = generateOTP(6); message = templates.BENEFICIARY_ADD(otp, beneficiary, ifsc); break; case 'BENEFICIARY_SUCCESS': message = templates.BENEFICIARY_SUCCESS(beneficiary); break; case 'BENEFICIARY_DELETE': otp = generateOTP(6); message = templates.BENEFICIARY_DELETE(otp, beneficiary); break; case 'NOTIFICATION': message = templates.NOTIFICATION(acctFrom, acctTo, amount, ref, date); break; case 'FORGOT_PASSWORD': otp = generateOTP(6); message = templates.FORGOT_PASSWORD(otp); break; case 'CHANGE_LPWORD': otp = generateOTP(6); message = templates.CHANGE_LPWORD(otp); break; case 'CHANGE_TPIN': otp = generateOTP(6); message = templates.CHANGE_TPIN(otp); break; case 'CHANGE_TPWORD': otp = generateOTP(6); message = templates.CHANGE_TPWORD(otp); break; case 'SET_TPWORD': otp = generateOTP(6); message = templates.SET_TPWORD(otp); break; case 'CHANGE_MPIN': otp = generateOTP(6); message = templates.CHANGE_MPIN(otp); break; case 'REGISTRATION': otp = userOtp ? userOtp : generateOTP(6); message = templates.REGISTRATION(otp); break; case 'RIGHT_UPDATE': message = templates.RIGHT_UPDATE; break; case 'EMandate': otp = generateOTP(6); message = templates.EMandate(otp); break; case 'USERNAME_UPDATED': otp = generateOTP(6); message = templates.USERNAME_UPDATED(otp); break; case 'USERNAME_SAVED': message = templates.USERNAME_SAVED(PreferName); break; case 'TLIMIT': otp = generateOTP(6); message = templates.TLIMIT(otp); break; case 'TLIMIT_SET': message = templates.TLIMIT_SET(amount); break; default: return res.status(400).json({ error: 'Invalid OTP type' }); } // Call SMS API const response = await axios.post( 'http://localhost:9999/api/SendtoMessage', { mobileNumber, stMessage: message, } ); if (response.data) { // Save OTP only if it's OTP based (skip notifications without OTP) if (message.includes('OTP')) { await setJson(`otp:${mobileNumber}`, otp, 300); } logger.info(`Sent OTP [${otp}] for type [${type}] to ${mobileNumber}`); } return res.status(200).json({ message: 'Message sent successfully' }); } catch (err) { logger.error(err, 'Error sending OTP'); return res.status(500).json({ error: 'Internal server error' }); } } // Verify OTP async function VerifyOtp(req, res) { const { mobileNumber } = req.query; const { otp } = req.body; if (!mobileNumber || !otp) { return res.status(400).json({ error: 'Phone number and OTP are required' }); } try { const storedOtp = await getJson(`otp:${mobileNumber}`); if (!storedOtp) { return res.status(400).json({ error: 'OTP expired or not found' }); } if (parseInt(otp, 10) !== parseInt(storedOtp, 10)) { return res.status(400).json({ error: 'Invalid OTP' }); } return res.status(200).json({ message: 'OTP verified successfully' }); } catch (err) { logger.error(err, 'Error verifying OTP'); return res.status(500).json({ error: 'Internal server error' }); } } async function sendForSetPassword(req, res) { try { const { customerNo } = req.query; if (!customerNo) return res.status(400).json({ error: 'CUSTOMER_NO_REQUIRED' }); // check if user is registered for in mobile banking data const user = await authService.findUserByCustomerNo(customerNo); if (!user) return res.status(404).json({ error: 'USER_NOT_FOUND' }); // if present then get his phone number from CBS const userDetails = await customerController.getDetails(customerNo); const singleUserDetail = userDetails[0]; if (!singleUserDetail?.mobileno) return res.status(400).json({ error: 'USER_PHONE_NOT_FOUND' }); const mobileNumber = singleUserDetail.mobileno; const otp = generateOTP(6); const message = templates.CHANGE_LPWORD(otp); const response = await axios.post( 'http://localhost:9999/api/SendtoMessage', { mobileNumber, stMessage: message, } ); await setJson(`otp:${mobileNumber}`, otp, 300); return res.status(200).json({ message: 'OTP_SENT' }); } catch (err) { logger.error(err, 'Error sending OTP'); return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' }); } } async function verifyForSetPassword(req, res) { try { const { customerNo, otp } = req.query; if (!customerNo || !otp) return res.status(400).json({ error: 'CUSTOMER_NO_REQUIRED' }); // check if user is registered for mobile banking database const user = await authService.findUserByCustomerNo(customerNo); if (!user) return res.status(404).json({ error: 'USER_NOT_FOUND' }); // if present then get his phone number from CBS const userDetails = await customerController.getDetails(customerNo); // temp check const singleUserDetail = userDetails[0]; if (!singleUserDetail?.mobileno) return res.status(400).json({ error: 'USER_PHONE_NOT_FOUND' }); const mobileNumber = singleUserDetail.mobileno; const storedOtp = await getJson(`otp:${mobileNumber}`); if (!storedOtp) { return res.status(400).json({ error: 'OTP expired or not found' }); } if (parseInt(otp, 10) !== parseInt(storedOtp, 10)) { return res.status(400).json({ error: 'Invalid OTP' }); } const token = generateToken(customerNo, 'user', '5m'); return res .status(200) .json({ message: 'OTP verified successfully', token: token }); } catch (err) { logger.error(err, 'Error sending OTP'); return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' }); } } module.exports = { SendOtp, VerifyOtp, sendForSetPassword, verifyForSetPassword, };