diff --git a/.gitignore b/.gitignore index dbef8e3..a4713c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ +.vscode/ .env logs/requests.log diff --git a/.vscode/settings.json b/.vscode/settings.json index 3c51a6b..9be9fc9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,9 @@ { "cSpell.words": [ + "MPIN", + "otpgenerator", "tpassword", - "tpin" + "tpin", + "TPWORD" ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2e75d14..d38797a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "axios": "^1.9.0", "bcrypt": "^6.0.0", "cors": "^2.8.5", + "dayjs": "^1.11.18", "dotenv": "^16.5.0", "express": "^5.1.0", "jsonwebtoken": "^9.0.2", @@ -842,6 +843,12 @@ "node": "*" } }, + "node_modules/dayjs": { + "version": "1.11.18", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==", + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", diff --git a/package.json b/package.json index bb10d6d..308780e 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "axios": "^1.9.0", "bcrypt": "^6.0.0", "cors": "^2.8.5", + "dayjs": "^1.11.18", "dotenv": "^16.5.0", "express": "^5.1.0", "jsonwebtoken": "^9.0.2", diff --git a/src/app.js b/src/app.js index 254e856..950a0b4 100644 --- a/src/app.js +++ b/src/app.js @@ -39,3 +39,4 @@ app.use((err, _req, res, _next) => { }); module.exports = app; + diff --git a/src/controllers/admin_auth.controller.js b/src/controllers/admin_auth.controller.js new file mode 100644 index 0000000..179b5ff --- /dev/null +++ b/src/controllers/admin_auth.controller.js @@ -0,0 +1,122 @@ +const adminAuthService = require('../services/admin.auth.service'); +const authService = require('../services/auth.service'); +const { generateToken } = require('../util/jwt'); +const { logger } = require('../util/logger'); +const { hashPassword } = require('../util/hash'); +const db = require('../config/db'); +const { generateOTP } = require('../otpgenerator'); +const dayjs = require("dayjs"); + +async function login(req, res) { + const { userName, password } = req.body; + + if (!userName || !password) { + return res + .status(400) + .json({ error: 'UserName and Password are required' }); + } + const currentTime = new Date().toISOString(); + try { + const admin = await adminAuthService.validateAdmin(userName, password); + if (!admin) return res.status(401).json({ error: 'invalid credentials' }); + + const token = generateToken(admin.username, 'admin', '1d'); + await db.query('UPDATE admin SET last_login = $1 WHERE username = $2', [ + currentTime, + userName, + ]); + res.json({ token }); + } catch (err) { + logger.error(err, 'login failed'); + res.status(500).json({ error: 'something went wrong' }); + } +} + +async function fetchAdminDetails(req, res) { + const customerNo = req.admin; + try { + const admin = await adminAuthService.findAdminByUserName(customerNo); + if (!admin) return res.status(404).json({ message: 'ADMIN_USER_NOT_FOUND' }); + return res.json(admin); + + } catch (err) { + logger.error(err, 'error occurred while fetching admin details'); + res.status(500).json({ error: 'something went wrong' }); + } +} + +async function getUserDetails(req, res) { + const { CIF } = req.query; + if (!CIF) { + res.status(400).json({ + error: 'CIF number is required', + }); + } + try { + const userDetails = await adminAuthService.getCustomerDetails(CIF); + if (!userDetails) + return res.status(401).json({ error: 'invalid CIF number' }); + return res.json(userDetails); + } catch (error) { + logger.error('while fetching customer details', error); + res.status(500).json({ error: 'invalid CIF number' }); + } +} +async function getUserRights(req, res) { + const { CIF } = req.query; + if (!CIF) { + res.status(400).json({ + error: 'CIF number is required', + }); + } + const userDetails = await adminAuthService.getCustomerDetailsFromDB(CIF); + if (!userDetails) + return res.status(401).json({ error: 'invalid CIF number or No rights is present for the user.' }); + return res.json(userDetails); +} + +async function UserRights(req, res) { + try { + const { CIF, ib_access_level, mb_access_level } = req.body; + + if (!CIF) { + return res.status(400).json({ error: 'CIF number is required' }); + } + + const currentTime = new Date().toISOString(); + const user = await authService.findUserByCustomerNo(CIF); + const first_time_pass = generateOTP(6); + const password = await hashPassword(first_time_pass); + if (user) { + const FirstTimeLogin = await authService.CheckFirstTimeLogin(CIF); + // if user did not login within 7 days + if (FirstTimeLogin && dayjs(currentTime).diff(dayjs(user.created_at), 'day') > 8) { + // Password expired, resend + await db.query( + 'UPDATE users SET password_hash=$2, updated_at=$5, ib_access_level=$3, mb_access_level=$4 WHERE customer_no=$1', + [CIF, password, ib_access_level, mb_access_level, currentTime] + ); + return res.json({ otp: first_time_pass }); + } + // Just update access levels and timestamp + await db.query( + 'UPDATE users SET updated_at=$4, ib_access_level=$2, mb_access_level=$3 WHERE customer_no=$1', + [CIF, ib_access_level, mb_access_level, currentTime] + ); + return res.json({ message: "User updated successfully." }); + } else { + // User does not exist, insert + await db.query( + 'INSERT INTO users (customer_no, password_hash, ib_access_level, mb_access_level) VALUES ($1, $2, $3, $4)', + [CIF, password, ib_access_level, mb_access_level] + ); + return res.json({ otp: first_time_pass }); + } + } catch (err) { + console.error(err); + logger.error(err, 'UserRights failed'); + return res.status(500).json({ error: 'Something went wrong' }); + } +} + +module.exports = { login, fetchAdminDetails, getUserDetails, UserRights, getUserRights }; diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 94e23f8..53aa2d3 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -2,6 +2,8 @@ const authService = require('../services/auth.service'); const { generateToken } = require('../util/jwt'); const { logger } = require('../util/logger'); const db = require('../config/db'); +const dayjs = require("dayjs"); +const { comparePassword } = require('../util/hash'); async function login(req, res) { const { customerNo, password } = req.body; @@ -16,13 +18,22 @@ async function login(req, res) { const user = await authService.validateUser(customerNo, password); if (!user || !password) return res.status(401).json({ error: 'invalid credentials' }); - const token = generateToken(user.customer_no, '1d'); const FirstTimeLogin = await authService.CheckFirstTimeLogin(customerNo); + // For registration : if try to login first time after 7 days. + if (FirstTimeLogin && dayjs(user.created_at).diff(currentTime, "day") > 8) + return res.status(401).json({ error: 'Password Expired.Please Contact with Administrator' }); + + const token = generateToken(user.customer_no, '1d'); + const loginPswExpiry = user.password_hash_expiry; + const rights = { + ibAccess: user.ib_access_level, + mbAccess: user.mb_access_level, + }; await db.query('UPDATE users SET last_login = $1 WHERE customer_no = $2', [ currentTime, customerNo, ]); - res.json({ token, FirstTimeLogin }); + res.json({ token, FirstTimeLogin, loginPswExpiry, rights }); } catch (err) { logger.error(err, 'login failed'); res.status(500).json({ error: 'something went wrong' }); @@ -88,6 +99,7 @@ async function setLoginPassword(req, res) { return res.status(500).json({ error: 'SOMETHING_WENT_WRONG' }); } } + async function setTransactionPassword(req, res) { const customerNo = req.user; try { @@ -102,6 +114,50 @@ async function setTransactionPassword(req, res) { } } +async function changeLoginPassword(req, res) { + const customerNo = req.user; + try { + const user = await authService.findUserByCustomerNo(customerNo); + if (!user) return res.status(404).json({ error: 'USER_NOT_FOUND' }); + const { OldLPsw, newLPsw, confirmLPsw } = req.body; + const isMatch = await comparePassword(OldLPsw, user.password_hash); + if (!isMatch) + return res.status(500).json({ error: 'Please Enter Correct Old Login Password' }); + if (newLPsw !== confirmLPsw) + return res.status(500).json({ error: 'New Password and Confirm Password not Match' }) + const isMatchWithOldPassword = await comparePassword(newLPsw, user.password_hash); + if (isMatchWithOldPassword) + return res.status(500).json({ error: 'New Password will be different from Previous Password' }) + authService.changeLoginPassword(customerNo, newLPsw); + return res.json({ message: 'New Login Password changed successfully' }); + } catch (error) { + logger.error(error); + return res.status(500).json({ error: 'SOMETHING_WENT_WRONG' }); + } +} + +async function changeTransPassword(req, res) { + const customerNo = req.user; + try { + const user = await authService.findUserByCustomerNo(customerNo); + if (!user) return res.status(404).json({ error: 'USER_NOT_FOUND' }); + const { OldTPsw, newTPsw, confirmTPsw } = req.body; + const isMatch = await comparePassword(OldTPsw, user.transaction_password); + if (!isMatch) + return res.status(500).json({ error: 'Please Enter Correct Old Transaction Password' }); + if (newTPsw !== confirmTPsw) + return res.status(500).json({ error: 'New Transaction Password and Confirm Transaction Password not Match' }) + const isMatchWithOldPassword = await comparePassword(newTPsw, user.transaction_password); + if (isMatchWithOldPassword) + return res.status(500).json({ error: 'New Transaction Password will be different from Previous Transaction Password' }) + authService.changeTransPassword(customerNo, newTPsw); + return res.json({ message: 'New Transaction Password changed successfully' }); + } catch (error) { + logger.error(error); + return res.status(500).json({ error: 'SOMETHING_WENT_WRONG' }); + } +} + module.exports = { login, tpin, @@ -109,4 +165,6 @@ module.exports = { setLoginPassword, setTransactionPassword, fetchUserDetails, + changeLoginPassword, + changeTransPassword, }; diff --git a/src/controllers/neft.controller.js b/src/controllers/neft.controller.js index a43acd8..32b9feb 100644 --- a/src/controllers/neft.controller.js +++ b/src/controllers/neft.controller.js @@ -47,6 +47,8 @@ async function send( 'API call failed: ' + (error.response?.data?.message || error.message) ); } + + } module.exports = { send }; diff --git a/src/controllers/otp.controller.js b/src/controllers/otp.controller.js new file mode 100644 index 0000000..c885d50 --- /dev/null +++ b/src/controllers/otp.controller.js @@ -0,0 +1,124 @@ + +const { setJson, getJson } = require('../config/redis'); +const { generateOTP } = require('../otpgenerator'); +const { logger } = require('../util/logger'); +const axios = require('axios'); +const templates = require('../util/sms_template'); + +// Send OTP +async function SendOtp(req, res) { + const { mobileNumber, type, amount, beneficiary, ifsc, acctFrom, acctTo, ref, date, userOtp } = 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 '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 '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 'CHANGE_MPIN': + otp = generateOTP(6); + message = templates.CHANGE_MPIN(otp); + break; + case 'REGISTRATION': + otp = userOtp ? userOtp : generateOTP(6); + message = templates.REGISTRATION(otp); + case 'RIGHT_UPDATE': + message = templates.RIGHT_UPDATE; + 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' }); + } +} + +module.exports = { SendOtp, VerifyOtp }; diff --git a/src/middlewares/admin.middleware.js b/src/middlewares/admin.middleware.js new file mode 100644 index 0000000..0c823e4 --- /dev/null +++ b/src/middlewares/admin.middleware.js @@ -0,0 +1,28 @@ +const { verifyToken } = require('../util/jwt'); +const { logger } = require('../util/logger'); + +function checkAdmin (req,res,next){ + const authHeader = req.headers.authorization; + + if (!authHeader || !authHeader.startsWith('Bearer ')) { + return res + .status(401) + .json({ error: 'missing or malformed authorization header' }); + } + + const token = authHeader.split(' ')[1]; + try { + const payload = verifyToken(token); + // console.log("hi",payload); + if(payload.customerNo && payload.role === 'admin'){ + req.admin = payload.customerNo; + next(); + } + else + return res.status(403).json({error :'Only admin can access'}) + } catch (err) { + logger.error(err, 'error verifying token'); + return res.status(401).json({ error: 'invalid or expired token' }); + } +} +module.exports = checkAdmin; diff --git a/src/middlewares/auth.middleware.js b/src/middlewares/auth.middleware.js index ee2b4c2..dec4e69 100644 --- a/src/middlewares/auth.middleware.js +++ b/src/middlewares/auth.middleware.js @@ -21,5 +21,4 @@ function auth(req, res, next) { return res.status(401).json({ error: 'invalid or expired token' }); } } - module.exports = auth; diff --git a/src/otpgenerator.js b/src/otpgenerator.js new file mode 100644 index 0000000..b66a46b --- /dev/null +++ b/src/otpgenerator.js @@ -0,0 +1,12 @@ + +function generateOTP(length) { + const digits = '0123456789'; + let otp = ''; + otp += digits[Math.floor(Math.random() * 9) + 1]; // first digit cannot be zero + for (let i = 1; i < length; i++) { + otp += digits[Math.floor(Math.random() * digits.length)]; + } + return otp; +} + +module.exports = { generateOTP }; diff --git a/src/routes/admin_auth.route.js b/src/routes/admin_auth.route.js new file mode 100644 index 0000000..a598831 --- /dev/null +++ b/src/routes/admin_auth.route.js @@ -0,0 +1,12 @@ +const adminAuthController = require('../controllers/admin_auth.controller'); +const adminAuthenticate = require('../middlewares/admin.middleware'); +const express = require('express'); + +const router = express.Router(); + +router.post('/login', adminAuthController.login); +router.get('/admin_details', adminAuthenticate, adminAuthController.fetchAdminDetails); +router.get('/fetch/customer_details',adminAuthenticate,adminAuthController.getUserDetails); +router.post('/user/rights',adminAuthenticate,adminAuthController.UserRights); +router.get('/user/rights',adminAuthenticate,adminAuthController.getUserRights); +module.exports = router; diff --git a/src/routes/auth.route.js b/src/routes/auth.route.js index 2ab5178..01df214 100644 --- a/src/routes/auth.route.js +++ b/src/routes/auth.route.js @@ -9,10 +9,9 @@ router.get('/user_details', authenticate, authController.fetchUserDetails); router.get('/tpin', authenticate, authController.tpin); router.post('/tpin', authenticate, authController.setTpin); router.post('/login_password', authenticate, authController.setLoginPassword); -router.post( - '/transaction_password', - authenticate, - authController.setTransactionPassword -); +router.post('/transaction_password',authenticate,authController.setTransactionPassword); +router.post('/change/login_password',authenticate,authController.changeLoginPassword); +router.post('/change/transaction_password',authenticate,authController.changeTransPassword); + module.exports = router; diff --git a/src/routes/index.js b/src/routes/index.js index 4819c87..a779232 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,5 +1,6 @@ const express = require('express'); const authRoute = require('./auth.route'); +const adminAuthRoute =require('./admin_auth.route'); const detailsRoute = require('./customer_details.route'); const transactionRoute = require('./transactions.route'); const authenticate = require('../middlewares/auth.middleware'); @@ -9,10 +10,12 @@ const neftRoute = require('./neft.route'); const rtgsRoute = require('./rtgs.route'); const impsRoute = require('./imps.route'); const { npciResponse } = require('../controllers/npci.controller'); +const otp = require('./otp.route'); const router = express.Router(); router.use('/auth', authRoute); +router.use('/auth/admin',adminAuthRoute); router.use('/customer', authenticate, detailsRoute); router.use('/transactions/account/:accountNo', authenticate, transactionRoute); router.use('/payment/transfer', authenticate, transferRoute); @@ -21,5 +24,7 @@ router.use('/payment/rtgs', authenticate, rtgsRoute); router.use('/payment/imps', authenticate, impsRoute); router.use('/beneficiary', authenticate, beneficiaryRoute); router.use('/npci/beneficiary-response', npciResponse); +router.use('/otp', otp); + module.exports = router; diff --git a/src/routes/otp.route.js b/src/routes/otp.route.js new file mode 100644 index 0000000..fdf2a7d --- /dev/null +++ b/src/routes/otp.route.js @@ -0,0 +1,13 @@ + +const express = require('express'); +const otpController = require('../controllers/otp.controller'); + +const router = express.Router(); + +// Send OTP (POST request with body) +router.post('/send', otpController.SendOtp); + +// Verify OTP (GET request with query params ?mobileNumber=xxx&otp=123456) +router.post('/verify', otpController.VerifyOtp); + +module.exports = router; diff --git a/src/services/admin.auth.service.js b/src/services/admin.auth.service.js new file mode 100644 index 0000000..e6489c8 --- /dev/null +++ b/src/services/admin.auth.service.js @@ -0,0 +1,47 @@ +const db = require('../config/db'); +const { comparePassword, hashPassword } = require('../util/hash'); +const axios = require('axios'); + +async function findAdminByUserName(customerNo) { + const result = await db.query('SELECT * FROM admin WHERE username = $1', [ + customerNo, + ]); + return result.rows[0]; +} + +async function validateAdmin(customerNo, password) { + const user = await findAdminByUserName(customerNo); + if (!user) return null; + const isMatch = await comparePassword(password, user.password); + return isMatch ? user : null; +} + +async function getCustomerDetails(customerNo) { + try { + const response = await axios.get( + 'http://localhost:8686/kccb/cbs/custInfo/details', + { params: { stcustno: customerNo } } + ); + const details = response.data; + const processedDetails = details.map((acc) => ({ + ...acc, + activeAccounts: details.length, + cifNumber: customerNo, + })); + return processedDetails; + } catch (error) { + logger.error('while fetching customer details', error); + throw new Error( + 'API call failed: ' + (error.response?.data?.message || error.message) + ); + } +} + +async function getCustomerDetailsFromDB(customerNo) { + const result = await db.query('SELECT customer_no,created_at,last_login,is_first_login,ib_access_level,mb_access_level FROM users WHERE customer_no = $1', [ + customerNo, + ]); + return result.rows[0]; +} + +module.exports = { validateAdmin, findAdminByUserName, getCustomerDetails,getCustomerDetailsFromDB }; diff --git a/src/services/auth.service.js b/src/services/auth.service.js index b5cfe71..52e448c 100644 --- a/src/services/auth.service.js +++ b/src/services/auth.service.js @@ -1,5 +1,6 @@ const db = require('../config/db'); const { comparePassword, hashPassword } = require('../util/hash'); +const dayjs =require("dayjs"); async function findUserByCustomerNo(customerNo) { const result = await db.query('SELECT * FROM users WHERE customer_no = $1', [ @@ -47,14 +48,16 @@ async function setTpin(customerNo, tpin) { // Set login password async function setLoginPassword(customerNo, login_psw) { const hashedLoginPassword = await hashPassword(login_psw); + const currentTime = dayjs().toISOString(); + const password_expiry = dayjs().add(90,"day").toISOString(); try { await db.query( - 'UPDATE users SET password_hash = $1 ,is_first_login = false WHERE customer_no = $2', - [hashedLoginPassword, customerNo] + 'UPDATE users SET password_hash = $1 ,is_first_login = false,updated_at = $3,password_hash_expiry =$4 WHERE customer_no = $2', + [hashedLoginPassword, customerNo ,currentTime ,password_expiry] ); } catch (error) { throw new Error( - `error occured while while setting new Login Password ${error.message}` + `error occurred while while setting new Login Password ${error.message}` ); } } @@ -69,14 +72,48 @@ async function validateTransactionPassword(customerNo, tpassword) { // Set transaction password async function setTransactionPassword(customerNo, trans_psw) { const hashedTransPassword = await hashPassword(trans_psw); + const currentTime = dayjs().toISOString(); + const password_expiry = dayjs().add(90,"day").toISOString(); try { await db.query( - 'UPDATE users SET transaction_password = $1 WHERE customer_no = $2', - [hashedTransPassword, customerNo] + 'UPDATE users SET transaction_password = $1 ,updated_at = $3,transaction_password_expiry =$4 WHERE customer_no = $2', + [hashedTransPassword, customerNo , currentTime ,password_expiry] ); } catch (error) { throw new Error( - `error occured while while setting new Transaction Password ${error.message}` + `error occurred while while setting new Transaction Password ${error.message}` + ); + } +} + +async function changeLoginPassword(customerNo, login_psw) { + const hashedLoginPassword = await hashPassword(login_psw); + const currentTime = dayjs().toISOString(); + const password_expiry = dayjs().add(90,"day").toISOString(); + try { + await db.query( + 'UPDATE users SET password_hash = $1 ,updated_at = $3,password_hash_expiry =$4 WHERE customer_no = $2', + [hashedLoginPassword, customerNo , currentTime ,password_expiry] + ); + } catch (error) { + throw new Error( + `error occured while while setting new Login Password ${error.message}` + ); + } +} + +async function changeTransPassword(customerNo, trans_psw) { + const hashedTransPassword = await hashPassword(trans_psw); + const currentTime = dayjs().toISOString(); + const password_expiry = dayjs().add(90,"day").toISOString(); + try { + await db.query( + 'UPDATE users SET transaction_password = $1 ,updated_at = $3,transaction_password_expiry =$4 WHERE customer_no = $2', + [hashedTransPassword, customerNo , currentTime ,password_expiry] + ); + } catch (error) { + throw new Error( + `error occurred while while setting new Login Password ${error.message}` ); } } @@ -90,4 +127,6 @@ module.exports = { setLoginPassword, validateTransactionPassword, setTransactionPassword, + changeLoginPassword, + changeTransPassword, }; diff --git a/src/util/jwt.js b/src/util/jwt.js index cea8ad0..e26a641 100644 --- a/src/util/jwt.js +++ b/src/util/jwt.js @@ -2,9 +2,9 @@ const jwt = require('jsonwebtoken'); const { jwtSecret } = require('../config/config'); const { logger } = require('./logger'); -function generateToken(customerNo, expiresIn = '10d') { - logger.info({ customerNo }, 'payload to encode'); - return jwt.sign({ customerNo }, jwtSecret, { expiresIn }); +function generateToken(customerNo, role = 'user', expiresIn = '10d') { + logger.info({ customerNo, role }, 'payload to encode'); + return jwt.sign({ customerNo, role }, jwtSecret, { expiresIn }); } function verifyToken(token) { diff --git a/src/util/sms_template.js b/src/util/sms_template.js new file mode 100644 index 0000000..2998655 --- /dev/null +++ b/src/util/sms_template.js @@ -0,0 +1,41 @@ +const templates = { + IMPS: (otp) => `Dear Customer, Please complete the fund transfer with OTP ${otp} -KCCB`, + + NEFT: (otp, amount, beneficiary) => + `Dear Customer, Please complete the NEFT of Rs.${amount} to ${beneficiary} with OTP:${otp} -KCCB`, + + RTGS: (otp, amount, beneficiary) => + `Dear Customer, Please complete the RTGS of Rs.${amount} to ${beneficiary} with OTP:${otp} -KCCB`, + + BENEFICIARY_ADD: (otp, beneficiary, ifsc) => + `Dear Customer, You have added beneficiary ${beneficiary} ${ifsc} for NEFT/RTGS. Please endorse the beneficiary with OTP ${otp} -KCCB`, + + BENEFICIARY_SUCCESS: (beneficiary) => + `Dear Customer, Your Beneficiary: ${beneficiary} for Net Banking is added successfully -KCCB`, + + NOTIFICATION: (acctFrom, acctTo, amount, ref, date) => + `Your A/c ${acctFrom} is debited for Rs. ${amount} to the credit of A/c ${acctTo} thru Net Banking - ref: ${ref} - ${date} - Kangra Central Co-Operative Bank -KCCB`, + + FORGOT_PASSWORD: (otp) => + `Dear Customer, Forgot Password OTP is ${otp} -KCCB`, + + CHANGE_LPWORD: (otp) => + `Dear Customer, Change Login Password OTP is ${otp} -KCCB`, + + CHANGE_TPIN: (otp) => + `Dear Customer, Change Transaction pin OTP is ${otp} -KCCB`, + + CHANGE_TPWORD: (otp) => + `Dear Customer, Change Transaction password OTP is ${otp} -KCCB`, + + CHANGE_MPIN: (otp) => + `Dear Customer, Change M-PIN OTP is ${otp} -KCCB`, + + REGISTRATION: (otp) => + `Dear Customer, Your CIF is enable.First time login password: ${otp} (valid for 7 days).Please login and change your password -KCCB`, + + RIGHT_UPDATE: + `Dear Customer, Your CIF rights have been updated. Please log in again to access the features. -KCCB`, +}; + +module.exports = templates; \ No newline at end of file