Compare commits
22 Commits
admin_feat
...
fetch-from
| Author | SHA1 | Date | |
|---|---|---|---|
| c94eff28cc | |||
| f81c9c4de1 | |||
| 68d0bf0151 | |||
| fc32e9c785 | |||
| aa755faaa7 | |||
| 785db2c8a4 | |||
| b1cf06ef08 | |||
| 7e852763ff | |||
| c5b5927398 | |||
| c8adc3688a | |||
| 69c5ccba1d | |||
| c3875afbd2 | |||
| 9446abd88b | |||
| 7cf19000d1 | |||
| 61b85abdd1 | |||
| 1e831acfe2 | |||
| bf06706b29 | |||
| a04830cdb2 | |||
| 12f0881c9b | |||
| 4c63ccf3ae | |||
| 60cb0076f1 | |||
| b68c8a08c2 |
@@ -168,6 +168,22 @@ async function tpin(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function transPassword(req, res) {
|
||||||
|
const customerNo = req.user;
|
||||||
|
try {
|
||||||
|
const user = await authService.findUserByCustomerNo(customerNo);
|
||||||
|
if (!user) return res.status(404).json({ message: 'USER_NOT_FOUND' });
|
||||||
|
if (!user.transaction_password) {
|
||||||
|
return res.json({ transPasswordSet: false });
|
||||||
|
} else {
|
||||||
|
return res.json({ transPasswordSet: true });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
logger.error(err, 'error occured while checking transaction password');
|
||||||
|
res.status(500).json({ error: 'something went wrong' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function setTpin(req, res) {
|
async function setTpin(req, res) {
|
||||||
const customerNo = req.user;
|
const customerNo = req.user;
|
||||||
try {
|
try {
|
||||||
@@ -221,12 +237,30 @@ async function setLoginPassword(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setTransactionPassword(req, res) {
|
async function setTransPassword(req, res) {
|
||||||
const customerNo = req.user;
|
const customerNo = req.user;
|
||||||
try {
|
try {
|
||||||
const user = await authService.findUserByCustomerNo(customerNo);
|
const user = await authService.findUserByCustomerNo(customerNo);
|
||||||
if (!user) return res.status(404).json({ error: 'USER_NOT_FOUND' });
|
if (!user) return res.status(404).json({ error: 'USER_NOT_FOUND' });
|
||||||
const { transaction_password } = req.body;
|
const { transaction_password } = req.body;
|
||||||
|
// if (user.transaction_password) {
|
||||||
|
// const isMatchWithOldPassword = await comparePassword(
|
||||||
|
// transaction_password,
|
||||||
|
// user.transaction_password
|
||||||
|
// );
|
||||||
|
// if (isMatchWithOldPassword)
|
||||||
|
// return res.status(500).json({
|
||||||
|
// error: 'New transaction Password will be different from Previous Password',
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
const isMatchWithLoginPassword = await comparePassword(
|
||||||
|
transaction_password,
|
||||||
|
user.password_hash
|
||||||
|
);
|
||||||
|
if (isMatchWithLoginPassword)
|
||||||
|
return res.status(500).json({
|
||||||
|
error: 'New transaction Password will be different from Login Password',
|
||||||
|
});
|
||||||
authService.setTransactionPassword(customerNo, transaction_password);
|
authService.setTransactionPassword(customerNo, transaction_password);
|
||||||
return res.json({ message: 'Transaction Password set' });
|
return res.json({ message: 'Transaction Password set' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -291,6 +325,14 @@ async function changeTransPassword(req, res) {
|
|||||||
error:
|
error:
|
||||||
'New Transaction Password will be different from Previous Transaction Password',
|
'New Transaction Password will be different from Previous Transaction Password',
|
||||||
});
|
});
|
||||||
|
const isMatchWithLoginPassword = await comparePassword(
|
||||||
|
newTPsw,
|
||||||
|
user.password_hash
|
||||||
|
);
|
||||||
|
if (isMatchWithLoginPassword)
|
||||||
|
return res.status(500).json({
|
||||||
|
error: 'New transaction Password will be different from Login Password',
|
||||||
|
});
|
||||||
authService.changeTransPassword(customerNo, newTPsw);
|
authService.changeTransPassword(customerNo, newTPsw);
|
||||||
return res.json({
|
return res.json({
|
||||||
message: 'New Transaction Password changed successfully',
|
message: 'New Transaction Password changed successfully',
|
||||||
@@ -395,7 +437,8 @@ module.exports = {
|
|||||||
setTpin,
|
setTpin,
|
||||||
changeTpin,
|
changeTpin,
|
||||||
setLoginPassword,
|
setLoginPassword,
|
||||||
setTransactionPassword,
|
transPassword,
|
||||||
|
setTransPassword,
|
||||||
fetchUserDetails,
|
fetchUserDetails,
|
||||||
changeLoginPassword,
|
changeLoginPassword,
|
||||||
changeTransPassword,
|
changeTransPassword,
|
||||||
|
|||||||
@@ -50,11 +50,19 @@ async function validateOutsideBank(req, res) {
|
|||||||
|
|
||||||
async function addBeneficiary(req, res) {
|
async function addBeneficiary(req, res) {
|
||||||
try {
|
try {
|
||||||
const { accountNo, ifscCode, accountType, name } = req.body;
|
const { accountNo, ifscCode, accountType, name, transactionLimit } =
|
||||||
|
req.body;
|
||||||
const customerNo = req.user;
|
const customerNo = req.user;
|
||||||
const query =
|
const query =
|
||||||
'INSERT INTO beneficiaries (customer_no, account_no, account_type, ifsc_code, name) VALUES ($1, $2, $3, $4, $5)';
|
'INSERT INTO beneficiaries (customer_no, account_no, account_type, ifsc_code, name, transaction_limit) VALUES ($1, $2, $3, $4, $5, $6)';
|
||||||
await db.query(query, [customerNo, accountNo, accountType, ifscCode, name]);
|
await db.query(query, [
|
||||||
|
customerNo,
|
||||||
|
accountNo,
|
||||||
|
accountType,
|
||||||
|
ifscCode,
|
||||||
|
name,
|
||||||
|
transactionLimit,
|
||||||
|
]);
|
||||||
res.json({ message: 'SUCCESS' });
|
res.json({ message: 'SUCCESS' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error, 'Error adding beneficiary');
|
logger.error(error, 'Error adding beneficiary');
|
||||||
@@ -132,6 +140,45 @@ async function getIfscDetails(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateBeneficiaryLimit(req, res) {
|
||||||
|
const { beneficiaryAccountNo, newLimit } = req.body;
|
||||||
|
|
||||||
|
if (newLimit === undefined) {
|
||||||
|
return res.status(400).json({ error: 'newLimit is required' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof newLimit !== 'number') {
|
||||||
|
return res.status(400).json({ error: 'Limit must be a numeric value' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newLimit < 0 || newLimit > 1000000) {
|
||||||
|
return res
|
||||||
|
.status(400)
|
||||||
|
.json({ error: 'Limit must be between 10 and 1000000' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updatedBeneficiary = await beneficiaryService.updateBeneficiaryLimit(
|
||||||
|
req.user,
|
||||||
|
beneficiaryAccountNo,
|
||||||
|
newLimit
|
||||||
|
);
|
||||||
|
return res.status(200).json({
|
||||||
|
message: `limit for beneficiary ${updatedBeneficiary.account_no} updated successfully to ${updatedBeneficiary.transaction_limit}`,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
if (error.message === 'ACCOUNT_NOT_FOUND') {
|
||||||
|
logger.warn(
|
||||||
|
`beneficiary ${beneficiaryAccountNo} does not exist for the customer ${req.user}`
|
||||||
|
);
|
||||||
|
return res.status(400).json({ error: 'INVALID_BENEFICIARY_ACCOUNT_NO' });
|
||||||
|
} else {
|
||||||
|
logger.error(error, 'error deleting beneficiary');
|
||||||
|
return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function delay(ms) {
|
function delay(ms) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
@@ -171,4 +218,5 @@ module.exports = {
|
|||||||
getIfscDetails,
|
getIfscDetails,
|
||||||
getBeneficiary,
|
getBeneficiary,
|
||||||
deleteBeneficiary,
|
deleteBeneficiary,
|
||||||
|
updateBeneficiaryLimit,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -114,6 +114,12 @@ async function SendOtp(req, res) {
|
|||||||
case 'TLIMIT_SET':
|
case 'TLIMIT_SET':
|
||||||
message = templates.TLIMIT_SET(amount);
|
message = templates.TLIMIT_SET(amount);
|
||||||
break;
|
break;
|
||||||
|
case 'LPWORD_CHANGE':
|
||||||
|
message = templates.LPWORD_CHANGE;
|
||||||
|
break;
|
||||||
|
case 'TPWORD_CHANGE':
|
||||||
|
message = templates.TPWORD_CHANGE;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return res.status(400).json({ error: 'Invalid OTP type' });
|
return res.status(400).json({ error: 'Invalid OTP type' });
|
||||||
}
|
}
|
||||||
@@ -194,6 +200,7 @@ async function sendForSetPassword(req, res) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
await setJson(`otp:${mobileNumber}`, otp, 300);
|
await setJson(`otp:${mobileNumber}`, otp, 300);
|
||||||
|
logger.info(`Sent OTP [${otp}] to ${mobileNumber}`);
|
||||||
return res.status(200).json({ message: 'OTP_SENT' });
|
return res.status(200).json({ message: 'OTP_SENT' });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err, 'Error sending OTP');
|
logger.error(err, 'Error sending OTP');
|
||||||
|
|||||||
33
src/middlewares/beneficiaryLimit.middleware.js
Normal file
33
src/middlewares/beneficiaryLimit.middleware.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
const { getSingleBeneficiary } = require('../services/beneficiary.service');
|
||||||
|
const { getBeneficiaryUsedLimit } = require('../services/paymentLimit.service');
|
||||||
|
const { logger } = require('../util/logger');
|
||||||
|
|
||||||
|
async function checkBeneficiaryLimit(req, res, next) {
|
||||||
|
const { amount, toAccount } = req.body;
|
||||||
|
const { user } = req;
|
||||||
|
const beneficiary = await getSingleBeneficiary(user, toAccount);
|
||||||
|
if (!beneficiary) {
|
||||||
|
return res
|
||||||
|
.status(403)
|
||||||
|
.json({ error: 'No beneficiary added for this account' });
|
||||||
|
}
|
||||||
|
const beneficiaryLimit = beneficiary.transaction_limit;
|
||||||
|
|
||||||
|
if (!beneficiaryLimit) {
|
||||||
|
logger.info('NO LIMIT SET FOR BENEFICIARY. ALLOWING TRANSACTIONS');
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
const usedLimit = await getBeneficiaryUsedLimit(user, toAccount);
|
||||||
|
|
||||||
|
const remainingLimit = beneficiaryLimit - usedLimit;
|
||||||
|
|
||||||
|
if (amount > remainingLimit) {
|
||||||
|
const midnight = new Date();
|
||||||
|
midnight.setHours(24, 0, 0, 0);
|
||||||
|
res.set('Retry-After', midnight.toUTCString());
|
||||||
|
return res.status(403).json({ error: 'Beneficairy limit exhausted' });
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { checkBeneficiaryLimit };
|
||||||
@@ -1,9 +1,18 @@
|
|||||||
const { logger } = require('../util/logger');
|
const { logger } = require('../util/logger');
|
||||||
|
|
||||||
function verifyClient(req, res, next) {
|
function verifyClient(req, res, next) {
|
||||||
|
// console.log('printing headers');
|
||||||
|
// console.log(req.headers);
|
||||||
const clientHeader = req.headers['x-login-type'];
|
const clientHeader = req.headers['x-login-type'];
|
||||||
|
|
||||||
if (!clientHeader || (clientHeader !== 'MB' && clientHeader !== 'IB' && clientHeader !== 'eMandate' && clientHeader !=='Admin')) {
|
if (
|
||||||
|
!clientHeader ||
|
||||||
|
(clientHeader !== 'MB' &&
|
||||||
|
clientHeader !== 'IB' &&
|
||||||
|
clientHeader !== 'NPCI' &&
|
||||||
|
clientHeader !== 'eMandate' &&
|
||||||
|
clientHeader !== 'Admin')
|
||||||
|
) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Invalid or missing client header. Expected 'MB' or 'IB'. Found ${clientHeader}`
|
`Invalid or missing client header. Expected 'MB' or 'IB'. Found ${clientHeader}`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ const router = express.Router();
|
|||||||
router.post('/login', adminAuthController.login);
|
router.post('/login', adminAuthController.login);
|
||||||
router.get('/admin_details', adminAuthenticate, adminAuthController.fetchAdminDetails);
|
router.get('/admin_details', adminAuthenticate, adminAuthController.fetchAdminDetails);
|
||||||
router.get('/fetch/customer_details',adminAuthenticate,adminAuthController.getUserDetails);
|
router.get('/fetch/customer_details',adminAuthenticate,adminAuthController.getUserDetails);
|
||||||
|
|
||||||
|
// User configuration
|
||||||
router.post('/user/rights',adminAuthenticate,adminAuthController.UserRights);
|
router.post('/user/rights',adminAuthenticate,adminAuthController.UserRights);
|
||||||
router.get('/user/rights',adminAuthenticate,adminAuthController.getUserRights);
|
router.get('/user/rights',adminAuthenticate,adminAuthController.getUserRights);
|
||||||
router.post('/user/unlock',adminAuthenticate,adminAuthController.handleUnlockUser);
|
router.post('/user/unlock',adminAuthenticate,adminAuthController.handleUnlockUser);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const router = express.Router();
|
|||||||
|
|
||||||
const atmRoute = async (req, res) => {
|
const atmRoute = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const query_str = 'SELECT * FROM atm';
|
const query_str = 'SELECT * FROM atm_details';
|
||||||
const result = await db.query(query_str);
|
const result = await db.query(query_str);
|
||||||
return res.json(result.rows);
|
return res.json(result.rows);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -6,20 +6,24 @@ const router = express.Router();
|
|||||||
|
|
||||||
router.post('/login', authController.login);
|
router.post('/login', authController.login);
|
||||||
router.get('/user_details', authenticate, authController.fetchUserDetails);
|
router.get('/user_details', authenticate, authController.fetchUserDetails);
|
||||||
|
|
||||||
router.get('/tpin', authenticate, authController.tpin);
|
router.get('/tpin', authenticate, authController.tpin);
|
||||||
router.post('/tpin', authenticate, authController.setTpin);
|
router.post('/tpin', authenticate, authController.setTpin);
|
||||||
router.post('/change/tpin', authenticate, authController.changeTpin);
|
router.post('/change/tpin', authenticate, authController.changeTpin);
|
||||||
|
|
||||||
router.post('/login_password', authenticate, authController.setLoginPassword);
|
router.post('/login_password', authenticate, authController.setLoginPassword);
|
||||||
router.post(
|
|
||||||
'/transaction_password',
|
|
||||||
authenticate,
|
|
||||||
authController.setTransactionPassword
|
|
||||||
);
|
|
||||||
router.post(
|
router.post(
|
||||||
'/change/login_password',
|
'/change/login_password',
|
||||||
authenticate,
|
authenticate,
|
||||||
authController.changeLoginPassword
|
authController.changeLoginPassword
|
||||||
);
|
);
|
||||||
|
|
||||||
|
router.get('/transaction_password', authenticate, authController.transPassword);
|
||||||
|
router.post(
|
||||||
|
'/transaction_password',
|
||||||
|
authenticate,
|
||||||
|
authController.setTransPassword
|
||||||
|
);
|
||||||
router.post(
|
router.post(
|
||||||
'/change/transaction_password',
|
'/change/transaction_password',
|
||||||
authenticate,
|
authenticate,
|
||||||
|
|||||||
@@ -13,5 +13,6 @@ router.delete(
|
|||||||
'/:beneficiaryAccountNo',
|
'/:beneficiaryAccountNo',
|
||||||
beneficiaryController.deleteBeneficiary
|
beneficiaryController.deleteBeneficiary
|
||||||
);
|
);
|
||||||
|
router.patch('/update-limit', beneficiaryController.updateBeneficiaryLimit);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
136
src/routes/cheque.route.js
Normal file
136
src/routes/cheque.route.js
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const { logger } = require('../util/logger');
|
||||||
|
const axios = require('axios');
|
||||||
|
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
||||||
|
|
||||||
|
const chequeEnquiryRoute = async (req, res) => {
|
||||||
|
const { accountNumber, instrumentType } = req.query;
|
||||||
|
if (!accountNumber || !instrumentType) {
|
||||||
|
return res.status(400).json({ error: 'BAD_REQUEST' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get('http://localhost:8444/kccb/cheque', {
|
||||||
|
params: { accountno: accountNumber, instrType: instrumentType },
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.json(response.data);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Unable to fetch cheque data: ', error);
|
||||||
|
return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const chequeStopRoute = async (req, res) => {
|
||||||
|
const {
|
||||||
|
accountNumber,
|
||||||
|
instrumentType,
|
||||||
|
stopFromChequeNo,
|
||||||
|
stopToChequeNo,
|
||||||
|
stopIssueDate,
|
||||||
|
stopExpiryDate,
|
||||||
|
stopAmount,
|
||||||
|
stopComment,
|
||||||
|
chqIssueDate,
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
if (!accountNumber || !instrumentType || !stopFromChequeNo) {
|
||||||
|
console.log('missing');
|
||||||
|
return res.status(400).json({ error: 'BAD_REQUEST' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(
|
||||||
|
'http://localhost:8444/kccb/chequeSetStop',
|
||||||
|
{
|
||||||
|
accountno: accountNumber,
|
||||||
|
stopFromChequeNo: stopFromChequeNo,
|
||||||
|
instrType: instrumentType,
|
||||||
|
stopToChequeNo: stopToChequeNo,
|
||||||
|
stopIssueDate: stopIssueDate,
|
||||||
|
stopExpiryDate: stopExpiryDate,
|
||||||
|
stopAmount: stopAmount,
|
||||||
|
stopComment: stopComment,
|
||||||
|
chqIssueDate: chqIssueDate,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('response from stop cheque api: ', response.data);
|
||||||
|
return res.json(response.data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Unable to fetch cheque data: ', e);
|
||||||
|
if (axios.isAxiosError(e)) {
|
||||||
|
if (e.response) {
|
||||||
|
// Server responded with a status outside 2xx
|
||||||
|
return res.status(e.response.status).json(e.response.data);
|
||||||
|
} else {
|
||||||
|
return res
|
||||||
|
.status(e.response.status)
|
||||||
|
.json({ error: 'UNKNOWN', message: 'NO_RESPONSE_FROM_CBS' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const revokeStop = async (req, res) => {
|
||||||
|
const {
|
||||||
|
accountNumber,
|
||||||
|
instrumentType,
|
||||||
|
removeFromChequeNo,
|
||||||
|
removeToChequeNo,
|
||||||
|
removeIssueDate,
|
||||||
|
removeExpiryDate,
|
||||||
|
removeAmount,
|
||||||
|
removeComment,
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
if (!accountNumber || !instrumentType || !removeFromChequeNo) {
|
||||||
|
console.log('missing');
|
||||||
|
return res.status(400).json({ error: 'BAD_REQUEST' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(
|
||||||
|
'http://localhost:8444/kccb/chequeRemoveStop',
|
||||||
|
{
|
||||||
|
accountno: accountNumber,
|
||||||
|
removeFromChequeNo: removeFromChequeNo,
|
||||||
|
instrType: instrumentType,
|
||||||
|
removeToChequeNo: removeToChequeNo,
|
||||||
|
removeIssueDate: removeIssueDate,
|
||||||
|
removeExpiryDate: removeExpiryDate,
|
||||||
|
removeAmount: removeAmount,
|
||||||
|
removeComment: removeComment,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('response from stop cheque api: ', response.data);
|
||||||
|
return res.json(response.data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Unable to fetch cheque data: ', e);
|
||||||
|
if (axios.isAxiosError(e)) {
|
||||||
|
if (e.response) {
|
||||||
|
// Server responded with a status outside 2xx
|
||||||
|
return res.status(e.response.status).json(e.response.data);
|
||||||
|
} else {
|
||||||
|
return res
|
||||||
|
.status(e.response.status)
|
||||||
|
.json({ error: 'UNKNOWN', message: 'NO_RESPONSE_FROM_CBS' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const enquiryRouter = express.Router();
|
||||||
|
const stopRouter = express.Router();
|
||||||
|
const removeStopRouter = express.Router();
|
||||||
|
const router = express.Router();
|
||||||
|
enquiryRouter.get('/enquiry', chequeEnquiryRoute);
|
||||||
|
stopRouter.use(paymentSecretValidator);
|
||||||
|
stopRouter.post('/stop', chequeStopRoute);
|
||||||
|
removeStopRouter.use(paymentSecretValidator);
|
||||||
|
removeStopRouter.post('/removeStop', revokeStop);
|
||||||
|
router.use(enquiryRouter, stopRouter, removeStopRouter);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -8,13 +8,16 @@ const emandateData = async (req, res) => {
|
|||||||
return res.status(404).json({ error: 'DATA NOT FOUND FROM CLIENT' })
|
return res.status(404).json({ error: 'DATA NOT FOUND FROM CLIENT' })
|
||||||
try {
|
try {
|
||||||
const reqData = { data, mandateRequest, mandateType };
|
const reqData = { data, mandateRequest, mandateType };
|
||||||
|
if (customer_no) {
|
||||||
|
reqData.customer_no = customer_no;
|
||||||
|
}
|
||||||
const response = await axios.post('http://192.168.1.166:9992/kccb/validation', reqData,
|
const response = await axios.post('http://192.168.1.166:9992/kccb/validation', reqData,
|
||||||
{
|
{
|
||||||
headers: { 'Content-Type': 'application/json', },
|
headers: { 'Content-Type': 'application/json', },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
logger.info("Data validate");
|
logger.info(response.data, "Data validate");
|
||||||
return response.data;
|
return res.json({ data: response.data });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error, 'error occured while E-Mandate validation');
|
logger.error(error, 'error occured while E-Mandate validation');
|
||||||
return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ const { logger } = require('../util/logger');
|
|||||||
const impsValidator = require('../validators/imps.validator');
|
const impsValidator = require('../validators/imps.validator');
|
||||||
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
||||||
const { checkLimit } = require('../middlewares/limitCheck.middleware');
|
const { checkLimit } = require('../middlewares/limitCheck.middleware');
|
||||||
|
const {
|
||||||
|
checkBeneficiaryLimit,
|
||||||
|
} = require('../middlewares/beneficiaryLimit.middleware');
|
||||||
const {
|
const {
|
||||||
checkBeneficiaryCooldown,
|
checkBeneficiaryCooldown,
|
||||||
} = require('../middlewares/cooldown.middleware');
|
} = require('../middlewares/cooldown.middleware');
|
||||||
@@ -13,7 +16,8 @@ router.use(
|
|||||||
impsValidator,
|
impsValidator,
|
||||||
paymentSecretValidator,
|
paymentSecretValidator,
|
||||||
checkLimit,
|
checkLimit,
|
||||||
checkBeneficiaryCooldown
|
checkBeneficiaryCooldown,
|
||||||
|
checkBeneficiaryLimit
|
||||||
);
|
);
|
||||||
|
|
||||||
const impsRoute = async (req, res) => {
|
const impsRoute = async (req, res) => {
|
||||||
|
|||||||
@@ -13,17 +13,18 @@ const impsRoute = require('./imps.route');
|
|||||||
const branchRoute = require('./branch.route');
|
const branchRoute = require('./branch.route');
|
||||||
const atmRoute = require('./atm.route');
|
const atmRoute = require('./atm.route');
|
||||||
const { npciResponse } = require('../controllers/npci.controller');
|
const { npciResponse } = require('../controllers/npci.controller');
|
||||||
|
const {
|
||||||
|
simDetailsResponse,
|
||||||
|
simDetailsRequest,
|
||||||
|
} = require('./sim_verfify.route.js');
|
||||||
const otp = require('./otp.route');
|
const otp = require('./otp.route');
|
||||||
<<<<<<< HEAD
|
|
||||||
const reports = require('./report.route');
|
const reports = require('./report.route');
|
||||||
|
|
||||||
=======
|
|
||||||
const eMandate = require('./emandate.route');
|
const eMandate = require('./emandate.route');
|
||||||
>>>>>>> 7e162e741d4d126fd029b1875bd5e4e0d3c460cf
|
const chequeRoute = require('./cheque.route');
|
||||||
|
const ppsRoute = require('./positive_pay.route');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.use('/auth', authRoute);
|
router.use('/auth', authRoute);
|
||||||
router.use('/auth/admin', adminAuthRoute);
|
|
||||||
router.use('/customer', authenticate, detailsRoute);
|
router.use('/customer', authenticate, detailsRoute);
|
||||||
router.use('/transactions/account/:accountNo', authenticate, transactionRoute);
|
router.use('/transactions/account/:accountNo', authenticate, transactionRoute);
|
||||||
router.use('/payment/transfer', authenticate, transferRoute);
|
router.use('/payment/transfer', authenticate, transferRoute);
|
||||||
@@ -32,10 +33,19 @@ router.use('/payment/rtgs', authenticate, rtgsRoute);
|
|||||||
router.use('/payment/imps', authenticate, impsRoute);
|
router.use('/payment/imps', authenticate, impsRoute);
|
||||||
router.use('/beneficiary', authenticate, beneficiaryRoute);
|
router.use('/beneficiary', authenticate, beneficiaryRoute);
|
||||||
router.use('/npci/beneficiary-response', npciResponse);
|
router.use('/npci/beneficiary-response', npciResponse);
|
||||||
router.use('/report',adminAuthenticate,reports);
|
|
||||||
router.use('/otp', otp);
|
|
||||||
router.use('/e-mandate', authenticate, eMandate);
|
router.use('/e-mandate', authenticate, eMandate);
|
||||||
router.use('/branch', authenticate, branchRoute);
|
router.use('/branch', authenticate, branchRoute);
|
||||||
router.use('/atm', authenticate, atmRoute);
|
router.use('/atm', authenticate, atmRoute);
|
||||||
|
router.use('/cheque', authenticate, chequeRoute);
|
||||||
|
router.use('/pps', authenticate, ppsRoute);
|
||||||
|
|
||||||
|
// OTP
|
||||||
|
router.use('/otp', otp);
|
||||||
|
|
||||||
|
// Admin APIs
|
||||||
|
router.use('/auth/admin', adminAuthRoute);
|
||||||
|
router.use('/report', adminAuthenticate, reports);
|
||||||
|
router.post('/sim-details', simDetailsResponse);
|
||||||
|
router.post('/sim-details-verify', simDetailsRequest);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ const { logger } = require('../util/logger');
|
|||||||
const neftValidator = require('../validators/neft.validator.js');
|
const neftValidator = require('../validators/neft.validator.js');
|
||||||
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
||||||
const { checkLimit } = require('../middlewares/limitCheck.middleware');
|
const { checkLimit } = require('../middlewares/limitCheck.middleware');
|
||||||
|
const {
|
||||||
|
checkBeneficiaryLimit,
|
||||||
|
} = require('../middlewares/beneficiaryLimit.middleware');
|
||||||
const {
|
const {
|
||||||
checkBeneficiaryCooldown,
|
checkBeneficiaryCooldown,
|
||||||
} = require('../middlewares/cooldown.middleware');
|
} = require('../middlewares/cooldown.middleware');
|
||||||
@@ -13,7 +16,8 @@ router.use(
|
|||||||
neftValidator,
|
neftValidator,
|
||||||
paymentSecretValidator,
|
paymentSecretValidator,
|
||||||
checkLimit,
|
checkLimit,
|
||||||
checkBeneficiaryCooldown
|
checkBeneficiaryCooldown,
|
||||||
|
checkBeneficiaryLimit
|
||||||
);
|
);
|
||||||
|
|
||||||
const neftRoute = async (req, res) => {
|
const neftRoute = async (req, res) => {
|
||||||
|
|||||||
51
src/routes/positive_pay.route.js
Normal file
51
src/routes/positive_pay.route.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const { logger } = require('../util/logger');
|
||||||
|
const axios = require('axios');
|
||||||
|
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
||||||
|
|
||||||
|
const ppsRegisterRoute = async (req, res) => {
|
||||||
|
console.log('hit pps');
|
||||||
|
const { cheque_no, account_number, issue_date, amount, payee_name } =
|
||||||
|
req.body;
|
||||||
|
console.log(cheque_no, account_number, issue_date, amount, payee_name);
|
||||||
|
|
||||||
|
if (!account_number || !cheque_no) {
|
||||||
|
console.log('missing');
|
||||||
|
return res.status(400).json({ error: 'BAD_REQUEST' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(
|
||||||
|
'http://localhost:8989/api/pps/register',
|
||||||
|
{
|
||||||
|
cheque_no: cheque_no,
|
||||||
|
account_number: account_number,
|
||||||
|
issue_date: issue_date,
|
||||||
|
amount: amount,
|
||||||
|
payee_name: payee_name,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('response from pps register: ', response.data);
|
||||||
|
return res.json(response.data);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Unable to fetch cheque data: ', e);
|
||||||
|
if (axios.isAxiosError(e)) {
|
||||||
|
if (e.response) {
|
||||||
|
// Server responded with a status outside 2xx
|
||||||
|
return res.status(e.response.status).json(e.response.data);
|
||||||
|
} else {
|
||||||
|
return res
|
||||||
|
.status(e.response.status)
|
||||||
|
.json({ error: 'UNKNOWN', message: 'NO_RESPONSE_FROM_CBS' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
router.use(paymentSecretValidator);
|
||||||
|
router.post('/', ppsRegisterRoute);
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -4,6 +4,9 @@ const { logger } = require('../util/logger');
|
|||||||
const rtgsValidator = require('../validators/rtgs.validator.js');
|
const rtgsValidator = require('../validators/rtgs.validator.js');
|
||||||
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
const paymentSecretValidator = require('../validators/payment.secret.validator');
|
||||||
const { checkLimit } = require('../middlewares/limitCheck.middleware');
|
const { checkLimit } = require('../middlewares/limitCheck.middleware');
|
||||||
|
const {
|
||||||
|
checkBeneficiaryLimit,
|
||||||
|
} = require('../middlewares/beneficiaryLimit.middleware');
|
||||||
const {
|
const {
|
||||||
checkBeneficiaryCooldown,
|
checkBeneficiaryCooldown,
|
||||||
} = require('../middlewares/cooldown.middleware');
|
} = require('../middlewares/cooldown.middleware');
|
||||||
@@ -13,7 +16,8 @@ router.use(
|
|||||||
rtgsValidator,
|
rtgsValidator,
|
||||||
paymentSecretValidator,
|
paymentSecretValidator,
|
||||||
checkLimit,
|
checkLimit,
|
||||||
checkBeneficiaryCooldown
|
checkBeneficiaryCooldown,
|
||||||
|
checkBeneficiaryLimit
|
||||||
);
|
);
|
||||||
|
|
||||||
const rtgsRoute = async (req, res) => {
|
const rtgsRoute = async (req, res) => {
|
||||||
|
|||||||
69
src/routes/sim_verfify.route.js
Normal file
69
src/routes/sim_verfify.route.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
const db = require('../config/db');
|
||||||
|
const { getJson, setJson } = require('../config/redis');
|
||||||
|
const { logger } = require('../util/logger');
|
||||||
|
const customerController = require('../controllers/customer_details.controller');
|
||||||
|
|
||||||
|
async function simDetailsResponse(req, res) {
|
||||||
|
const { phoneNo, uuid } = req.body;
|
||||||
|
try {
|
||||||
|
console.log(`phone no from sms: ${phoneNo}`);
|
||||||
|
console.log(`message body from sms: ${uuid}`);
|
||||||
|
await setJson(uuid, phoneNo);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error, 'error processing sim details response');
|
||||||
|
}
|
||||||
|
res.json({ message: 'OK' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function simDetailsRequest(req, res) {
|
||||||
|
const { cifNo, uuid } = req.body;
|
||||||
|
try {
|
||||||
|
const customerDetails = await customerController.getDetails(cifNo);
|
||||||
|
const phoneNo = customerDetails[0].mobileno?.slice(-10);
|
||||||
|
const phoneNoFromVendor = await pollRedisKey(uuid);
|
||||||
|
if (!phoneNoFromVendor) {
|
||||||
|
return res.json({ error: 'Could not verify phone number' });
|
||||||
|
}
|
||||||
|
const strippedPhoneNo = phoneNoFromVendor.slice(-10);
|
||||||
|
console.log('phone no from CBS: ', phoneNo);
|
||||||
|
console.log('phone no from SIM: ', strippedPhoneNo);
|
||||||
|
if (phoneNo === strippedPhoneNo) {
|
||||||
|
return res.json({ status: 'VERIFIED' });
|
||||||
|
}
|
||||||
|
return res.json({ status: 'NOT_VERIFIED' });
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error, 'sim verification failed');
|
||||||
|
res.status(500).json({ error: 'SIM verification failed' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pollRedisKey(key) {
|
||||||
|
const timeout = 2 * 60 * 1000;
|
||||||
|
const interval = 2000;
|
||||||
|
const startTime = Date.now();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const poll = async () => {
|
||||||
|
try {
|
||||||
|
const phoneNo = await getJson(key);
|
||||||
|
if (phoneNo !== null) {
|
||||||
|
console.log(phoneNo, 'payload from redis');
|
||||||
|
return resolve(phoneNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Date.now() - startTime >= timeout) {
|
||||||
|
return resolve(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('not found retrying for uuid');
|
||||||
|
|
||||||
|
setTimeout(poll, interval);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
poll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
module.exports = { simDetailsResponse, simDetailsRequest };
|
||||||
@@ -36,7 +36,7 @@ async function validateOutsideBank(accountNo, ifscCode, name) {
|
|||||||
|
|
||||||
async function getSingleBeneficiary(customerNo, accountNo) {
|
async function getSingleBeneficiary(customerNo, accountNo) {
|
||||||
const queryStr =
|
const queryStr =
|
||||||
'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';
|
'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, b.created_at, b.transaction_limit, 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]);
|
const result = await db.query(queryStr, [customerNo, accountNo]);
|
||||||
return result.rows[0];
|
return result.rows[0];
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ async function deleteBeneficiary(customerNo, beneficiaryAccountNo) {
|
|||||||
|
|
||||||
async function getAllBeneficiaries(customerNo) {
|
async function getAllBeneficiaries(customerNo) {
|
||||||
const queryStr =
|
const queryStr =
|
||||||
'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';
|
'SELECT b.account_no, b.name, b.account_type, b.ifsc_code, b.created_at, b.transaction_limit, 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 result = await db.query(queryStr, [customerNo]);
|
||||||
const list = result.rows.map((row) => {
|
const list = result.rows.map((row) => {
|
||||||
const details = {
|
const details = {
|
||||||
@@ -61,6 +61,7 @@ async function getAllBeneficiaries(customerNo) {
|
|||||||
name: row['name'],
|
name: row['name'],
|
||||||
accountType: row['account_type'],
|
accountType: row['account_type'],
|
||||||
createdAt: row['created_at'],
|
createdAt: row['created_at'],
|
||||||
|
transactionLimit: row['transaction_limit'],
|
||||||
};
|
};
|
||||||
if (row['ifsc_code'] === '_') {
|
if (row['ifsc_code'] === '_') {
|
||||||
details['bankName'] = 'THE KANGRA CENTRAL COOPERATIVE BANK LIMITED';
|
details['bankName'] = 'THE KANGRA CENTRAL COOPERATIVE BANK LIMITED';
|
||||||
@@ -74,10 +75,29 @@ async function getAllBeneficiaries(customerNo) {
|
|||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateBeneficiaryLimit(
|
||||||
|
customerNo,
|
||||||
|
beneficiaryAccountNo,
|
||||||
|
newLimit
|
||||||
|
) {
|
||||||
|
const queryStr =
|
||||||
|
'UPDATE beneficiaries set transaction_limit = $1 WHERE customer_no = $2 AND account_no = $3 RETURNING *';
|
||||||
|
const result = await db.query(queryStr, [
|
||||||
|
newLimit,
|
||||||
|
customerNo,
|
||||||
|
beneficiaryAccountNo,
|
||||||
|
]);
|
||||||
|
if (result.rowCount == 0) {
|
||||||
|
throw new Error('ACCOUNT_NOT_FOUND');
|
||||||
|
}
|
||||||
|
return result.rows[0];
|
||||||
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
validateWithinBank,
|
validateWithinBank,
|
||||||
validateOutsideBank,
|
validateOutsideBank,
|
||||||
getAllBeneficiaries,
|
getAllBeneficiaries,
|
||||||
getSingleBeneficiary,
|
getSingleBeneficiary,
|
||||||
deleteBeneficiary,
|
deleteBeneficiary,
|
||||||
|
updateBeneficiaryLimit,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ async function getUsedLimit(customerNo, clientType) {
|
|||||||
return Number(usedLimit);
|
return Number(usedLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getBeneficiaryUsedLimit(customerNo, beneficiaryAccountNo) {
|
||||||
|
const query =
|
||||||
|
"SELECT SUM(amount::numeric) AS used_limit FROM transactions WHERE created_at BETWEEN CURRENT_DATE AND (CURRENT_DATE + INTERVAL '1 day') AND customer_no = $1 AND to_account = $2";
|
||||||
|
const result = await db.query(query, [customerNo, beneficiaryAccountNo]);
|
||||||
|
const usedLimit = result.rows[0].used_limit;
|
||||||
|
return Number(usedLimit);
|
||||||
|
}
|
||||||
|
|
||||||
async function setDailyLimit(customerNo, clientType, amount) {
|
async function setDailyLimit(customerNo, clientType, amount) {
|
||||||
let query = '';
|
let query = '';
|
||||||
if (clientType === 'IB') {
|
if (clientType === 'IB') {
|
||||||
@@ -35,4 +43,9 @@ async function setDailyLimit(customerNo, clientType, amount) {
|
|||||||
logger.info(`set new limit: ${result.rowCount} rows affected`);
|
logger.info(`set new limit: ${result.rowCount} rows affected`);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getDailyLimit, getUsedLimit, setDailyLimit };
|
module.exports = {
|
||||||
|
getDailyLimit,
|
||||||
|
getUsedLimit,
|
||||||
|
setDailyLimit,
|
||||||
|
getBeneficiaryUsedLimit,
|
||||||
|
};
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ const templates = {
|
|||||||
|
|
||||||
TLIMIT_SET: (amount) =>
|
TLIMIT_SET: (amount) =>
|
||||||
`Dear Customer,Your transaction limit for Internet Banking is set to Rs ${amount}. -KCCB`,
|
`Dear Customer,Your transaction limit for Internet Banking is set to Rs ${amount}. -KCCB`,
|
||||||
|
|
||||||
|
LPWORD_CHANGE:
|
||||||
|
`Dear Customer, Your Login password has been successfully updated. If you did not initiate this, please contact your nearest branch immediately. -KCCB`,
|
||||||
|
|
||||||
|
TPWORD_CHANGE:
|
||||||
|
`Dear Customer, Your transaction password has been successfully updated. If you did not initiate this, please contact your nearest branch immediately. -KCCB`,
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = templates;
|
module.exports = templates;
|
||||||
Reference in New Issue
Block a user