From caef3bd690a332736d29b5f84a277584cb4dcde6 Mon Sep 17 00:00:00 2001 From: asif Date: Fri, 7 Nov 2025 16:01:07 +0530 Subject: [PATCH 01/13] fix: added beneficiary create date in beneficiary list payload --- src/services/beneficiary.service.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/beneficiary.service.js b/src/services/beneficiary.service.js index d5a6cfc..f9ef7a2 100644 --- a/src/services/beneficiary.service.js +++ b/src/services/beneficiary.service.js @@ -53,13 +53,14 @@ async function deleteBeneficiary(customerNo, beneficiaryAccountNo) { async function getAllBeneficiaries(customerNo) { const queryStr = - 'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, i.bank_name, i.branch_name FROM beneficiaries b JOIN LATERAL( SELECT * FROM ifsc_details i WHERE i.ifsc_code = b.ifsc_code LIMIT 1 ) i ON true WHERE customer_no = $1'; + 'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, b.created_at, i.bank_name, i.branch_name FROM beneficiaries b JOIN LATERAL( SELECT * FROM ifsc_details i WHERE i.ifsc_code = b.ifsc_code LIMIT 1 ) i ON true WHERE customer_no = $1'; const result = await db.query(queryStr, [customerNo]); const list = result.rows.map((row) => { const details = { accountNo: row['account_no'], name: row['name'], accountType: row['account_type'], + createdAt: row['created_at'], }; if (row['ifsc_code'] === '_') { details['bankName'] = 'THE KANGRA CENTRAL COOPERATIVE BANK LIMITED'; From 95fc26ef6b76c904c7839f021359c753e041cda9 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 02:04:48 +0530 Subject: [PATCH 02/13] feat: added beneficiary creation date and time in the api response to manage cooldown at frontend --- src/services/beneficiary.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/beneficiary.service.js b/src/services/beneficiary.service.js index f9ef7a2..7068daf 100644 --- a/src/services/beneficiary.service.js +++ b/src/services/beneficiary.service.js @@ -36,7 +36,7 @@ async function validateOutsideBank(accountNo, ifscCode, name) { async function getSingleBeneficiary(customerNo, accountNo) { const queryStr = - 'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, i.bank_name, i.branch_name FROM beneficiaries b JOIN ifsc_details i ON b.ifsc_code = i.ifsc_code WHERE customer_no = $1 AND account_no = $2'; + 'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, b.created_at, i.bank_name, i.branch_name FROM beneficiaries b JOIN ifsc_details i ON b.ifsc_code = i.ifsc_code WHERE customer_no = $1 AND account_no = $2'; const result = await db.query(queryStr, [customerNo, accountNo]); return result.rows[0]; } From f7bc0f6785ccad973724934a0836fc20ab431fb2 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 02:06:17 +0530 Subject: [PATCH 03/13] added middleware to check if the transaction is within cooldown period --- src/middlewares/cooldown.middleware.js | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/middlewares/cooldown.middleware.js diff --git a/src/middlewares/cooldown.middleware.js b/src/middlewares/cooldown.middleware.js new file mode 100644 index 0000000..7e6fe0b --- /dev/null +++ b/src/middlewares/cooldown.middleware.js @@ -0,0 +1,28 @@ +const { logger } = require('../util/logger'); +const { getSingleBeneficiary } = require('../services/beneficiary.service'); + +async function checkBeneficiaryCooldown(req, res, next) { + const cooldownTime = parseInt( + process.env.BENEFICIARY_COOLDOWN_TIME || '60', + 10 + ); + const customerNo = req.user; + const { toAccount } = req.body; + const beneficiary = await getSingleBeneficiary(customerNo, toAccount); + + if (beneficiary) { + const now = new Date(); + const cooldownPeriod = new Date(now.getTime() - cooldownTime * 60 * 1000); + const createdAt = new Date(beneficiary['created_at']); + if (createdAt > cooldownPeriod) { + const remaining = (now - createdAt) / (60 * 1000); + logger.warn('TRANSACTION_FAILED_BENEFICIARY_COOLDOWN_ACTIVE'); + return res.status(403).json({ + error: `beneficiary cooldown period active. Retry after ${remaining} minutes`, + }); + } + } + next(); +} + +module.exports = { checkBeneficiaryCooldown }; From 0164aad4027e0b988a4ac982dc22eb3941266b24 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 02:07:45 +0530 Subject: [PATCH 04/13] added beneficiary payment middleware to neft, rtgs, imps and transfer routes --- src/routes/imps.route.js | 10 +++++++++- src/routes/neft.route.js | 10 +++++++++- src/routes/rtgs.route.js | 10 +++++++++- src/routes/transfer.route.js | 10 +++++++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/routes/imps.route.js b/src/routes/imps.route.js index f663283..dc4ecaf 100644 --- a/src/routes/imps.route.js +++ b/src/routes/imps.route.js @@ -4,9 +4,17 @@ const { logger } = require('../util/logger'); const impsValidator = require('../validators/imps.validator'); const paymentSecretValidator = require('../validators/payment.secret.validator'); const { checkLimit } = require('../middlewares/limitCheck.middleware'); +const { + checkBeneficiaryCooldown, +} = require('../middlewares/cooldown.middleware'); const router = express.Router(); -router.use(impsValidator, paymentSecretValidator, checkLimit); +router.use( + impsValidator, + paymentSecretValidator, + checkLimit, + checkBeneficiaryCooldown +); const impsRoute = async (req, res) => { const { fromAccount, toAccount, ifscCode, amount, beneficiaryName, remarks } = diff --git a/src/routes/neft.route.js b/src/routes/neft.route.js index bccbed7..d62d6b8 100644 --- a/src/routes/neft.route.js +++ b/src/routes/neft.route.js @@ -4,9 +4,17 @@ const { logger } = require('../util/logger'); const neftValidator = require('../validators/neft.validator.js'); const paymentSecretValidator = require('../validators/payment.secret.validator'); const { checkLimit } = require('../middlewares/limitCheck.middleware'); +const { + checkBeneficiaryCooldown, +} = require('../middlewares/cooldown.middleware'); const router = express.Router(); -router.use(neftValidator, paymentSecretValidator, checkLimit); +router.use( + neftValidator, + paymentSecretValidator, + checkLimit, + checkBeneficiaryCooldown +); const neftRoute = async (req, res) => { const { diff --git a/src/routes/rtgs.route.js b/src/routes/rtgs.route.js index 7534715..9a8c189 100644 --- a/src/routes/rtgs.route.js +++ b/src/routes/rtgs.route.js @@ -4,9 +4,17 @@ const { logger } = require('../util/logger'); const rtgsValidator = require('../validators/rtgs.validator.js'); const paymentSecretValidator = require('../validators/payment.secret.validator'); const { checkLimit } = require('../middlewares/limitCheck.middleware'); +const { + checkBeneficiaryCooldown, +} = require('../middlewares/cooldown.middleware'); const router = express.Router(); -router.use(rtgsValidator, paymentSecretValidator, checkLimit); +router.use( + rtgsValidator, + paymentSecretValidator, + checkLimit, + checkBeneficiaryCooldown +); const rtgsRoute = async (req, res) => { const { diff --git a/src/routes/transfer.route.js b/src/routes/transfer.route.js index 6602b4d..dfabc49 100644 --- a/src/routes/transfer.route.js +++ b/src/routes/transfer.route.js @@ -4,9 +4,17 @@ const express = require('express'); const transferValidator = require('../validators/transfer.validator'); const passwordValidator = require('../validators/payment.secret.validator.js'); const { checkLimit } = require('../middlewares/limitCheck.middleware'); +const { + checkBeneficiaryCooldown, +} = require('../middlewares/cooldown.middleware'); const router = express.Router(); -router.use(passwordValidator, transferValidator, checkLimit); +router.use( + passwordValidator, + transferValidator, + checkLimit, + checkBeneficiaryCooldown +); const transferRoute = async (req, res) => { const { fromAccount, toAccount, toAccountType, amount, remarks } = req.body; From 55c822487b5393aa91d0b2cbdc4ca769999de791 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 02:08:49 +0530 Subject: [PATCH 05/13] feat: added change tpin route --- src/controllers/auth.controller.js | 22 ++++++++++++++++++++++ src/routes/auth.route.js | 24 ++++++++++++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 74756f5..7c0192c 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -169,6 +169,27 @@ async function setTpin(req, res) { } } +async function changeTpin(req, res) { + const customerNo = req.user; + try { + const user = await authService.findUserByCustomerNo(customerNo); + if (!user) return res.status(404).json({ error: 'USER_NOT_FOUND' }); + if (!user.tpin) + return res.status(400).json({ error: 'USER_DOESNT_HAVE_A_TPIN' }); + const { oldTpin, newTpin } = req.body; + if(oldTpin !== user.tpin) + return res.status(400).json({ error: 'TPIN_DOESNT_MATCH' }); + + if (!/^\d{6}$/.test(newTpin)) + return res.status(400).json({ error: 'INVALID_TPIN_FORMAT' }); + authService.setTpin(customerNo, tpin); + return res.json({ message: 'TPIN_SET' }); + } catch (error) { + logger.error(error); + return res.status(500).json({ error: 'SOMETHING_WENT_WRONG' }); + } +} + async function setLoginPassword(req, res) { const customerNo = req.user; try { @@ -325,6 +346,7 @@ module.exports = { login, tpin, setTpin, + changeTpin, setLoginPassword, setTransactionPassword, fetchUserDetails, diff --git a/src/routes/auth.route.js b/src/routes/auth.route.js index 5bd61f6..c7d2c3a 100644 --- a/src/routes/auth.route.js +++ b/src/routes/auth.route.js @@ -8,12 +8,24 @@ router.post('/login', authController.login); router.get('/user_details', authenticate, authController.fetchUserDetails); router.get('/tpin', authenticate, authController.tpin); router.post('/tpin', authenticate, authController.setTpin); +router.post('/change/tpin', authenticate, authController.changeTpin); router.post('/login_password', authenticate, authController.setLoginPassword); -router.post('/transaction_password',authenticate,authController.setTransactionPassword); -router.post('/change/login_password',authenticate,authController.changeLoginPassword); -router.post('/change/transaction_password',authenticate,authController.changeTransPassword); -router.get('/user_name',authenticate,authController.isUserNameExits); -router.post('/user_name',authenticate,authController.setUserName); - +router.post( + '/transaction_password', + authenticate, + authController.setTransactionPassword +); +router.post( + '/change/login_password', + authenticate, + authController.changeLoginPassword +); +router.post( + '/change/transaction_password', + authenticate, + authController.changeTransPassword +); +router.get('/user_name', authenticate, authController.isUserNameExits); +router.post('/user_name', authenticate, authController.setUserName); module.exports = router; From c021d6033c3f0cda9a06b9a458322c5483cbddc3 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 02:22:26 +0530 Subject: [PATCH 06/13] refactor: added remaining time in beneficiary cooldown failure response --- src/middlewares/cooldown.middleware.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/middlewares/cooldown.middleware.js b/src/middlewares/cooldown.middleware.js index 7e6fe0b..80db4e2 100644 --- a/src/middlewares/cooldown.middleware.js +++ b/src/middlewares/cooldown.middleware.js @@ -16,9 +16,10 @@ async function checkBeneficiaryCooldown(req, res, next) { const createdAt = new Date(beneficiary['created_at']); if (createdAt > cooldownPeriod) { const remaining = (now - createdAt) / (60 * 1000); - logger.warn('TRANSACTION_FAILED_BENEFICIARY_COOLDOWN_ACTIVE'); + logger.warn('TRANSACTION_FAILED BENEFICIARY_COOLDOWN_ACTIVE'); return res.status(403).json({ - error: `beneficiary cooldown period active. Retry after ${remaining} minutes`, + remaining, + error: 'beneficiary cooldown period active', }); } } From 3f86697f6bae71b32450b205471f02c505ce6627 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 02:44:56 +0530 Subject: [PATCH 07/13] feat: added mobile tnc flag in login response --- src/controllers/auth.controller.js | 51 ++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 7c0192c..9d99b74 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -7,13 +7,14 @@ const { comparePassword } = require('../util/hash'); const customerController = require('../controllers/customer_details.controller.js'); const { setJson, getJson } = require('../config/redis'); - async function login(req, res) { let { customerNo, userName, password, otp } = req.body; const loginType = req.headers['x-login-type'] || 'standard'; if ((!customerNo && !userName) || !password) { - return res.status(400).json({ error: 'customerNo and password are required' }); + return res + .status(400) + .json({ error: 'customerNo and password are required' }); } const currentTime = new Date().toISOString(); const MAX_ATTEMPTS = 3; // Max invalid attempts before lock @@ -23,14 +24,17 @@ async function login(req, res) { const blockedKey = `login:blocked:${customerNo}`; const attemptsKey = `login:attempts:${customerNo}`; if (!customerNo && userName) { - const result = await db.query('SELECT * FROM users WHERE preferred_name = $1', [ - userName, - ]); + const result = await db.query( + 'SELECT * FROM users WHERE preferred_name = $1', + [userName] + ); if (result.rows.length === 0) { - logger.error("Customer not found with this user name."); - return res.status(404).json({ error: 'No user found with this username.' }); + logger.error('Customer not found with this user name.'); + return res + .status(404) + .json({ error: 'No user found with this username.' }); } - logger.info("Customer found with user name."); + logger.info('Customer found with user name.'); customerNo = result.rows[0].customer_no; } @@ -40,7 +44,7 @@ async function login(req, res) { // check DB locked flag if (userCheck && userCheck.locked) { await setJson(blockedKey, true, BLOCK_DURATION); - logger.error("USER Account Locked"); + logger.error('USER Account Locked'); return res.status(423).json({ error: 'Your account is locked. Please contact the administrator.', }); @@ -61,12 +65,16 @@ async function login(req, res) { attempts += 1; if (attempts >= MAX_ATTEMPTS) { - await db.query('UPDATE users SET locked = true WHERE customer_no = $1', [customerNo]); + await db.query( + 'UPDATE users SET locked = true WHERE customer_no = $1', + [customerNo] + ); await setJson(blockedKey, true, BLOCK_DURATION); await setJson(attemptsKey, 0); return res.status(423).json({ - error: 'Your account has been locked due to multiple failed login attempts. Please contact the administrator.', + error: + 'Your account has been locked due to multiple failed login attempts. Please contact the administrator.', }); } else { await setJson(attemptsKey, attempts, BLOCK_DURATION); @@ -107,6 +115,8 @@ async function login(req, res) { // --- Step 7: Generate token and update last login --- const token = generateToken(user.customer_no); const loginPswExpiry = user.password_hash_expiry; + const mobileTncAccepted = user.tnc_mobile; + const tnc = { mobile: mobileTncAccepted }; const rights = { ibAccess: user.ib_access_level, mbAccess: user.mb_access_level, @@ -116,7 +126,7 @@ async function login(req, res) { customerNo, ]); logger.info(`Login successful | Type: ${loginType}`); - return res.json({ token, FirstTimeLogin, loginPswExpiry, rights }); + return res.json({ token, FirstTimeLogin, loginPswExpiry, rights, tnc }); } catch (err) { logger.error(err, `login failed | Type: ${loginType}`); return res.status(500).json({ error: 'something went wrong' }); @@ -177,7 +187,7 @@ async function changeTpin(req, res) { if (!user.tpin) return res.status(400).json({ error: 'USER_DOESNT_HAVE_A_TPIN' }); const { oldTpin, newTpin } = req.body; - if(oldTpin !== user.tpin) + if (oldTpin !== user.tpin) return res.status(400).json({ error: 'TPIN_DOESNT_MATCH' }); if (!/^\d{6}$/.test(newTpin)) @@ -319,18 +329,25 @@ async function setUserName(req, res) { return res.json({ message: 'All set! Your username has been saved.' }); } if (userNameIsExits) { - const historyRes = await db.query('SELECT preferred_name FROM preferred_name_history WHERE customer_no = $1 ORDER BY changed_at DESC LIMIT 5', + const historyRes = await db.query( + 'SELECT preferred_name FROM preferred_name_history WHERE customer_no = $1 ORDER BY changed_at DESC LIMIT 5', [customerNo] ); // maximum 5 times can changed username - const history = historyRes.rows.map((r) => r.preferred_name.toLowerCase()); + const history = historyRes.rows.map((r) => + r.preferred_name.toLowerCase() + ); if (history.length >= 5) { - return res.status(429).json({ error: "Preferred name change limit reached -5 times" }); + return res + .status(429) + .json({ error: 'Preferred name change limit reached -5 times' }); } // Cannot match last 2 const lastTwo = history.slice(0, 2); if (lastTwo.includes(user_name.toLowerCase())) { - return res.status(409).json({ error: "Preferred name cannot match last 2 preferred names" }); + return res.status(409).json({ + error: 'Preferred name cannot match last 2 preferred names', + }); } await authService.setUserName(customerNo, user_name); logger.info('User name has been updated.'); From c39492eddef794b141fb4d3d67a14008c0c3fda5 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 18:39:39 +0530 Subject: [PATCH 08/13] feat: implemented routes for getting and setting customer tnc flag --- src/controllers/auth.controller.js | 24 +++++++++++++++++ src/routes/auth.route.js | 3 +++ src/services/auth.service.js | 43 ++++++++++++++++++++++++------ 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 9d99b74..7299bba 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -359,6 +359,28 @@ async function setUserName(req, res) { } } +async function getTncAcceptanceFlag(req, res) { + try { + const flag = await authService.getTncFlag(req.user, req.client); + res.json({ tnc_accepted: flag }); + } catch (error) { + logger.error(error, 'error occured while getting tnc flag'); + res.status(500).json({ error: 'INTERNAL SERVER ERROR' }); + } +} + +async function setTncAcceptanceFlag(req, res) { + try { + const { flag } = req.body; + if (typeof flag !== 'boolean') + res.staus(400).json({ error: 'invalid value for flag' }); + await authService.setTncFlag(req.user, req.client, flag); + } catch (error) { + logger.error(error, 'error occured while updating tnc flag'); + res.status(500).json({ error: 'INTERNAL SERVER ERROR' }); + } +} + module.exports = { login, tpin, @@ -371,4 +393,6 @@ module.exports = { changeTransPassword, isUserNameExits, setUserName, + getTncAcceptanceFlag, + setTncAcceptanceFlag, }; diff --git a/src/routes/auth.route.js b/src/routes/auth.route.js index c7d2c3a..60511ef 100644 --- a/src/routes/auth.route.js +++ b/src/routes/auth.route.js @@ -28,4 +28,7 @@ router.post( router.get('/user_name', authenticate, authController.isUserNameExits); router.post('/user_name', authenticate, authController.setUserName); +router.get('/tnc', authenticate, authController.getTncAcceptanceFlag); +router.post('/tnc', authenticate, authController.setTncAcceptanceFlag); + module.exports = router; diff --git a/src/services/auth.service.js b/src/services/auth.service.js index 5dd1922..367141f 100644 --- a/src/services/auth.service.js +++ b/src/services/auth.service.js @@ -127,16 +127,16 @@ async function changeTransPassword(customerNo, trans_psw) { async function CheckUserName(customerNo) { try { - const result = await db.query('SELECT preferred_name from users WHERE customer_no = $1', + const result = await db.query( + 'SELECT preferred_name from users WHERE customer_no = $1', [customerNo] ); if (result.rows.length > 0) { - return result.rows[0].preferred_name;; + return result.rows[0].preferred_name; } else { return null; } - } - catch (error) { + } catch (error) { throw new Error( `error occurred while fetch the preferred name ${error.message}` ); @@ -150,12 +150,12 @@ async function setUserName(customerNo, username) { 'UPDATE users SET preferred_name = $1 ,updated_at = $2 WHERE customer_no = $3', [username, currentTime, customerNo] ); - logger.info("user table updated"); + logger.info('user table updated'); await db.query( - "INSERT INTO preferred_name_history (customer_no, preferred_name) VALUES ($1, $2)", + 'INSERT INTO preferred_name_history (customer_no, preferred_name) VALUES ($1, $2)', [customerNo, username] ); - logger.info("preferred_name_history table updated"); + logger.info('preferred_name_history table updated'); } catch (error) { if (error.code === '23505') { throw new Error('PREFERRED_NAME_ALREADY_EXISTS'); @@ -166,6 +166,32 @@ async function setUserName(customerNo, username) { } } +async function getTncFlag(customerNo, clientType) { + let query = ''; + if (clientType === 'MB') { + query = 'SELECT tnc_mobile AS tnc_flag FROM users WHERE customer_no = $1'; + } else if (clientType === 'IB') { + query = 'SELECT tnc_inb AS tnc_flag FROM users WHERE customer_no = $1'; + } else { + throw new Error('UNKNOWN_CLIENT_TYPE. ONLY IB AND MB ALLOWED'); + } + + const result = await db.query(query, [customerNo]); + return result.rows[0]['tnc_flag']; +} + +async function setTncFlag(customerNo, clientType, flag) { + let query = ''; + if (clientType === 'MB') { + query = 'UPDATE users SET tnc_mobile = $1 WHERE customer_no = $2'; + } else if (clientType === 'IB') { + query = 'UPDATE users SET tnc_inb = $1 WHERE customer_no = $2'; + } else { + throw new Error('UNKNOWN_CLIENT_TYPE. ONLY IB AND MB ALLOWED'); + } + await db.query(query, [flag, customerNo]); +} + module.exports = { validateUser, findUserByCustomerNo, @@ -180,5 +206,6 @@ module.exports = { isMigratedUser, CheckUserName, setUserName, - + getTncFlag, + setTncFlag, }; From b9c9d35f7449ee39b0854424876ec85f00f5738c Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 20:27:37 +0530 Subject: [PATCH 09/13] fix: added await in calling set tpin --- src/controllers/auth.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 7299bba..8e1f73e 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -171,7 +171,7 @@ async function setTpin(req, res) { const { tpin } = req.body; if (!/^\d{6}$/.test(tpin)) return res.status(400).json({ error: 'INVALID_TPIN_FORMAT' }); - authService.setTpin(customerNo, tpin); + await authService.setTpin(customerNo, tpin); return res.json({ message: 'TPIN_SET' }); } catch (error) { logger.error(error); From f92217976512ca297b0087c126ead440f0aa0315 Mon Sep 17 00:00:00 2001 From: asif Date: Sat, 8 Nov 2025 20:28:21 +0530 Subject: [PATCH 10/13] fix: change tpin match with hashing and not directly --- src/controllers/auth.controller.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 8e1f73e..2c0c88f 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -187,12 +187,12 @@ async function changeTpin(req, res) { if (!user.tpin) return res.status(400).json({ error: 'USER_DOESNT_HAVE_A_TPIN' }); const { oldTpin, newTpin } = req.body; - if (oldTpin !== user.tpin) - return res.status(400).json({ error: 'TPIN_DOESNT_MATCH' }); + const isMatch = await comparePassword(oldTpin, user.tpin); + if (!isMatch) return res.status(400).json({ error: 'TPIN_DOESNT_MATCH' }); if (!/^\d{6}$/.test(newTpin)) return res.status(400).json({ error: 'INVALID_TPIN_FORMAT' }); - authService.setTpin(customerNo, tpin); + await authService.setTpin(customerNo, newTpin); return res.json({ message: 'TPIN_SET' }); } catch (error) { logger.error(error); From a28c08f8b2e768a03c60ff814be95ea088eb39a1 Mon Sep 17 00:00:00 2001 From: asif Date: Mon, 10 Nov 2025 12:20:04 +0530 Subject: [PATCH 11/13] fix: set tnc accepted api --- src/controllers/auth.controller.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 2c0c88f..6b80029 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -372,9 +372,10 @@ async function getTncAcceptanceFlag(req, res) { async function setTncAcceptanceFlag(req, res) { try { const { flag } = req.body; - if (typeof flag !== 'boolean') - res.staus(400).json({ error: 'invalid value for flag' }); + if (flag !== 'Y' && flag !== 'N') + res.status(400).json({ error: 'invalid value for flag' }); await authService.setTncFlag(req.user, req.client, flag); + return res.json({ message: 'SUCCESS' }); } catch (error) { logger.error(error, 'error occured while updating tnc flag'); res.status(500).json({ error: 'INTERNAL SERVER ERROR' }); From 6b80ef83b405fb7c857f73eb91ece95236e441b7 Mon Sep 17 00:00:00 2001 From: asif Date: Mon, 10 Nov 2025 20:35:41 +0530 Subject: [PATCH 12/13] feat: default password for migrated users --- src/controllers/auth.controller.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 6b80029..c6103d1 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -39,6 +39,9 @@ async function login(req, res) { } const userCheck = await authService.findUserByCustomerNo(customerNo); + if (!userCheck) { + return res.status(404).json({ error: 'customer not found' }); + } if (loginType.toUpperCase() === 'IB') { // check DB locked flag @@ -52,9 +55,13 @@ async function login(req, res) { } // --- Step 2: Check migration status - const isMigratedUser = await authService.isMigratedUser(customerNo); - if (isMigratedUser) + const migratedPassword = `${userCheck.customer_no}@KCCB`; + const isMigratedUser = userCheck.password === migratedPassword; + if (isMigratedUser) { + if (password !== migratedPassword) + return res.status(401).json({ error: 'Invalid credentials.' }); return res.status(401).json({ error: 'MIGRATED_USER_HAS_NO_PASSWORD' }); + } // --- Step 3: Validate credentials --- const user = await authService.validateUser(customerNo, password); From 739f2737ba2c55a2b761081e31b7bdf6e93f4003 Mon Sep 17 00:00:00 2001 From: asif Date: Tue, 11 Nov 2025 01:50:42 +0530 Subject: [PATCH 13/13] fix: migrated users default password --- src/controllers/auth.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index c6103d1..b4222b2 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -56,7 +56,7 @@ async function login(req, res) { // --- Step 2: Check migration status const migratedPassword = `${userCheck.customer_no}@KCCB`; - const isMigratedUser = userCheck.password === migratedPassword; + const isMigratedUser = userCheck.password_hash === migratedPassword; if (isMigratedUser) { if (password !== migratedPassword) return res.status(401).json({ error: 'Invalid credentials.' });