From a54625214c281f0f3cbfa4305d59adb956ee7fd3 Mon Sep 17 00:00:00 2001 From: holabayor Date: Sat, 23 Sep 2023 10:30:18 +0100 Subject: [PATCH 1/4] simple fixes --- controllers/authController.js | 4 ++-- controllers/organizationController.js | 1 + controllers/withdraw.controller.js | 4 ---- routes/orgRoutes.js | 7 ++----- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/controllers/authController.js b/controllers/authController.js index 337c2c2b..34831d1f 100644 --- a/controllers/authController.js +++ b/controllers/authController.js @@ -43,7 +43,7 @@ async function createUser(req, res, next) { is_admin: is_admin || false, profile_pic: 'https://cdn-icons-png.flaticon.com/512/147/147142.png', org_id: req.org_id || org_id, - lunch_credit_balance: lunch_credit_balance || 1000, + lunch_credit_balance: lunch_credit_balance || 5000, bank_code, bank_name, bank_number, @@ -158,7 +158,7 @@ async function createOrgAndUser(req, res, next) { const organization = await Organization.create({ name: org_name, lunch_price, - currency_code, + currency_code: currency_code || 'NGN', }); const lunchWallet = await OrgLunchWallet.create({ diff --git a/controllers/organizationController.js b/controllers/organizationController.js index c8bc084d..f945224e 100644 --- a/controllers/organizationController.js +++ b/controllers/organizationController.js @@ -7,6 +7,7 @@ const transporter = require('../middlewares/emailConfig'); // Create a new organization and user (Admin user only) const createOrganization = async (req, res, next) => { + console.log('Hello'); try { const { name, lunch_price, currency_code } = req.body; diff --git a/controllers/withdraw.controller.js b/controllers/withdraw.controller.js index 06343d6e..54d6ffdc 100644 --- a/controllers/withdraw.controller.js +++ b/controllers/withdraw.controller.js @@ -20,8 +20,6 @@ async function withdrawCashController(req, res, next) { // eslint-disable-next-line camelcase userWithdrawing.update({ bank_number, bank_name, bank_code }); - console.log(userWithdrawing.lunch_credit_balance); - if ( !userWithdrawing.lunch_credit_balance || userWithdrawing.lunch_credit_balance === 0 || @@ -43,13 +41,11 @@ async function withdrawCashController(req, res, next) { data: newEntry, }); } catch (error) { - console.log(error); next(error); } } async function withdrawalHistory(req, res, next) { - console.log(req.user); try { const { id } = req.user; diff --git a/routes/orgRoutes.js b/routes/orgRoutes.js index aabc1414..5936194e 100644 --- a/routes/orgRoutes.js +++ b/routes/orgRoutes.js @@ -3,19 +3,16 @@ const { auth, adminUser } = require('../middlewares/auth'); const router = express.Router(); const { - createOrganization, + //createOrganization, sendInviteCode, confirmInviteCode, updateOrgDetails, } = require('../controllers/organizationController'); -const { - createOrgAndUser -} = require('../controllers/authController'); +const { createOrgAndUser } = require('../controllers/authController'); // admin user middleware to block non admin from accessing the follow routes - router.post('/confirm-invite', confirmInviteCode); router.post('/create', createOrgAndUser); From 2bdd6ab7226a69fcce80a9176c43506976573cab Mon Sep 17 00:00:00 2001 From: holabayor Date: Sat, 23 Sep 2023 10:33:17 +0100 Subject: [PATCH 2/4] lint fix --- controllers/authController.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/controllers/authController.js b/controllers/authController.js index af68f21b..3ff300c1 100644 --- a/controllers/authController.js +++ b/controllers/authController.js @@ -5,20 +5,21 @@ const User = require('../models/user.model'); const { createCustomError } = require('../errors/custom-errors'); const Organization = require('../models/organization.model'); const OrgLunchWallet = require('../models/org_lunch_wallet.model'); -const {sendEmail} = require('./mailController') +const { sendEmail } = require('./mailController'); + const secretKey = process.env.JWT_SECRET_KEY; async function validateEmail(req, res, next) { try { - const email = req.body.email; + const { email } = req.body; const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - + if (!emailRegex.test(email)) { throw createCustomError('Invalid email format', 400); } await sendEmail(email); - + next(); } catch (error) { console.error(`Error sending email: ${error.message}`); @@ -26,8 +27,6 @@ async function validateEmail(req, res, next) { } } - - async function createUser(req, res, next) { try { const { @@ -231,4 +230,10 @@ async function createOrgAndUser(req, res, next) { } } -module.exports = { validateEmail, createUser, loginUser, logoutUser, createOrgAndUser }; +module.exports = { + validateEmail, + createUser, + loginUser, + logoutUser, + createOrgAndUser, +}; From 7d78d3691e615ef893a044d3481511c9efc561e4 Mon Sep 17 00:00:00 2001 From: holabayor Date: Sat, 23 Sep 2023 10:43:10 +0100 Subject: [PATCH 3/4] email validation on the model --- models/organisation_invite.model.js | 3 +++ models/user.model.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/models/organisation_invite.model.js b/models/organisation_invite.model.js index d97637a4..cce36883 100644 --- a/models/organisation_invite.model.js +++ b/models/organisation_invite.model.js @@ -13,6 +13,9 @@ const orgInvites = sequelize.define( email: { type: DataTypes.STRING, allowNull: false, + validate: { + isEmail: { msg: 'Invalid email' }, + }, }, token: { type: DataTypes.STRING, diff --git a/models/user.model.js b/models/user.model.js index b6eb91d9..8176654d 100644 --- a/models/user.model.js +++ b/models/user.model.js @@ -22,6 +22,9 @@ const User = sequelize.define( type: DataTypes.STRING, unique: true, allowNull: false, + validate: { + isEmail: { msg: 'Invalid email' }, + }, }, password_hash: { type: DataTypes.STRING, From 7fc4116db36c005f244089d42c8072d384731d4a Mon Sep 17 00:00:00 2001 From: holabayor Date: Sat, 23 Sep 2023 12:11:21 +0100 Subject: [PATCH 4/4] reset and forgot password --- .eslintrc.json | 3 +- controllers/authController.js | 85 +++++++++++++++++++++++++++++++++ controllers/lunch.controller.js | 15 ------ controllers/userController.js | 54 --------------------- generate-secret-key.js | 4 -- middlewares/auth.js | 2 - middlewares/index.js | 0 models/index.js | 50 ------------------- routes/auth.route.js | 7 +++ routes/users.js | 6 --- tests/userController.test.js | 5 +- 11 files changed, 96 insertions(+), 135 deletions(-) delete mode 100644 controllers/lunch.controller.js delete mode 100644 generate-secret-key.js delete mode 100644 middlewares/index.js delete mode 100644 models/index.js diff --git a/.eslintrc.json b/.eslintrc.json index fd739455..e7e17262 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,5 +15,6 @@ "class-methods-use-this": "off", "prefer-destructuring": ["error", { "object": true, "array": false }], "no-unused-vars": ["error", { "argsIgnorePattern": "req|res|next|val" }] - } + }, + "ignorePatterns": ["tests/"] } diff --git a/controllers/authController.js b/controllers/authController.js index 3ff300c1..5d4972de 100644 --- a/controllers/authController.js +++ b/controllers/authController.js @@ -6,6 +6,7 @@ const { createCustomError } = require('../errors/custom-errors'); const Organization = require('../models/organization.model'); const OrgLunchWallet = require('../models/org_lunch_wallet.model'); const { sendEmail } = require('./mailController'); +const transporter = require('../middlewares/emailConfig'); const secretKey = process.env.JWT_SECRET_KEY; @@ -230,10 +231,94 @@ async function createOrgAndUser(req, res, next) { } } +async function forgotPassword(req, res, next) { + const { email } = req.body; + try { + if (!email) { + return res.status(400).json({ + success: false, + message: 'Enter your email address', + }); + } + + const user = await User.findOne({ where: { email } }); + + if (!user) { + throw createCustomError('User not found', 404); + } + + const verificationCode = Math.floor( + 100000 + Math.random() * 900000, + ).toString(); + + // Send an email with the verification code + const mailOptions = { + from: process.env.MAIL_USER, // Your email address + to: email, // User's email address + subject: 'Password Reset', + text: `Your password reset code is: ${verificationCode}`, + }; + + // Send the email + await transporter.sendMail(mailOptions); + await user.update({ refresh_token: verificationCode }); + // Assuming sendUserOtp returns the expected response object + console.log(user); + res.status(202).json({ + success: true, + message: 'Password reset code sent successfully', + data: { + id: user.id, + email: user.email, + }, + }); + } catch (error) { + next(createCustomError('Invalid email', 401)); + } +} + +async function resetPassword(req, res, next) { + const { token, password } = req.body; + + if (!token || !password) { + return res.status(400).json({ + success: false, + message: 'Missing required fields', + data: null, + }); + } + try { + const user = await User.findOne({ where: { refresh_token: token } }); + + if (!user) { + throw createCustomError('User not found', 404); + } + + const salt = await bcrypt.genSalt(10); + const hashedPassword = await bcrypt.hash(password, salt); + // Update the user's password + await user.update({ password_hash: hashedPassword }); + + await user.update({ refresh_token: null }); + + await user.save(); + + res.status(200).json({ + success: true, + message: 'Password reset successfully', + data: user, + }); + } catch (error) { + next(createCustomError('Invalid reset code', 400)); + } +} + module.exports = { validateEmail, createUser, loginUser, logoutUser, createOrgAndUser, + forgotPassword, + resetPassword, }; diff --git a/controllers/lunch.controller.js b/controllers/lunch.controller.js deleted file mode 100644 index 0ad7e929..00000000 --- a/controllers/lunch.controller.js +++ /dev/null @@ -1,15 +0,0 @@ -const { Lunch } = require('../models/index'); - -const redeemedLunch = async (req, res) => { - //req.user is equal to the user's id stored in the authentication middleware - await Lunch.update({ redeemed: true }, { where: { sender_id: req.user } }); - return res.status(200).json({ - success: true, - message: 'Lunch has successfully been redeemed', - data: {}, - }); -}; - -module.exports = { - redeemedLunch, -}; diff --git a/controllers/userController.js b/controllers/userController.js index 70347eec..afdcd09a 100644 --- a/controllers/userController.js +++ b/controllers/userController.js @@ -1,7 +1,6 @@ /* eslint-disable camelcase */ const User = require('../models/user.model'); //import user model const { createCustomError } = require('../errors/custom-errors'); -const { sendUserOtp } = require('./mailController'); async function getMe(req, res, next) { try { @@ -147,63 +146,10 @@ async function updateUser(req, res, next) { } } -async function forgotPassword(req, res, next) { - const { email } = req.body; - if (!email) { - return res.status(404).json({ - success: false, - message: 'User not found', - }); - } - - const user = await User.findOne({ where: { email } }); - if (!user) { - throw createCustomError('Invalid credentials', 404); - } - - const response = await sendUserOtp(user.id, email); - - let status = 500; - if (response.status === true) { - status = 202; - } - - res.status(status).json(response); -} - -async function resetPassword(req, res) { - const { email, otp, password } = req.body; - if (!(email && otp && password)) { - return res.status(404).json({ - success: false, - message: 'User not found', - }); - } - - const user = await User.findOne({ where: { email } }); - if (!user) { - throw createCustomError('Invalid credentials', 404); - } - - // const response = await verifyOtp(user.id, otp) - - // update password - user.password = password; - await user.save(); - - res.status(200).json({ - success: true, - message: 'Password reset successfully', - data: null, - }); -} - module.exports = { getMe, getUserById, getAllUsers, updateUser, deleteUser, - forgotPassword, - resetPassword, }; diff --git a/generate-secret-key.js b/generate-secret-key.js deleted file mode 100644 index 79e94fb3..00000000 --- a/generate-secret-key.js +++ /dev/null @@ -1,4 +0,0 @@ -const crypto = require('crypto'); - -const secretKey = crypto.randomBytes(32).toString('hex'); -console.log('Generated Secret Key:', secretKey); diff --git a/middlewares/auth.js b/middlewares/auth.js index a170ea7c..a41fba26 100644 --- a/middlewares/auth.js +++ b/middlewares/auth.js @@ -32,8 +32,6 @@ async function auth(req, res, next) { } } - - /** * checks if the user is an admin user * @requires auth middleware be added first diff --git a/middlewares/index.js b/middlewares/index.js deleted file mode 100644 index e69de29b..00000000 diff --git a/models/index.js b/models/index.js deleted file mode 100644 index 897c1096..00000000 --- a/models/index.js +++ /dev/null @@ -1,50 +0,0 @@ -const Sequelize = require('sequelize'); - -const connection = new Sequelize({ - dialect: 'mysql', -}); - -const Lunch = connection.define('Lunch', { - id: { - type: Sequelize.UUID, - primaryKey: true, - defaultValue: Sequelize.UUIDV4, - }, - org_id: { - type: Sequelize.TEXT, - references: { - model: 'Users', - key: 'org_id', - }, - }, - sender_id: { - type: Sequelize.TEXT, - references: { - model: 'Users', - key: 'id', - }, - }, - receiver_id: { - type: Sequelize.TEXT, - references: { - model: 'Users', - key: 'id', - }, - }, - quantity: { - type: Sequelize.INTEGER, - }, - redeemed: { - type: Sequelize.TINYINT, - }, - created_at: { - type: Sequelize.DATE, - }, - note: { - type: Sequelize.TEXT, - }, -}); - -module.exports = { - Lunch, -}; diff --git a/routes/auth.route.js b/routes/auth.route.js index 305c4768..c73a7320 100644 --- a/routes/auth.route.js +++ b/routes/auth.route.js @@ -4,6 +4,8 @@ const { loginUser, logoutUser, createOrgAndUser, + forgotPassword, + resetPassword, } = require('../controllers/authController'); const { auth } = require('../middlewares/auth'); @@ -12,6 +14,11 @@ const router = express.Router(); router.post('/signup', createUser); router.post('/login', loginUser); router.post('/signup/org-user', createOrgAndUser); + +// forgot password +router.post('/forgot-password', forgotPassword); +router.post('/reset-password', resetPassword); + router.use(auth); router.post('/logout', logoutUser); diff --git a/routes/users.js b/routes/users.js index 79b27048..4b190e8b 100644 --- a/routes/users.js +++ b/routes/users.js @@ -9,16 +9,10 @@ const { getUserById, getAllUsers, updateUser, - forgotPassword, - resetPassword, deleteUser, } = require('../controllers/userController'); const { auth, adminUser } = require('../middlewares/auth'); -// forgot password -router.post('/forgot-password', forgotPassword); -router.post('/reset-password', resetPassword); - router.use(auth); router.get('/me', getMe); diff --git a/tests/userController.test.js b/tests/userController.test.js index 0c8a1210..31f8a4ab 100644 --- a/tests/userController.test.js +++ b/tests/userController.test.js @@ -83,15 +83,14 @@ describe('Users COntroller Endpoints', () => { }); }); - - describe('Users Endpoints', () => { + describe('Users Endpoints', () => { it('should fetch all users', async () => { const res = await request(app).get(`/api/users`); expect(res.status).toEqual(500); }); }); - describe('Users Endpoints', () => { + describe('Users Endpoints', () => { it('should fetch all users', async () => { const res = await request(app).post(`/api/auth/logout`); expect(res.status).toEqual(200);