diff --git a/server/v1/app.js b/server/v1/app.js index e06d89b..9184e36 100644 --- a/server/v1/app.js +++ b/server/v1/app.js @@ -5,7 +5,6 @@ import debug from 'debug'; import swaggerUi from 'swagger-ui-express'; import swaggerDocument from '../swagger'; import RegisterRoute from './routes/register'; -import CreateStaffRoute from './routes/createStaffs'; import LoginRoute from './routes/login'; import CreateAccountRoute from './routes/createAccount'; import TransactionRoute from './routes/transaction'; @@ -32,7 +31,6 @@ app.get('/', (req, res) => { // creating the api version route app.use('/api/auth/signup', RegisterRoute); app.use('/api/auth/signin', LoginRoute); -app.use('/api/auth/addstaff', jwtMiddleware.checkToken, CreateStaffRoute); app.use('/api/v1/accounts', jwtMiddleware.checkToken, CreateAccountRoute); app.use('/api/v1/transactions', jwtMiddleware.checkToken, TransactionRoute); app.use('/api/v1/users', jwtMiddleware.checkToken, UsersRoute); diff --git a/server/v1/controllers/createAccount.js b/server/v1/controllers/createAccount.js index a48ffcb..058e19c 100644 --- a/server/v1/controllers/createAccount.js +++ b/server/v1/controllers/createAccount.js @@ -1,14 +1,15 @@ import CreateAccountService from '../services/createAccount'; +import statusHelper from '../helper/statusHelper'; const CreateAccountController = { async createAccount(req, res) { const accountData = req.body; const createdAccount = await CreateAccountService .createAccount(accountData, req.authorizedData); - return res.json({ - status: 'success', - data: createdAccount, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, createdAccount.returnStatus, createdAccount.returnError, createdAccount.returnSuccess); + return data; }, // all accounts @@ -16,10 +17,10 @@ const CreateAccountController = { const queryParams = req.query.status; const allAccounts = await CreateAccountService .allAccounts(queryParams); - return res.json({ - status: 'success', - data: allAccounts, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, allAccounts.returnStatus, allAccounts.returnError, allAccounts.returnSuccess); + return data; }, // specific account @@ -27,10 +28,10 @@ const CreateAccountController = { const { accountNumber } = req.params; const specificAccounts = await CreateAccountService .specificAccounts(accountNumber); - return res.json({ - status: 'success', - data: specificAccounts, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, specificAccounts.returnStatus, specificAccounts.returnError, specificAccounts.returnSuccess); + return data; }, // get transaction history @@ -38,10 +39,10 @@ const CreateAccountController = { const { accountNumber } = req.params; const transactionHistory = await CreateAccountService .allAccountTransaction(accountNumber); - return res.json({ - status: 'success', - data: transactionHistory, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, transactionHistory.returnStatus, transactionHistory.returnError, transactionHistory.returnSuccess); + return data; }, // patchAccount @@ -50,10 +51,10 @@ const CreateAccountController = { const accountStatus = req.body; const updatedAccount = await CreateAccountService .patchAccount(accountNumber, accountStatus, req.authorizedData); - return res.json({ - status: 'success', - data: updatedAccount, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, updatedAccount.returnStatus, updatedAccount.returnError, updatedAccount.returnSuccess); + return data; }, // deleteAccount @@ -61,10 +62,10 @@ const CreateAccountController = { const { accountNumber } = req.params; const deleteAccount = await CreateAccountService .deleteAccount(accountNumber, req.authorizedData); - return res.json({ - status: 'success', - data: deleteAccount, - }).status(200); + + const data = await statusHelper + .statusHelper('nothing', res, deleteAccount.returnStatus, deleteAccount.returnError, deleteAccount.returnSuccess); + return data; }, }; diff --git a/server/v1/controllers/createStaffs.js b/server/v1/controllers/createStaffs.js deleted file mode 100644 index 67bf47f..0000000 --- a/server/v1/controllers/createStaffs.js +++ /dev/null @@ -1,16 +0,0 @@ -import CreateStaffService from '../services/createStaffs'; - -const CreateStaffController = { - createStaff(req, res) { - const userData = req.body; - // eslint-disable-next-line no-unused-expressions - const createdStaff = CreateStaffService - .createStaffUser(userData, req.authorizedData); - return res.json({ - status: 'success', - data: createdStaff, - }).status(201); - }, -}; - -export default CreateStaffController; diff --git a/server/v1/controllers/login.js b/server/v1/controllers/login.js index 99e72bf..3d571c7 100644 --- a/server/v1/controllers/login.js +++ b/server/v1/controllers/login.js @@ -1,14 +1,14 @@ import LoginService from '../services/login'; +import statusHelper from '../helper/statusHelper'; const LoginController = { async loginUser(req, res) { const userData = req.body; + const loggedUser = await LoginService.loginUser(userData, req.signintoken); - const loggedUser = await LoginService.loginUser(userData, req.token); - res.json({ - status: 'success', - data: loggedUser, - }).status(201); + const data = await statusHelper + .statusHelper('nothing', res, loggedUser.returnStatus, loggedUser.returnError, loggedUser.returnSuccess); + return data; }, }; diff --git a/server/v1/controllers/register.js b/server/v1/controllers/register.js index ec7913e..955daa5 100644 --- a/server/v1/controllers/register.js +++ b/server/v1/controllers/register.js @@ -1,14 +1,24 @@ import RegisterService from '../services/register'; +import statusHelper from '../helper/statusHelper'; const RegisterController = { async registerUser(req, res) { const userData = req.body; + const createdUser = await RegisterService.registerUser(userData, req.signintoken); - const createdUser = await RegisterService.registerUser(userData, req.token); - return res.json({ - status: 'success', - data: createdUser, - }).status(201); + const data = await statusHelper + .statusHelper('nothing', res, createdUser.returnStatus, createdUser.returnError, createdUser.returnSuccess); + return data; + }, + + async createStaffs(req, res) { + const userData = req.body; + const createdStaff = await RegisterService + .createStaffs(userData, req.signintoken, req.authorizedData); + + const data = await statusHelper + .statusHelper('nothing', res, createdStaff.returnStatus, createdStaff.returnError, createdStaff.returnSuccess); + return data; }, }; diff --git a/server/v1/controllers/transaction.js b/server/v1/controllers/transaction.js index 693c0f7..11eb56d 100644 --- a/server/v1/controllers/transaction.js +++ b/server/v1/controllers/transaction.js @@ -1,5 +1,6 @@ /* eslint-disable consistent-return */ import TransactionService from '../services/transaction'; +import statusHelper from '../helper/statusHelper'; const TransactionController = { async debitTransaction(req, res) { @@ -7,20 +8,20 @@ const TransactionController = { const transactionData = req.body; const debitedData = await TransactionService .debitTransaction(accountNumber, req.authorizedData, transactionData); - return res.json({ - status: 'success', - data: debitedData, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, debitedData.returnStatus, debitedData.returnError, debitedData.returnSuccess); + return data; }, async getSpecificTransaction(req, res) { const { transactionid } = req.params; const getTransaction = await TransactionService .getSpecificTransaction(transactionid); - return res.json({ - status: 'success', - data: getTransaction, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, getTransaction.returnStatus, getTransaction.returnError, getTransaction.returnSuccess); + return data; }, async creditTransaction(req, res) { @@ -28,10 +29,10 @@ const TransactionController = { const transactionData = req.body; const creditedData = await TransactionService .creditTransaction(accountNumber, req.authorizedData, transactionData); - return res.json({ - status: 'success', - data: creditedData, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, creditedData.returnStatus, creditedData.returnError, creditedData.returnSuccess); + return data; }, }; diff --git a/server/v1/controllers/users.js b/server/v1/controllers/users.js index 98d0dbd..9f04115 100644 --- a/server/v1/controllers/users.js +++ b/server/v1/controllers/users.js @@ -1,30 +1,31 @@ import UserService from '../services/users'; +import statusHelper from '../helper/statusHelper'; const UsersController = { async getAllUsers(req, res) { const allUsers = await UserService.getAllUsers(req.authorizedData); - return res.json({ - status: 'success', - data: allUsers, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, allUsers.returnStatus, allUsers.returnError, allUsers.returnSuccess); + return data; }, async getUsersAccounts(req, res) { const { email } = req.params; const getUsersAccounts = await UserService.getUsersAccounts(email); - return res.json({ - status: 'success', - data: getUsersAccounts, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, getUsersAccounts.returnStatus, getUsersAccounts.returnError, getUsersAccounts.returnSuccess); + return data; }, async deleteUser(req, res) { const { id } = req.params; const deleteUser = await UserService.deleteUser(id, req.authorizedData); - return res.json({ - status: 'success', - data: deleteUser, - }).status(201); + + const data = await statusHelper + .statusHelper('nothing', res, deleteUser.returnStatus, deleteUser.returnError, deleteUser.returnSuccess); + return data; }, }; diff --git a/server/v1/helper/statusHelper.js b/server/v1/helper/statusHelper.js new file mode 100644 index 0000000..ddd8cad --- /dev/null +++ b/server/v1/helper/statusHelper.js @@ -0,0 +1,56 @@ +/* eslint-disable no-else-return */ +const statusHelper = { + async statusHelper(req, res, status, error, data) { + if (status === 401) { // unauthorized + res.status(401); + return res.json({ + status: 401, + data: error, + }); + } else if (status === 500) { // internal error + res.status(500); + return res.json({ + status: 500, + data: 'Internal Server Error', + }); + } else if (status === 409) { // conflict + res.status(409); + return res.json({ + status: 409, + data: error, + }); + } else if (status === 201) { // created + res.status(201); + return res.json({ + status: 201, + data, + }); + } else if (status === 200) { // success + res.status(200); + return res.json({ + status: 200, + data, + }); + } else if (status === 404) { // not found + res.status(404); + return res.json({ + status: 404, + data: error, + }); + } else if (status === 204) { // no content + res.status(204); + return res.json({ + status: 204, + data: error, + }); + } else if (status === 422) { + res.status(422); + return res.json({ // unprocessable entity + status: 422, + data: error, + }); + } + }, +}; + +export default statusHelper; diff --git a/server/v1/middleware/jwt.js b/server/v1/middleware/jwt.js index 28b4dac..bf875df 100644 --- a/server/v1/middleware/jwt.js +++ b/server/v1/middleware/jwt.js @@ -16,21 +16,21 @@ const jwtMiddleware = { res.sendStatus(403); } }, - verifyJwt(req, res, next) { - jwt.verify(req.token, process.env.JWTSECRETKEY, (err, authorizedData) => { + signinJwt(req, res, next) { + jwt.sign(req.body, process.env.JWTSECRETKEY, async (err, token) => { if (err) { return res.sendStatus(403); } - req.authorizedData = authorizedData; + req.signintoken = token; return next(); }); }, - signinJwt(req, res, next) { - jwt.sign(req.body, process.env.JWTSECRETKEY, async (err, token) => { + verifyJwt(req, res, next) { + jwt.verify(req.token, process.env.JWTSECRETKEY, (err, authorizedData) => { if (err) { return res.sendStatus(403); } - req.token = token; + req.authorizedData = authorizedData; return next(); }); }, diff --git a/server/v1/routes/createStaffs.js b/server/v1/routes/createStaffs.js deleted file mode 100644 index 5a7ed84..0000000 --- a/server/v1/routes/createStaffs.js +++ /dev/null @@ -1,10 +0,0 @@ -import express from 'express'; -import jwtMiddleware from '../middleware/jwt'; -import CreateStaffController from '../controllers/createStaffs'; - -const router = express.Router(); - -// creating our routes -router.post('/', jwtMiddleware.verifyJwt, CreateStaffController.createStaff); - -export default router; diff --git a/server/v1/routes/register.js b/server/v1/routes/register.js index eb5bf6a..ab9b7c4 100644 --- a/server/v1/routes/register.js +++ b/server/v1/routes/register.js @@ -6,5 +6,6 @@ const router = express.Router(); // creating our routes router.post('/', jwtMiddleware.signinJwt, RegisterController.registerUser); +router.post('/addstaff', jwtMiddleware.checkToken, jwtMiddleware.signinJwt, jwtMiddleware.verifyJwt, RegisterController.createStaffs); export default router; diff --git a/server/v1/services/createAccount.js b/server/v1/services/createAccount.js index 6cba5ae..7fc6b3e 100644 --- a/server/v1/services/createAccount.js +++ b/server/v1/services/createAccount.js @@ -4,12 +4,12 @@ import AccountModel from '../model/CreateAccount'; const CreateAccountService = { async createAccount(accountData, userData) { + let returnStatus; let returnSuccess = ''; let returnError = ''; const accountNumberGenerator = Math.floor(Math.random() * 1000000000) + 3000000000; const date = new Date(); const createdOn = `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`; const balance = 0.00; const status = 'active'; - let accountOutput; // pulling users data from database const userDetails = await dbConnection @@ -32,49 +32,85 @@ const CreateAccountService = { account.type = accountDbData.rows[0].type; account.status = accountDbData.rows[0].status; account.balance = accountDbData.rows[0].balance; - accountOutput = account; + returnStatus = 201; + returnSuccess = account; } } else { - accountOutput = 'account type can either be savings or current'; + returnStatus = 422; + returnError = 'account type can either be savings or current'; } - return accountOutput; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async allAccounts(queryParams) { + let returnStatus; let returnSuccess = ''; let returnError = ''; if (typeof queryParams === 'undefined' || queryParams === null) { const allAccounts = await dbConnection .dbConnect('SELECT * from accounts'); - return allAccounts.rows; - } - const allAccounts = await dbConnection - .dbConnect('SELECT * from accounts WHERE status=$1', [queryParams]); - if (allAccounts.rows.length > 0) { - return allAccounts.rows; + returnStatus = 200; + returnSuccess = allAccounts.rows; + } else { + const allAccounts = await dbConnection + .dbConnect('SELECT * from accounts WHERE status=$1', [queryParams]); + if (allAccounts.rows.length > 0) { + returnStatus = 200; + returnSuccess = allAccounts.rows; + } else { + returnStatus = 404; + returnError = 'no account found for this user'; + } } - return 'no account found'; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async specificAccounts(accountNumber) { + let returnStatus; let returnSuccess = ''; let returnError = ''; const userAccount = await dbConnection .dbConnect('SELECT * from accounts WHERE accountnumber=$1', [accountNumber]); if (userAccount.rows.length > 0) { - return userAccount.rows[0]; + returnStatus = 200; + // eslint-disable-next-line prefer-destructuring + returnSuccess = userAccount.rows[0]; + } else { + returnStatus = 404; + returnError = 'no transaction found'; } - return 'no transaction found'; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async allAccountTransaction(accountNumber) { + let returnStatus; let returnSuccess = ''; let returnError = ''; const userTransaction = await dbConnection .dbConnect('SELECT * from transactions WHERE accountnumber=$1', [accountNumber]); if (userTransaction.rows.length > 0) { - return userTransaction.rows; + returnStatus = 200; + returnSuccess = userTransaction.rows; + } else { + returnStatus = 404; + returnError = 'no transaction found'; } - return 'no transaction found'; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async patchAccount(accountNumber, accountUpdate, staff) { - let account; + let returnStatus; let returnSuccess = ''; let returnError = ''; // pulling users data from database const userDetails = await dbConnection @@ -91,19 +127,26 @@ const CreateAccountService = { if (updateAccount.command === 'UPDATE') { const userDbData = await dbConnection.dbConnect('SELECT accountnumber, status FROM accounts WHERE accountnumber=$1', [accountNumber]); const { accountnumber, status } = userDbData.rows[0]; - account = { accountnumber, status }; + returnStatus = 200; + returnSuccess = { accountnumber, status }; } else { - account = 'Something wrong happened'; + returnStatus = 500; } } } else { - account = 'Sorry you don\'t have permission to perform this task'; + returnStatus = 401; + returnError = 'Sorry you don\'t have permission to perform this task'; } - return account; + + return { + returnStatus, + returnSuccess, + returnError, + }; }, async deleteAccount(accountNumber, staff) { - let account; + let returnStatus; let returnSuccess = ''; let returnError = ''; const userDetails = await dbConnection .dbConnect('SELECT type, isadmin FROM users WHERE email=$1', [staff.email]); @@ -115,14 +158,23 @@ const CreateAccountService = { if (checkAccount.rows.length > 0) { const accountDbData = await dbConnection .dbConnect('DELETE FROM accounts WHERE accountnumber=$1', [accountNumber]); - if (accountDbData.command === 'DELETE') account = 'Account successfully deleted'; + if (accountDbData.command === 'DELETE') { + returnStatus = 204; + returnSuccess = 'Account successfully deleted'; + } } else { - account = 'no account found'; + returnStatus = 404; + returnError = 'no account found'; } } else { - account = 'Sorry you don\'t have permission to perform this task'; + returnStatus = 401; + returnError = 'Sorry you don\'t have permission to perform this task'; } - return account; + return { + returnStatus, + returnSuccess, + returnError, + }; }, }; diff --git a/server/v1/services/createStaffs.js b/server/v1/services/createStaffs.js deleted file mode 100644 index 256e977..0000000 --- a/server/v1/services/createStaffs.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable no-param-reassign */ -import usersData from '../../dummyJson/users'; -import registrationHelper from '../helper/registrationHelper'; - -const { users } = usersData; - -const CreateStaffService = { - createStaffUser(userData, admin) { - const returnData = registrationHelper.registrationHelper(users, userData); - let returnValue; - // eslint-disable-next-line max-len - if (returnData[0] === true && returnData[1] === true && returnData[2] === true && returnData[3] === true) { - if (admin.loggedUser.isAdmin === true) { - userData.type = 'staff'; - userData.isAdmin = false; - users.push(userData); - returnValue = userData; - } else { - returnValue = 'You must be an admin to create staffs'; - } - } else { - // eslint-disable-next-line prefer-destructuring - returnValue = returnData[4]; - } - return returnValue; - }, -}; - -export default CreateStaffService; diff --git a/server/v1/services/login.js b/server/v1/services/login.js index e015c9d..f645676 100644 --- a/server/v1/services/login.js +++ b/server/v1/services/login.js @@ -6,7 +6,7 @@ const LoginService = { async loginUser(userData, token) { const emailRegex = /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,10})$/; const passwordRegex = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/; - const returnValue = []; + let returnStatus; let returnSuccess = ''; let returnError = ''; // Check if email and password is valid if (emailRegex.test(userData.email) && passwordRegex.test(userData.password)) { @@ -24,26 +24,37 @@ const LoginService = { user.lastName = emailresponse.rows[0].lastname; user.email = emailresponse.rows[0].email; user.token = token; - returnValue.push(user); + returnStatus = 201; + returnSuccess = user; } else { // else echo incorrect password - returnValue.push('incorrect password'); + returnStatus = 422; + returnError = 'incorrect password'; } } else { - returnValue.push('email does not exist'); + returnStatus = 404; + returnError = 'email does not exist'; + } + } else { + const error = []; + if (!emailRegex.test(userData.email)) { + returnStatus = 422; + error.push('invalid email address'); } - } - const checkError = (regex, data, msg) => { - if (!regex.test(data)) { - returnValue.push(msg); + if (!passwordRegex.test(userData.password)) { + returnStatus = 422; + error.push('Password should contain atleast 8 characters, 1 uppercase letter, 1 lowercase letter, 1 number and 1 symbol or character'); } - }; + returnError = error; + } - checkError(emailRegex, userData.email, 'invalid email address'); - checkError(passwordRegex, userData.password, 'Password should contain atleast 8 characters, 1 uppercase letter, 1 lowercase letter, 1 number and 1 symbol or character'); - return returnValue; + return { + returnStatus, + returnSuccess, + returnError, + }; }, }; diff --git a/server/v1/services/register.js b/server/v1/services/register.js index bf0215f..e12958e 100644 --- a/server/v1/services/register.js +++ b/server/v1/services/register.js @@ -7,7 +7,7 @@ import UserModel from '../model/users'; const RegisterService = { async registerUser(userData, token) { const returnData = await registrationHelper.registrationHelper(userData); - let returnValue; + let returnStatus; let returnSuccess = ''; let returnError = ''; // eslint-disable-next-line max-len if (returnData[0] === true && returnData[1] === true && returnData[2] === true && returnData[3] === true) { @@ -18,7 +18,8 @@ const RegisterService = { // checks if email exist const emailresponse = await dbConnection.dbConnect('SELECT email FROM users WHERE email=$1', [userData.email]); if (emailresponse.rows.length >= 1) { - returnValue = 'email already exist'; + returnStatus = 409; + returnError = 'email already exist'; } else { // email does not exist... you can insert data const response = await dbConnection.dbConnect('INSERT into users(email, firstName, lastName, password, type, isAdmin) values($1, $2, $3, $4, $5, $6)', @@ -31,16 +32,74 @@ const RegisterService = { user.lastName = userDbData.rows[0].lastname; user.email = userDbData.rows[0].email; user.token = token; - returnValue = user; + returnStatus = 201; + returnSuccess = user; } else { - returnValue = 'Something wrong happened'; + returnStatus = 500; } } } else { + returnStatus = 422; // eslint-disable-next-line prefer-destructuring - returnValue = returnData[4]; + returnError = returnData[4]; } - return returnValue; + return { + returnStatus, + returnSuccess, + returnError, + }; + }, + + async createStaffs(userData, token, admin) { + const returnData = await registrationHelper.registrationHelper(userData); + let returnStatus; let returnSuccess = ''; let returnError = ''; + + const userDetails = await dbConnection + .dbConnect('SELECT isadmin FROM users WHERE email=$1', [admin.email]); + const { isadmin } = userDetails.rows[0]; + + if (isadmin === true) { + // eslint-disable-next-line max-len + if (returnData[0] === true && returnData[1] === true && returnData[2] === true && returnData[3] === true) { + const salt = bcrypt.genSaltSync(10); + const hash = bcrypt.hashSync(userData.password, salt); + // checks if email exist + const emailresponse = await dbConnection.dbConnect('SELECT email FROM users WHERE email=$1', [userData.email]); + if (emailresponse.rows.length >= 1) { + returnStatus = 409; + returnError = 'email already exist'; + } else { + // email does not exist... you can insert data + const response = await dbConnection.dbConnect('INSERT into users(email, firstName, lastName, password, type, isAdmin) values($1, $2, $3, $4, $5, $6)', + [userData.email, userData.firstName, userData.lastName, hash, userData.type, userData.isAdmin]); + if (response.command === 'INSERT') { + const userDbData = await dbConnection.dbConnect('SELECT * FROM users WHERE email=$1', [userData.email]); + const user = new UserModel(); + user.id = userDbData.rows[0].id; + user.firstName = userDbData.rows[0].firstname; + user.lastName = userDbData.rows[0].lastname; + user.email = userDbData.rows[0].email; + user.token = token; + returnStatus = 201; + returnSuccess = user; + } else { + returnStatus = 500; + } + } + } else { + returnStatus = 422; + // eslint-disable-next-line prefer-destructuring + returnError = returnData[4]; + } + } else { + returnStatus = 401; + returnError = 'you must be an admin to create staffs'; + } + return { + returnStatus, + returnSuccess, + returnError, + }; }, }; diff --git a/server/v1/services/transaction.js b/server/v1/services/transaction.js index 10bad74..9d659c0 100644 --- a/server/v1/services/transaction.js +++ b/server/v1/services/transaction.js @@ -4,7 +4,7 @@ import TransactionModel from '../model/Transaction'; const TransactionService = { async debitTransaction(accountNumber, loggedInUser, transactionData) { - let returnData; + let returnStatus; let returnSuccess = ''; let returnError = ''; // check the users table const userDetails = await dbConnection @@ -41,28 +41,43 @@ const TransactionService = { transaction.cashier = accountData.rows[0].cashier; transaction.transactionType = accountData.rows[0].type; transaction.accountBalance = accountData.rows[0].newbalance; - returnData = transaction; + returnStatus = 201; + returnSuccess = transaction; } else { - returnData = 'Something wrong happened'; + returnStatus = 500; } } } else { - returnData = 'You must be a staff or admin to perform this transaction'; + returnStatus = 401; + returnError = 'You must be a staff or admin to perform this transaction'; } - return returnData; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async getSpecificTransaction(transactionId) { + let returnStatus; let returnSuccess = ''; let returnError = ''; const userTransaction = await dbConnection .dbConnect('SELECT * from transactions WHERE id=$1', [transactionId]); if (userTransaction.rows.length > 0) { - return userTransaction.rows; + returnStatus = 200; + returnSuccess = userTransaction.rows; + } else { + returnStatus = 404; + returnError = 'no transaction found'; } - return 'no transaction found'; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async creditTransaction(accountNumber, loggedInUser, transactionData) { - let returnData; + let returnStatus; let returnSuccess = ''; let returnError = ''; // check the users table const userDetails = await dbConnection @@ -82,7 +97,7 @@ const TransactionService = { // check if a string const checkForDigit = /^-?\d+\.?\d*$/; if (checkForDigit.test(transactionData.amount)) { - // adding the passed in amount from the current balance + // add the passed in amount from the current balance const newBalance = balance + transactionData.amount; const transactionDbData = await dbConnection .dbConnect('INSERT into transactions(createdon, type, accountNumber, cashier, amount, oldbalance, newbalance) values($1, $2, $3, $4, $5,$6, $7)', @@ -99,15 +114,21 @@ const TransactionService = { transaction.cashier = accountData.rows[0].cashier; transaction.transactionType = accountData.rows[0].type; transaction.accountBalance = accountData.rows[0].newbalance; - returnData = transaction; + returnStatus = 201; + returnSuccess = transaction; } else { - returnData = 'Something wrong happened'; + returnStatus = 500; } } } else { - returnData = 'You must be a staff or admin to perform this transaction'; + returnStatus = 401; + returnError = 'You must be a staff or admin to perform this transaction'; } - return returnData; + return { + returnStatus, + returnSuccess, + returnError, + }; }, }; diff --git a/server/v1/services/users.js b/server/v1/services/users.js index ee72cce..ea0464c 100644 --- a/server/v1/services/users.js +++ b/server/v1/services/users.js @@ -2,6 +2,7 @@ import dbConnection from '../config/database'; const UsersServices = { async getAllUsers(staff) { + let returnStatus; let returnSuccess = ''; let returnError = ''; // check the users table const userDetails = await dbConnection .dbConnect('SELECT id, type, isadmin FROM users WHERE email=$1', [staff.email]); @@ -10,23 +11,46 @@ const UsersServices = { if (type === 'staff' || isadmin === true) { const allAccounts = await dbConnection .dbConnect('SELECT * from users'); - return allAccounts.rows; + returnStatus = 200; + returnSuccess = allAccounts.rows; + } else { + returnStatus = 401; + returnError = 'You don\'t have permission to view this page'; } - return 'You don\'t have permission to view this page'; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async getUsersAccounts(email) { + let returnStatus; let returnSuccess = ''; let returnError = ''; const allAccounts = await dbConnection .dbConnect('SELECT email from users WHERE email=$1', [email]); if (allAccounts.rows.length > 0) { const accountDbData = await dbConnection .dbConnect('SELECT * from accounts WHERE email=$1', [email]); - return accountDbData.rows; + if (accountDbData.rows.length > 0) { + returnStatus = 200; + returnSuccess = accountDbData.rows; + } else { + returnStatus = 404; + returnError = 'no account found for this user'; + } + } else { + returnStatus = 404; + returnError = 'email does not exist'; } - return 'no account found'; + return { + returnStatus, + returnSuccess, + returnError, + }; }, async deleteUser(id, staff) { + let returnStatus; let returnSuccess = ''; let returnError = ''; // check the users table const userDetails = await dbConnection .dbConnect('SELECT id, type, isadmin FROM users WHERE email=$1', [staff.email]); @@ -38,12 +62,25 @@ const UsersServices = { if (checkusers.rows.length > 0) { const accountDbData = await dbConnection .dbConnect('DELETE FROM users WHERE id=$1', [id]); - if (accountDbData.command === 'DELETE') return 'Account successfully deleted'; + if (accountDbData.command === 'DELETE') { + returnStatus = 204; + returnSuccess = 'Account successfully deleted'; + } else { + returnStatus = 500; + } } else { - return 'no account found'; + returnStatus = 404; + returnError = 'no account found'; } + } else { + returnStatus = 401; + returnError = 'You don\'t have permission to view this page'; } - return 'You don\'t have permission to view this page'; + return { + returnStatus, + returnSuccess, + returnError, + }; }, }; diff --git a/server/v1/test/accounts.js b/server/v1/test/accounts.js index d141603..0d640fc 100644 --- a/server/v1/test/accounts.js +++ b/server/v1/test/accounts.js @@ -1,7 +1,6 @@ /* eslint-disable no-undef */ import chaiHttp from 'chai-http'; import chai, { expect } from 'chai'; -import dbConnection from '../config/database'; import app from '../app'; @@ -19,7 +18,7 @@ describe('Testing Accounts Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .post('/api/v1/accounts') .set('Authorization', `Bearer ${token}`) @@ -27,7 +26,7 @@ describe('Testing Accounts Controller', () => { type: 'savings', }); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(201); expect(res.body.data).to.have.property('id'); expect(res.body.data).to.have.property('accountNumber'); expect(res.body.data).to.have.property('createdOn'); @@ -48,7 +47,7 @@ describe('Testing Accounts Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .post('/api/v1/accounts') .set('Authorization', `Bearer ${token}`) @@ -63,7 +62,8 @@ describe('Testing Accounts Controller', () => { status: 'dormant', }); expect(res1.body).to.be.an('object'); - expect(res1.body.status).to.equal('success'); + expect(res1.body.status).to.equal(401); + expect(res1).to.have.status(401); expect(res1.body.data).to.equal('Sorry you don\'t have permission to perform this task'); }, ); @@ -78,7 +78,7 @@ describe('Testing Accounts Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .post('/api/v1/accounts') .set('Authorization', `Bearer ${token}`) @@ -91,7 +91,8 @@ describe('Testing Accounts Controller', () => { .set('Authorization', `Bearer ${token}`) .send(); expect(res1.body).to.be.an('object'); - expect(res1.body.status).to.equal('success'); + expect(res1.body.status).to.equal(401); + expect(res1).to.have.status(401); expect(res1.body.data).to.equal('Sorry you don\'t have permission to perform this task'); }, ); @@ -106,13 +107,13 @@ describe('Testing Accounts Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .get('/api/v1/accounts/3003801983/transactions') .set('Authorization', `Bearer ${token}`) .send(); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(200); expect(res.body.data[0]).to.have.property('id'); expect(res.body.data[0]).to.have.property('createdon'); expect(res.body.data[0]).to.have.property('type'); @@ -134,13 +135,13 @@ describe('Testing Accounts Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .get('/api/v1/accounts') .set('Authorization', `Bearer ${token}`) .send(); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(200); expect(res.body.data[0]).to.have.property('id'); expect(res.body.data[0]).to.have.property('email'); expect(res.body.data[0]).to.have.property('firstname'); @@ -164,13 +165,14 @@ describe('Testing Accounts Controller', () => { email: 'admin@banka.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .delete('/api/v1/accounts/883939378372') .set('Authorization', `Bearer ${token}`) .send(); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res.body.status).to.equal(404); + expect(res).to.have.status(404); expect(res.body.data).to.equal('no account found'); }, ); diff --git a/server/v1/test/signin.js b/server/v1/test/signin.js index f068b95..a5ef6a5 100644 --- a/server/v1/test/signin.js +++ b/server/v1/test/signin.js @@ -18,13 +18,13 @@ describe('Testing User Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - expect(response.body.data[0]).to.be.an('object'); - expect(response.body.status).to.equal('success'); - expect(response.body.data[0]).to.have.property('id'); - expect(response.body.data[0]).to.have.property('email'); - expect(response.body.data[0]).to.have.property('firstName'); - expect(response.body.data[0]).to.have.property('lastName'); - expect(response.body.data[0]).to.have.property('token'); + expect(response.body.data).to.be.an('object'); + expect(response).to.have.status(201); + expect(response.body.data).to.have.property('id'); + expect(response.body.data).to.have.property('email'); + expect(response.body.data).to.have.property('firstName'); + expect(response.body.data).to.have.property('lastName'); + expect(response.body.data).to.have.property('token'); }, ); @@ -37,7 +37,7 @@ describe('Testing User Controller', () => { password: 'passworD4@', }); expect(response.body).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('invalid email address'); }, ); @@ -48,12 +48,12 @@ describe('Testing User Controller', () => { const response = await chai.request(app) .post(signinUrl) .send({ - email: 'banka876@banka4.com', + email: 'banka85576@banka4.com', password: 'passworD4@', }); expect(response.body).to.be.an('object'); - expect(response.body.status).to.equal('success'); - expect(response.body.data[0]).to.equal('email does not exist'); + expect(response).to.have.status(404); + expect(response.body.data).to.equal('email does not exist'); }, ); @@ -66,7 +66,7 @@ describe('Testing User Controller', () => { email: 'banka872@banka4.com', }); expect(response.body).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('Password should contain atleast 8 characters, 1 uppercase letter, 1 lowercase letter, 1 number and 1 symbol or character'); }, ); @@ -81,8 +81,8 @@ describe('Testing User Controller', () => { password: 'passworD4@@', }); expect(response.body).to.be.an('object'); - expect(response.body.status).to.equal('success'); - expect(response.body.data[0]).to.equal('incorrect password'); + expect(response).to.have.status(422); + expect(response.body.data).to.equal('incorrect password'); }, ); @@ -96,7 +96,7 @@ describe('Testing User Controller', () => { password: 'passworD4', }); expect(response.body).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('Password should contain atleast 8 characters, 1 uppercase letter, 1 lowercase letter, 1 number and 1 symbol or character'); }, ); diff --git a/server/v1/test/signup.js b/server/v1/test/signup.js index b648b76..e4eb671 100644 --- a/server/v1/test/signup.js +++ b/server/v1/test/signup.js @@ -11,10 +11,11 @@ chai.use(chaiHttp); describe('Testing User Controller', () => { before(async () => { await dbConnection.dbTesting('DELETE FROM users'); + await dbConnection + .dbConnect('INSERT into users(email, firstName, lastName, password, type, isAdmin) values($1, $2, $3, $4, $5, $6)', ['admin@banka.com', 'cavdy', 'ikenna', '$2a$10$CmmIst1.D3QjaWuafKbBaOuAFu0r9o7xxQY.0SMKiAN.h9z52a2y2', 'staff', true]); }); describe('Testing signup controller', () => { const signupUrl = '/api/auth/signup'; - const signupStaffUrl = '/api/auth/addstaff'; it( 'should register a new user when all the parameters are given', async () => { @@ -27,7 +28,7 @@ describe('Testing User Controller', () => { password: 'passworD4@', }); expect(response).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(201); expect(response.body.data).to.have.property('id'); expect(response.body.data).to.have.property('firstName'); expect(response.body.data).to.have.property('lastName'); @@ -48,7 +49,7 @@ describe('Testing User Controller', () => { password: 'passworD4@', }); expect(response).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(409); expect(response.body.data).to.equal('email already exist'); }, ); @@ -64,7 +65,7 @@ describe('Testing User Controller', () => { password: 'passworD4@', }); expect(response).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('Email is required'); }, ); @@ -80,7 +81,7 @@ describe('Testing User Controller', () => { password: 'passworD4@', }); expect(response).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('Firstname required'); }, ); @@ -96,7 +97,7 @@ describe('Testing User Controller', () => { password: 'passworD4@', }); expect(response).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('Lastname required'); }, ); @@ -112,7 +113,7 @@ describe('Testing User Controller', () => { email: 'banka873@banka4.com', }); expect(response).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('Password should contain atleast 8 characters, 1 uppercase letter, 1 lowercase letter, 1 number and 1 symbol or character'); }, ); @@ -128,80 +129,65 @@ describe('Testing User Controller', () => { password: 'passworD4', }); expect(response).to.be.an('object'); - expect(response.body.status).to.equal('success'); + expect(response).to.have.status(422); expect(response.body.data[0]).to.equal('Password should contain atleast 8 characters, 1 uppercase letter, 1 lowercase letter, 1 number and 1 symbol or character'); }, ); - // it( - // 'should not create staffs if not admin', - // async () => { - // await chai.request(app) - // .post(signupUrl) - // .send({ - // firstName: 'cavdy', - // lastName: 'isaiah', - // email: 'bankaadmin@banka.com', - // password: 'passworadmiN4@', - // isAdmin: true, - // }); - // const signinUrl = '/api/auth/signin'; - // const response = await chai.request(app) - // .post(signinUrl) - // .send({ - // email: 'bankaadmin@banka.com', - // password: 'passworadmiN4@', - // }); - // console.log(response.body); - // const { token } = response.body.data[0]; - // const res = await chai.request(app) - // .post(signupStaffUrl) - // .set('Authorization', `Bearer ${token}`) - // .send({ - // firstName: 'cavdy', - // lastName: 'isaiah', - // email: 'banka4@banka.com', - // password: 'passworD4@', - // }); - // expect(res.body).to.be.an('object'); - // expect(res.body.status).to.equal('success'); - // expect(res.body.data).to.equal('You must be an admin to create staffs'); - // }, - // ); + it( + 'only admin can create staffs', + async () => { + const signinUrl = '/api/auth/signin'; + const response = await chai.request(app) + .post(signinUrl) + .send({ + email: 'admin@banka.com', + password: 'passworD4@', + }); + const { token } = response.body.data; + const res = await chai.request(app) + .post('/api/auth/signup/addstaff') + .set('Authorization', `Bearer ${token}`) + .send({ + firstName: 'cavdy', + lastName: 'isaiah', + email: 'staff25@banka.com', + password: 'passworD4@', + }); + expect(res).to.be.an('object'); + expect(res).to.have.status(201); + expect(res.body.data).to.have.property('id'); + expect(res.body.data).to.have.property('firstName'); + expect(res.body.data).to.have.property('lastName'); + expect(res.body.data).to.have.property('email'); + expect(res.body.data).to.have.property('token'); + }, + ); - // it( - // 'should create staffs if admin', - // (done) => { - // const signinUrl = '/api/auth/signin'; - // chai.request(app) - // .post(signinUrl) - // .send({ - // email: 'banka3@banka.com', - // password: 'passworD3@', - // }) - // .end((error, response) => { - // const { token } = response.body.data; - // chai.request(app) - // .post(signupStaffUrl) - // .set('Authorization', `Bearer ${token}`) - // .send({ - // firstName: 'cavdy', - // lastName: 'isaiah', - // email: 'banka4@banka.com', - // password: 'passworD4@', - // }) - // .end((err, res) => { - // expect(res.body).to.be.an('object'); - // expect(res.body.status).to.equal('success'); - // expect(res.body.data).to.be.a('object'); - // expect(res.body.data).to.have.property('id'); - // expect(res.body.data).to.have.property('firstName'); - // expect(res.body.data).to.have.property('lastName'); - // expect(res.body.data).to.have.property('email'); - // }); - // done(); - // }); - // }, - // ); + it( + 'should not create staff if not admin', + async () => { + const signinUrl = '/api/auth/signin'; + const response = await chai.request(app) + .post(signinUrl) + .send({ + email: 'banka872@banka4.com', + password: 'passworD4@', + }); + const { token } = response.body.data; + const res = await chai.request(app) + .post('/api/auth/signup/addstaff') + .set('Authorization', `Bearer ${token}`) + .send({ + firstName: 'cavdy', + lastName: 'isaiah', + email: 'staff8@banka.com', + password: 'passworD4@', + }); + expect(res).to.be.an('object'); + expect(res).to.have.status(401); + expect(res.body.data).to.equal('you must be an admin to create staffs'); + }, + ); }); }); diff --git a/server/v1/test/transactions.js b/server/v1/test/transactions.js index 552e880..d331009 100644 --- a/server/v1/test/transactions.js +++ b/server/v1/test/transactions.js @@ -1,17 +1,12 @@ /* eslint-disable no-undef */ import chaiHttp from 'chai-http'; import chai, { expect } from 'chai'; -import dbConnection from '../config/database'; import app from '../app'; chai.use(chaiHttp); describe('Testing Transactions Controller', () => { - before(async () => { - await dbConnection - .dbConnect('INSERT into users(email, firstName, lastName, password, type, isAdmin) values($1, $2, $3, $4, $5, $6)', ['admin@banka.com', 'cavdy', 'ikenna', '$2a$10$CmmIst1.D3QjaWuafKbBaOuAFu0r9o7xxQY.0SMKiAN.h9z52a2y2', 'staff', true]); - }); describe('Testing transactions controller', () => { it( 'transactions should have all required propertise', @@ -23,7 +18,7 @@ describe('Testing Transactions Controller', () => { email: 'admin@banka.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .post('/api/v1/transactions/3003801983/debit') .set('Authorization', `Bearer ${token}`) @@ -31,7 +26,7 @@ describe('Testing Transactions Controller', () => { amount: 500, }); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(201); expect(res.body.data).to.have.property('transactionId'); expect(res.body.data).to.have.property('accountNumber'); expect(res.body.data).to.have.property('cashier'); @@ -51,7 +46,7 @@ describe('Testing Transactions Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .post('/api/v1/transactions/3003801983/debit') .set('Authorization', `Bearer ${token}`) @@ -59,7 +54,7 @@ describe('Testing Transactions Controller', () => { amount: 500, }); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(401); expect(res.body.data).to.equal('You must be a staff or admin to perform this transaction'); }, ); @@ -74,13 +69,13 @@ describe('Testing Transactions Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .get('/api/v1/transactions/4') .set('Authorization', `Bearer ${token}`) .send(); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(200); expect(res.body.data[0]).to.have.property('id'); expect(res.body.data[0]).to.have.property('createdon'); expect(res.body.data[0]).to.have.property('type'); @@ -102,7 +97,7 @@ describe('Testing Transactions Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .post('/api/v1/transactions/3003801983/credit') .set('Authorization', `Bearer ${token}`) @@ -110,7 +105,7 @@ describe('Testing Transactions Controller', () => { amount: 500, }); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(401); expect(res.body.data).to.equal('You must be a staff or admin to perform this transaction'); }, ); diff --git a/server/v1/test/users.js b/server/v1/test/users.js index 200befc..de2905c 100644 --- a/server/v1/test/users.js +++ b/server/v1/test/users.js @@ -23,13 +23,13 @@ describe('Testing All Users Controller', () => { email: 'admin@banka.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .get('/api/v1/users') .set('Authorization', `Bearer ${token}`) .send(); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(200); expect(res.body.data[0]).to.have.property('id'); expect(res.body.data[0]).to.have.property('firstname'); expect(res.body.data[0]).to.have.property('lastname'); @@ -50,13 +50,13 @@ describe('Testing All Users Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { token } = response.body.data[0]; + const { token } = response.body.data; const res = await chai.request(app) .get('/api/v1/users') .set('Authorization', `Bearer ${token}`) .send(); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(401); expect(res.body.data).to.equal('You don\'t have permission to view this page'); }, ); @@ -71,13 +71,13 @@ describe('Testing All Users Controller', () => { email: 'banka872@banka4.com', password: 'passworD4@', }); - const { id, token } = response.body.data[0]; + const { id, token } = response.body.data; const res = await chai.request(app) .delete(`/api/v1/users/${id}`) .set('Authorization', `Bearer ${token}`) .send(); expect(res.body).to.be.an('object'); - expect(res.body.status).to.equal('success'); + expect(res).to.have.status(401); expect(res.body.data).to.equal('You don\'t have permission to view this page'); }, );