diff --git a/src/controllers/auth.controller.js b/src/controllers/auth.controller.js index 337d28e9..7bd2064b 100644 --- a/src/controllers/auth.controller.js +++ b/src/controllers/auth.controller.js @@ -15,6 +15,11 @@ const login = catchAsync(async (req, res) => { res.send({ user, tokens }); }); +const logout = catchAsync(async (req, res) => { + await authService.logout(req.body.refreshToken); + res.status(httpStatus.NO_CONTENT).send(); +}); + const refreshTokens = catchAsync(async (req, res) => { const tokens = await authService.refreshAuth(req.body.refreshToken); res.send({ ...tokens }); @@ -34,6 +39,7 @@ const resetPassword = catchAsync(async (req, res) => { module.exports = { register, login, + logout, refreshTokens, forgotPassword, resetPassword, diff --git a/src/routes/v1/auth.route.js b/src/routes/v1/auth.route.js index 1abfd19e..5c2ce5d7 100644 --- a/src/routes/v1/auth.route.js +++ b/src/routes/v1/auth.route.js @@ -7,6 +7,7 @@ const router = express.Router(); router.post('/register', validate(authValidation.register), authController.register); router.post('/login', validate(authValidation.login), authController.login); +router.post('/logout', validate(authValidation.logout), authController.logout); router.post('/refresh-tokens', validate(authValidation.refreshTokens), authController.refreshTokens); router.post('/forgot-password', validate(authValidation.forgotPassword), authController.forgotPassword); router.post('/reset-password', validate(authValidation.resetPassword), authController.resetPassword); @@ -118,6 +119,33 @@ module.exports = router; * message: Invalid email or password */ +/** + * @swagger + * path: + * /auth/logout: + * post: + * summary: Logout + * tags: [Auth] + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - refreshToken + * properties: + * refreshToken: + * type: string + * example: + * refreshToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZWJhYzUzNDk1NGI1NDEzOTgwNmMxMTIiLCJpYXQiOjE1ODkyOTg0ODQsImV4cCI6MTU4OTMwMDI4NH0.m1U63blB0MLej_WfB7yC2FTMnCziif9X8yzwDEfJXAg + * responses: + * "204": + * description: No content + * "401": + * $ref: '#/components/responses/Unauthorized' + */ + /** * @swagger * path: diff --git a/src/services/auth.service.js b/src/services/auth.service.js index 03c72295..ef253093 100644 --- a/src/services/auth.service.js +++ b/src/services/auth.service.js @@ -18,6 +18,20 @@ const loginUserWithEmailAndPassword = async (email, password) => { return user; }; +/** + * Logout + * @param {string} refreshToken + * @returns {Promise} + */ +const logout = async (refreshToken) => { + try { + const refreshTokenDoc = await tokenService.verifyToken(refreshToken, 'refresh'); + await refreshTokenDoc.remove(); + } catch (error) { + throw new ApiError(httpStatus.UNAUTHORIZED, 'Please authenticate'); + } +}; + /** * Refresh auth tokens * @param {string} refreshToken @@ -59,6 +73,7 @@ const resetPassword = async (resetPasswordToken, newPassword) => { module.exports = { loginUserWithEmailAndPassword, + logout, refreshAuth, resetPassword, }; diff --git a/src/validations/auth.validation.js b/src/validations/auth.validation.js index b85bfb4f..14da1e10 100644 --- a/src/validations/auth.validation.js +++ b/src/validations/auth.validation.js @@ -16,6 +16,12 @@ const login = { }), }; +const logout = { + body: Joi.object().keys({ + refreshToken: Joi.string().required(), + }), +}; + const refreshTokens = { body: Joi.object().keys({ refreshToken: Joi.string().required(), @@ -40,6 +46,7 @@ const resetPassword = { module.exports = { register, login, + logout, refreshTokens, forgotPassword, resetPassword,