From da0e42cbd5966d3afb854adffdcf2229f571b45a Mon Sep 17 00:00:00 2001 From: Ndevu12 Date: Mon, 6 May 2024 12:07:18 +0200 Subject: [PATCH] ft logout feature updates --- src/__test__/logout.test.ts | 74 ++++++ src/__test__/route.test.ts | 41 ++- src/__test__/userServices.test.ts | 25 +- src/__test__/userStatus.test.ts | 246 +++++++++--------- src/controllers/authController.ts | 20 +- src/helper/verify.ts | 2 +- src/index.ts | 1 - src/middlewares/index.ts | 3 +- src/middlewares/isValid.ts | 14 +- src/routes/UserRoutes.ts | 28 +- src/services/index.ts | 1 + src/services/userServices/logoutServices.ts | 18 ++ src/services/userServices/userLoginService.ts | 7 + .../userServices/userPasswordResetService.ts | 65 +++-- src/services/userServices/userResendOTP.ts | 4 + src/services/userServices/userSendOTPEmail.ts | 1 - src/utils/sendMail.ts | 3 +- 17 files changed, 334 insertions(+), 219 deletions(-) create mode 100644 src/__test__/logout.test.ts create mode 100644 src/services/userServices/logoutServices.ts diff --git a/src/__test__/logout.test.ts b/src/__test__/logout.test.ts new file mode 100644 index 0000000..19cdf70 --- /dev/null +++ b/src/__test__/logout.test.ts @@ -0,0 +1,74 @@ +import request from 'supertest'; +import { app, server } from '../index'; +import { createConnection, getConnection, getConnectionOptions, getRepository } from 'typeorm'; +import { User } from '../entities/User'; + +beforeAll(async () => { + // Connect to the test database + const connectionOptions = await getConnectionOptions(); + await createConnection({ ...connectionOptions, name: 'testConnection' }); +}); + +afterAll(async () => { + await getConnection('testConnection').close(); + server.close(); +}); + +describe('POST /user/logout', () => { + it('should logout a user', async () => { + // sign up a user + const registerUser = { + firstName: 'Ndevu', + lastName: 'Elisa', + email: 'ndevukumurindi@gmail.com', + gender: 'male', + phoneNumber: '078907987443', + photoUrl: 'https://example.com/images/photo.jpg', + userType: 'vender', + verified: true, + status: 'active', + password: process.env.TEST_USER_LOGIN_PASS, + }; + + await request(app).post('/user/register').send(registerUser); + + const loginUser = { + email: registerUser.email, + password: process.env.TEST_USER_LOGIN_PASS, + }; + + const userRepository = getRepository(User); + const user = await userRepository.findOne({ where: { email: registerUser.email } }); + if (user) { + const verifyRes = await request(app).get(`/user/verify/${user.id}`); + + if (!verifyRes) throw new Error(`Test User verification failed for ${user.email}`); + + const loginResponse = await request(app).post('/user/login').send(loginUser); + const setCookie = loginResponse.headers['set-cookie']; + + if (!setCookie) { + throw new Error('No cookies set in login response'); + } + + const resp = await request(app).post('/user/logout').set('Cookie', setCookie); + expect(resp.status).toBe(200); + expect(resp.body).toEqual({ Message: 'Logged out successfully' }); + + // Clean up: delete the test user + await userRepository.remove(user); + } + }); + + it('should not logout a user who is not logged in or with no token', async () => { + const fakeEmail = 'ndevukkkk@gmail.com'; + const loginUser = { + email: fakeEmail, + password: process.env.TEST_USER_LOGIN_PASS, + }; + const token = ''; + const res = await request(app).post('/user/logout').send(loginUser).set('Cookie', token); + expect(res.status).toBe(400); + expect(res.body).toEqual({ Message: 'Access denied. You must be logged in' }); + }); +}); diff --git a/src/__test__/route.test.ts b/src/__test__/route.test.ts index 5f46e0c..d1c3be2 100644 --- a/src/__test__/route.test.ts +++ b/src/__test__/route.test.ts @@ -8,11 +8,8 @@ beforeAll(async () => { const connectionOptions = await getConnectionOptions(); await createConnection({ ...connectionOptions, name: 'testConnection' }); - }); - - afterAll(async () => { const connection = getConnection('testConnection'); const userRepository = connection.getRepository(User); @@ -106,9 +103,8 @@ describe('POST /user/verify/:id', () => { }); describe('Send password reset link', () => { - it('Attempt to send email with rate limiting', async () => { - const email = "elijahladdiedv@gmail.com"; + const email = 'elijahladdiedv@gmail.com'; const requests = Array.from({ length: 5 }, async () => { return await request(app).post(`/user/password/reset/link?email=${email}`); @@ -118,34 +114,33 @@ describe('Send password reset link', () => { const lastResponse = responses[responses.length - 1]; expect(lastResponse.status).toBe(404); expect(lastResponse.body.message).toEqual('User not found'); - }); + }, 20000); it('Attempt to send email with invalid email template', async () => { - const email = "elijahladdiedv@gmail.com"; + const email = 'elijahladdiedv@gmail.com'; const res = await request(app).post(`/user/password/reset/link?email=${email}`); expect(res.status).toBe(404); expect(res.body.message).toEqual('User not found'); - }); + }, 10000); it('Send email to a user with special characters in email address', async () => { - const email = "user+test@example.com"; + const email = 'user+test@example.com'; const res = await request(app).post(`/user/password/reset/link?email=${encodeURIComponent(email)}`); expect(res.status).toBe(404); expect(res.body.message).toEqual('User not found'); - }); - + }, 10000); }); describe('Password Reset Service', () => { it('Should reset password successfully', async () => { const data = { - "newPassword": "user", - "confirmPassword": "user", + newPassword: 'user', + confirmPassword: 'user', }; - const email = "elijahladdiedv@gmail.com"; + const email = 'elijahladdiedv@gmail.com'; const userRepository = getRepository(User); const user = await userRepository.findOne({ where: { email: email } }); if (user) { @@ -158,22 +153,21 @@ describe('Password Reset Service', () => { it('Should return 404 if user not found', async () => { const data = { - "newPassword": "user", - "confirmPassword": "user", + newPassword: 'user', + confirmPassword: 'user', }; - const email = "nonexistentemail@example.com"; - const userId = "nonexistentuserid"; + const email = 'nonexistentemail@example.com'; + const userId = 'nonexistentuserid'; const res: any = await request(app).post(`/user/password/reset?userid=${userId}&email=${email}`).send(data); // Asser expect(res).toBeTruthy; - }); it('Should return 204 if required fields are missing', async () => { const data = { // }; - const email = "elijahladdiedv@gmail.com"; + const email = 'elijahladdiedv@gmail.com'; const userRepository = getRepository(User); const user = await userRepository.findOne({ where: { email: email } }); @@ -186,10 +180,10 @@ describe('Password Reset Service', () => { it('Should return 204 if newPassword and confirmPassword do not match', async () => { const data = { - "newPassword": "user123", - "confirmPassword": "user456", + newPassword: 'user123', + confirmPassword: 'user456', }; - const email = "elijahladdiedv@gmail.com"; + const email = 'elijahladdiedv@gmail.com'; const userRepository = getRepository(User); const user = await userRepository.findOne({ where: { email: email } }); @@ -200,4 +194,3 @@ describe('Password Reset Service', () => { } }); }); - diff --git a/src/__test__/userServices.test.ts b/src/__test__/userServices.test.ts index 9bd34ff..5e435d1 100644 --- a/src/__test__/userServices.test.ts +++ b/src/__test__/userServices.test.ts @@ -152,7 +152,8 @@ describe('start2FAProcess', () => { it('should return 403 if OTP is expired', async () => { const email = 'john.doe1@example.com'; - const user = await getRepository(User).findOneBy({ email }); + const userRepository = getRepository(User); + const user = await userRepository.findOneBy({ email }); if (user) { user.twoFactorEnabled = true; user.twoFactorCode = '123456'; @@ -168,6 +169,9 @@ describe('start2FAProcess', () => { const res = await request(app).post('/user/verify-otp').send(data); expect(res.status).toBe(403); expect(res.body).toEqual({ status: 'error', message: 'Authentication code expired' }); + if (user) { + await userRepository.remove(user); + } }); it('should return 400 if not sent email in body on resending OTP', async () => { @@ -190,14 +194,29 @@ describe('start2FAProcess', () => { }); it('should resend OTP', async () => { + const newUser = { + firstName: 'John', + lastName: 'Doe', + email: 'john.doe187@example.com', + password: 'password', + gender: 'Male', + phoneNumber: '0785044398', + userType: 'Buyer', + }; + + // Act + const resp = await request(app).post('/user/register').send(newUser); + if (!resp) { + console.log('Error creating user in resend otp test case'); + } const data = { - email: 'john.doe1@example.com', + email: 'john.doe187@example.com', }; const res = await request(app).post('/user/resend-otp').send(data); expect(res.status).toBe(200); expect(res.body).toEqual({ status: 'success', data: { message: 'OTP sent successfully' } }); - }); + }, 20000); it('should return 400 if not sent email in body on login', async () => { const data = {}; diff --git a/src/__test__/userStatus.test.ts b/src/__test__/userStatus.test.ts index 1f14416..f253551 100644 --- a/src/__test__/userStatus.test.ts +++ b/src/__test__/userStatus.test.ts @@ -1,7 +1,7 @@ import request from 'supertest'; import jwt from 'jsonwebtoken'; import { app, server } from '../index'; -import {getRepository } from 'typeorm'; +import { getRepository } from 'typeorm'; import { getConnection } from 'typeorm'; import { dbConnection } from '../startups/dbConnection'; import { User } from '../entities/User'; @@ -9,23 +9,23 @@ import { v4 as uuid } from 'uuid'; const adminUserId = uuid(); -const jwtSecretKey = process.env.JWT_SECRET || ""; +const jwtSecretKey = process.env.JWT_SECRET || ''; beforeAll(async () => { - const connection = await dbConnection(); + const connection = await dbConnection(); - const userRepository = connection?.getRepository(User); + const userRepository = connection?.getRepository(User); - const adminUser = new User(); - adminUser.id = adminUserId; - adminUser.firstName = 'remjsa'; - adminUser.lastName = 'djkchd'; - adminUser.email = 'admin.kjaxs@example.com'; - adminUser.password = 'passwordadmin'; - adminUser.userType = 'Admin'; - adminUser.gender = 'Male'; - adminUser.phoneNumber = '126380996347'; - adminUser.photoUrl = 'https://example.com/photo.jpg'; + const adminUser = new User(); + adminUser.id = adminUserId; + adminUser.firstName = 'remjsa'; + adminUser.lastName = 'djkchd'; + adminUser.email = 'admin.kjaxs@example.com'; + adminUser.password = 'passwordadmin'; + adminUser.userType = 'Admin'; + adminUser.gender = 'Male'; + adminUser.phoneNumber = '126380996347'; + adminUser.photoUrl = 'https://example.com/photo.jpg'; await userRepository?.save(adminUser); @@ -35,131 +35,119 @@ beforeAll(async () => { }); afterAll(async () => { - const connection = getConnection(); - const userRepository = connection.getRepository(User); + const connection = getConnection(); + const userRepository = connection.getRepository(User); - // Close the connection to the test database + // Close the connection to the test database await connection.close(); server.close(); }); const data = { - id: adminUserId, - email: "admin.kjaxs@example.com" - }; + id: adminUserId, + email: 'admin.kjaxs@example.com', +}; const testUser = { - firstName: 'John', - lastName: 'Doe', - email: 'checki@testing.com', - password: 'password', - gender: 'Male', - phoneNumber: '4223567890', - photoUrl: 'https://example.com/photo.jpg', - }; + firstName: 'John', + lastName: 'Doe', + email: 'checki@testing.com', + password: 'password', + gender: 'Male', + phoneNumber: '4223567890', + photoUrl: 'https://example.com/photo.jpg', +}; describe('POST /user/deactivate', () => { - it('should deactivate a user', async () => { - await request(app) - .post('/user/register') - .send(testUser); - - const token = jwt.sign(data,jwtSecretKey); - - const response = await request(app) - .post(`/user/deactivate`) - .set("Cookie", `token=${token}`) - .send({email: `${testUser.email}`}); - expect(response.status).toBe(200); - expect(response.body.message).toBe('User deactivated successfully'); - }); - - it('should return 404 when email is not submitted', async ()=> { - - const token = jwt.sign(data,jwtSecretKey); - const response = await request(app) - .post(`/user/deactivate`) - .set("Cookie", `token=${token}`) - - expect(response.status).toBe(404); - expect(response.body.error).toBe('Email is needed'); - }) - it('should return message "User is already suspended" if user is already suspended', async () => { - - const token = jwt.sign(data,jwtSecretKey); - const response = await request(app) - .post(`/user/deactivate`) - .set("Cookie", `token=${token}`) - .send({email: `${testUser.email}`}); - - expect(response.status).toBe(200); - expect(response.body.message).toBe('User is already suspended'); - }); - - it('should return 404 if user not found when deactivating', async () => { - - const token = jwt.sign(data,jwtSecretKey); - const response = await request(app) - .post(`/user/deactivate`) - .set("Cookie", `token=${token}`) - .send({email: "nonexistent@example.com"}); - - expect(response.status).toBe(404); - expect(response.body.error).toBe('User not found'); - }); + it('should deactivate a user', async () => { + await request(app).post('/user/register').send(testUser); + const token = jwt.sign(data, jwtSecretKey); + + const response = await request(app) + .post(`/user/deactivate`) + .set('Cookie', `token=${token}`) + .send({ email: `${testUser.email}` }); + expect(response.status).toBe(200); + expect(response.body.message).toBe('User deactivated successfully'); + }, 10000); + + it('should return 404 when email is not submitted', async () => { + const token = jwt.sign(data, jwtSecretKey); + const response = await request(app).post(`/user/deactivate`).set('Cookie', `token=${token}`); + + expect(response.status).toBe(404); + expect(response.body.error).toBe('Email is needed'); }); - - describe('POST /user/activate', () => { - it('should activate a user', async () => { - const token = jwt.sign(data,jwtSecretKey); - - const response = await request(app) - .post(`/user/activate`) - .set("Cookie", `token=${token}`) - .send({email: `${testUser.email}`}); - - expect(response.status).toBe(200); - expect(response.body.message).toBe('User activated successfully'); - - }); - - it('should return 404 when email is not submitted', async ()=> { - const token = jwt.sign(data,jwtSecretKey); - const response = await request(app) - .post(`/user/activate`) - .set("Cookie", `token=${token}`) - - expect(response.status).toBe(404); - expect(response.body.error).toBe('Email is needed'); - }) - - it('should return message "User is already active" if user is already active', async () => { - const token = jwt.sign(data,jwtSecretKey); - const response = await request(app) - .post(`/user/activate`) - .set("Cookie", `token=${token}`) - .send({email: `${testUser.email}`}); - - expect(response.status).toBe(200); - expect(response.body.message).toBe('User is already active'); - - const userRepository = getRepository(User); - const user = await userRepository.findOne({ where: { email: testUser.email } }); - if (user) { - await userRepository.remove(user); - } - }); - - it('should return 404 if user not found when activating', async () => { - const token = jwt.sign(data,jwtSecretKey); - const response = await request(app) - .post('/user/activate') - .set("Cookie", `token=${token}`) - .send({email: "nonexistent@example.com"}); - - expect(response.status).toBe(404); - expect(response.body.error).toBe('User not found'); - }); - + it('should return message "User is already suspended" if user is already suspended', async () => { + const token = jwt.sign(data, jwtSecretKey); + const response = await request(app) + .post(`/user/deactivate`) + .set('Cookie', `token=${token}`) + .send({ email: `${testUser.email}` }); + + expect(response.status).toBe(200); + expect(response.body.message).toBe('User is already suspended'); + }); + + it('should return 404 if user not found when deactivating', async () => { + const token = jwt.sign(data, jwtSecretKey); + const response = await request(app) + .post(`/user/deactivate`) + .set('Cookie', `token=${token}`) + .send({ email: 'nonexistent@example.com' }); + + expect(response.status).toBe(404); + expect(response.body.error).toBe('User not found'); }); +}); + +describe('POST /user/activate', () => { + it('should activate a user', async () => { + const token = jwt.sign(data, jwtSecretKey); + + const response = await request(app) + .post(`/user/activate`) + .set('Cookie', `token=${token}`) + .send({ email: `${testUser.email}` }); + + expect(response.status).toBe(200); + expect(response.body.message).toBe('User activated successfully'); + }, 10000); + + it('should return 404 when email is not submitted', async () => { + const token = jwt.sign(data, jwtSecretKey); + const response = await request(app).post(`/user/activate`).set('Cookie', `token=${token}`); + + expect(response.status).toBe(404); + expect(response.body.error).toBe('Email is needed'); + }); + + it('should return message "User is already active" if user is already active', async () => { + const token = jwt.sign(data, jwtSecretKey); + const response = await request(app) + .post(`/user/activate`) + .set('Cookie', `token=${token}`) + .send({ email: `${testUser.email}` }); + + expect(response.status).toBe(200); + expect(response.body.message).toBe('User is already active'); + + const userRepository = getRepository(User); + const user = await userRepository.findOne({ where: { email: testUser.email } }); + if (user) { + await userRepository.remove(user); + } + }); + + it('should return 404 if user not found when activating', async () => { + const token = jwt.sign(data, jwtSecretKey); + const response = await request(app) + .post('/user/activate') + .set('Cookie', `token=${token}`) + .send({ email: 'nonexistent@example.com' }); + + expect(response.status).toBe(404); + expect(response.body.error).toBe('User not found'); + }); +}); diff --git a/src/controllers/authController.ts b/src/controllers/authController.ts index 9f5f248..fbc025d 100644 --- a/src/controllers/authController.ts +++ b/src/controllers/authController.ts @@ -7,6 +7,7 @@ import { userDisableTwoFactorAuth, userValidateOTP, userResendOtpService, + logoutService, } from '../services'; import { userPasswordResetService } from '../services/userServices/userPasswordResetService'; import { sendPasswordResetLinkService } from '../services/userServices/sendResetPasswordLinkService'; @@ -40,18 +41,25 @@ export const verifyOTP = async (req: Request, res: Response) => { export const resendOTP = async (req: Request, res: Response) => { await userResendOtpService(req, res); }; + +export const sampleAPI = async (req: Request, res: Response) => { + res.status(200).json({ message: 'Token is valid' }); +}; export const userPasswordReset = async (req: Request, res: Response) => { - await userPasswordResetService(req, res); -} + await userPasswordResetService(req, res); +}; export const sendPasswordResetLink = async (req: Request, res: Response) => { - await sendPasswordResetLinkService(req, res); -} + await sendPasswordResetLinkService(req, res); +}; export async function activateUser(req: Request, res: Response) { - await activateUserService(req,res); + await activateUserService(req, res); } export async function disactivateUser(req: Request, res: Response) { - await deactivateUserService(req,res); + await deactivateUserService(req, res); } +export const logout = async (req: Request, res: Response) => { + await logoutService(req, res); +}; diff --git a/src/helper/verify.ts b/src/helper/verify.ts index 5fad54e..bda6a00 100644 --- a/src/helper/verify.ts +++ b/src/helper/verify.ts @@ -16,4 +16,4 @@ export const verifiedToken = (token: string): any => { console.error(err); return null; } -}; \ No newline at end of file +}; diff --git a/src/index.ts b/src/index.ts index bcb47c3..fb60cd4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,7 +14,6 @@ dotenv.config(); export const app = express(); const port = process.env.PORT || 8000; app.use(express.json()); - app.use(cookieParser()); app.use(cors({ origin: '*' })); app.use(router); diff --git a/src/middlewares/index.ts b/src/middlewares/index.ts index aa7e780..8fd48b8 100644 --- a/src/middlewares/index.ts +++ b/src/middlewares/index.ts @@ -1,2 +1,3 @@ -export * from "./errorHandler" +export * from './errorHandler'; export * from './roleCheck'; +export * from './isValid'; diff --git a/src/middlewares/isValid.ts b/src/middlewares/isValid.ts index 5d0c897..bd3a004 100644 --- a/src/middlewares/isValid.ts +++ b/src/middlewares/isValid.ts @@ -9,11 +9,7 @@ export interface DecodedUser { email: string; } -export const isTokenValide: RequestHandler = async ( - req: Request, - res: Response, - next: NextFunction -): Promise => { +export const isTokenValide: RequestHandler = async (req: Request, res: Response, next: NextFunction): Promise => { try { const token = req.cookies.token; const userPaylod = verifiedToken(token); @@ -22,9 +18,9 @@ export const isTokenValide: RequestHandler = async ( return; } const userRepository = getRepository(User); - const user = await userRepository.findOne({where: {id: userPaylod.id}}) - if(!user){ - res.status(404).json({Message: 'User not found'}); + const user = await userRepository.findOne({ where: { id: userPaylod.id } }); + if (!user) { + res.status(404).json({ Message: 'User not found' }); return; } req.user = user; @@ -34,4 +30,4 @@ export const isTokenValide: RequestHandler = async ( res.status(401).json({ Message: 'Sorry, Something went wrong' }); return; } -}; \ No newline at end of file +}; diff --git a/src/routes/UserRoutes.ts b/src/routes/UserRoutes.ts index 1db2d08..9eac282 100644 --- a/src/routes/UserRoutes.ts +++ b/src/routes/UserRoutes.ts @@ -1,10 +1,19 @@ import { Router } from 'express'; -import { disable2FA, enable2FA, login, resendOTP, sendPasswordResetLink, userPasswordReset , userRegistration, userVerification, verifyOTP} from '../controllers'; +import { + disable2FA, + enable2FA, + login, + resendOTP, + sendPasswordResetLink, + userPasswordReset, + userRegistration, + userVerification, + verifyOTP, + logout, +} from '../controllers'; - - -import { activateUser,disactivateUser } from '../controllers/index'; -import {hasRole} from '../middlewares/roleCheck'; +import { activateUser, disactivateUser } from '../controllers/index'; +import { hasRole } from '../middlewares/roleCheck'; import { isTokenValide } from '../middlewares/isValid'; const router = Router(); @@ -12,13 +21,14 @@ const router = Router(); router.post('/register', userRegistration); router.get('/verify/:id', userVerification); router.post('/login', login); +router.post('/logout', logout); router.post('/enable-2fa', enable2FA); router.post('/disable-2fa', disable2FA); router.post('/verify-otp', verifyOTP); router.post('/resend-otp', resendOTP); -router.post('/activate',isTokenValide,hasRole("ADMIN"),activateUser); -router.post('/deactivate',isTokenValide,hasRole("ADMIN"),disactivateUser); -router.post("/password/reset", userPasswordReset); -router.post("/password/reset/link", sendPasswordResetLink); +router.post('/activate', isTokenValide, hasRole('ADMIN'), activateUser); +router.post('/deactivate', isTokenValide, hasRole('ADMIN'), disactivateUser); +router.post('/password/reset', userPasswordReset); +router.post('/password/reset/link', sendPasswordResetLink); export default router; diff --git a/src/services/index.ts b/src/services/index.ts index a646114..a7b7863 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -8,3 +8,4 @@ export * from './userServices/userDisableTwoFactorAuth'; export * from './userServices/userValidateOTP'; export * from './userServices/userLoginService'; export * from './userServices/userResendOTP'; +export * from './userServices/logoutServices'; diff --git a/src/services/userServices/logoutServices.ts b/src/services/userServices/logoutServices.ts new file mode 100644 index 0000000..541c364 --- /dev/null +++ b/src/services/userServices/logoutServices.ts @@ -0,0 +1,18 @@ +import { Request, Response } from 'express'; + +// logout method +export const logoutService = async (req: Request, res: Response): Promise => { + try { + const token = req.cookies['token'] || null; + if (!token) { + res.status(400).json({ Message: 'Access denied. You must be logged in' }); + return; + } + + res.clearCookie('token'); + res.status(200).json({ Message: 'Logged out successfully' }); + } catch (error) { + console.error('Error logging out:', error); + res.status(500).json({ error: 'Sorry, Token required.' }); + } +}; diff --git a/src/services/userServices/userLoginService.ts b/src/services/userServices/userLoginService.ts index 8b0cffa..57633d0 100644 --- a/src/services/userServices/userLoginService.ts +++ b/src/services/userServices/userLoginService.ts @@ -48,6 +48,13 @@ export const userLoginService = async (req: Request, res: Response) => { process.env.JWT_SECRET as string, { expiresIn: '24h' } ); + + if (process.env.APP_ENV === 'production') { + res.cookie('token', token, { httpOnly: true, sameSite: false, secure: true }); + } else { + res.cookie('token', token, { httpOnly: true, sameSite: 'lax', secure: false }); + } + return res.status(200).json({ status: 'success', data: { diff --git a/src/services/userServices/userPasswordResetService.ts b/src/services/userServices/userPasswordResetService.ts index a14ebad..8428f1a 100644 --- a/src/services/userServices/userPasswordResetService.ts +++ b/src/services/userServices/userPasswordResetService.ts @@ -1,39 +1,38 @@ import bcrypt from 'bcrypt'; -import { Request, Response } from "express"; -import { responseError, responseServerError, responseSuccess } from "../../utils/response.utils"; -import { getRepository } from "typeorm"; -import { User } from "../../entities/User"; +import { Request, Response } from 'express'; +import { responseError, responseServerError, responseSuccess } from '../../utils/response.utils'; +import { getRepository } from 'typeorm'; +import { User } from '../../entities/User'; export const userPasswordResetService = async (req: Request, res: Response) => { - try { - const { email, userid } = req.query; - const { newPassword, confirmPassword } = req.body; - const mail: any = email; - const userId: any = userid; - const userRepository = getRepository(User); - if (!email || !userid) { - return responseError(res, 404, `Something went wrong while fetching your data`); - } - const existingUser = await userRepository.findOneBy({ email: mail, id: userId }); - if (!existingUser) { - return responseError(res, 404, `We can't find you data`); - } - - if (!newPassword || !confirmPassword) { - return responseError(res, 200, 'Please provide all required fields'); - } - if (newPassword !== confirmPassword) { - return responseError(res, 200, 'new password must match confirm password'); - } - const saltRounds = 10; - const hashedPassword = await bcrypt.hash(newPassword, saltRounds); + try { + const { email, userid } = req.query; + const { newPassword, confirmPassword } = req.body; + const mail: any = email; + const userId: any = userid; + const userRepository = getRepository(User); + if (!email || !userid) { + return responseError(res, 404, `Something went wrong while fetching your data`); + } + const existingUser = await userRepository.findOneBy({ email: mail, id: userId }); + if (!existingUser) { + return responseError(res, 404, `We can't find you data`); + } - existingUser.password = hashedPassword; - const updadeUser = await userRepository.save(existingUser); - return responseSuccess(res, 201, "Password updated successfully", updadeUser); - } catch (error) { - console.log(error) - return responseServerError(res, "Internal server error"); + if (!newPassword || !confirmPassword) { + return responseError(res, 200, 'Please provide all required fields'); + } + if (newPassword !== confirmPassword) { + return responseError(res, 200, 'new password must match confirm password'); } -} + const saltRounds = 10; + const hashedPassword = await bcrypt.hash(newPassword, saltRounds); + existingUser.password = hashedPassword; + const updadeUser = await userRepository.save(existingUser); + return responseSuccess(res, 201, 'Password updated successfully', updadeUser); + } catch (error) { + console.log('error: reseting password in password reset service'); + return responseServerError(res, 'Internal server error'); + } +}; diff --git a/src/services/userServices/userResendOTP.ts b/src/services/userServices/userResendOTP.ts index f86662b..f728b31 100644 --- a/src/services/userServices/userResendOTP.ts +++ b/src/services/userServices/userResendOTP.ts @@ -13,6 +13,7 @@ export const userResendOtpService = async (req: Request, res: Response) => { const { email } = req.body; if (!email) { + console.log('No email address provided'); return res.status(400).json({ status: 'error', message: 'Please provide an email' }); } @@ -20,11 +21,14 @@ export const userResendOtpService = async (req: Request, res: Response) => { const user = await userRepository.findOneBy({ email }); if (!user) { + console.log('User not found'); return res.status(404).json({ status: 'error', message: 'Incorrect email' }); } const otpCode = await start2FAProcess(user.email); + if (!otpCode) throw new Error('Error generating OTP'); const OTPEmailcontent = otpTemplate(user.firstName, otpCode.toString()); + if (!OTPEmailcontent) throw new Error('Error generating OTP email content'); await sendOTPEmail('Login OTP', user.email, OTPEmailcontent); if (process.env.APP_ENV !== 'test') { await sendOTPSMS(user.phoneNumber, otpCode.toString()); diff --git a/src/services/userServices/userSendOTPEmail.ts b/src/services/userServices/userSendOTPEmail.ts index a556eea..f80e39c 100644 --- a/src/services/userServices/userSendOTPEmail.ts +++ b/src/services/userServices/userSendOTPEmail.ts @@ -21,7 +21,6 @@ export const sendOTPEmail = async (subject: string, email: string, content: any) try { const info = await transporter.sendMail(mailOptions); - console.log('Message sent: %s', info.messageId); } catch (error) { console.log('Error occurred while sending email', error); } diff --git a/src/utils/sendMail.ts b/src/utils/sendMail.ts index e63cb6d..0836765 100644 --- a/src/utils/sendMail.ts +++ b/src/utils/sendMail.ts @@ -29,7 +29,7 @@ const sendMail = async ( -