├── .env.example ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE ├── Procfile ├── README.md ├── __mocks__ └── index.ts ├── __tests__ ├── api.test.ts ├── app.test.ts └── posts.test.ts ├── dist └── src │ ├── api │ ├── index.js │ └── index.js.map │ ├── app.js │ ├── app.js.map │ ├── configs │ ├── custom-environment-variables.config.js │ ├── custom-environment-variables.config.js.map │ ├── db.config.js │ ├── db.config.js.map │ ├── indes.js │ └── indes.js.map │ ├── controllers │ ├── admin.controller.js │ ├── admin.controller.js.map │ ├── auth.controller.js │ ├── auth.controller.js.map │ ├── index.js │ ├── index.js.map │ ├── post.controller.js │ └── post.controller.js.map │ ├── index.js │ ├── index.js.map │ ├── interfaces │ ├── ErrorResponse.js │ ├── ErrorResponse.js.map │ ├── MessageResponse.js │ ├── MessageResponse.js.map │ ├── Post.js │ ├── Post.js.map │ ├── User.js │ ├── User.js.map │ ├── index.js │ └── index.js.map │ ├── middlewares │ ├── auth │ │ ├── checkIsAdmin.js │ │ ├── checkIsAdmin.js.map │ │ ├── checkIsAuth.js │ │ ├── checkIsAuth.js.map │ │ ├── index.js │ │ ├── index.js.map │ │ ├── verifyRefreshToken.js │ │ └── verifyRefreshToken.js.map │ ├── errors │ │ ├── errorHandler.js │ │ ├── errorHandler.js.map │ │ ├── index.js │ │ ├── index.js.map │ │ ├── notFound.js │ │ └── notFound.js.map │ ├── file-upload │ │ ├── index.js │ │ ├── index.js.map │ │ ├── uploadImage.middleware.js │ │ └── uploadImage.middleware.js.map │ ├── index.js │ ├── index.js.map │ ├── sort-filter-pagination │ │ ├── index.js │ │ ├── index.js.map │ │ ├── postsFeatures.middleware.js │ │ └── postsFeatures.middleware.js.map │ └── validation │ │ ├── authValidation │ │ ├── index.js │ │ ├── index.js.map │ │ ├── userSchema.js │ │ ├── userSchema.js.map │ │ ├── userValidation.js │ │ └── userValidation.js.map │ │ ├── validator.js │ │ └── validator.js.map │ ├── models │ ├── Post.model.js │ ├── Post.model.js.map │ ├── Token.model.js │ ├── Token.model.js.map │ ├── User.model.js │ ├── User.model.js.map │ ├── index.js │ └── index.js.map │ ├── routes │ ├── admin.route.js │ ├── admin.route.js.map │ ├── auth.route.js │ ├── auth.route.js.map │ ├── index.js │ ├── index.js.map │ ├── post.route.js │ └── post.route.js.map │ ├── services │ ├── admin.service.js │ ├── admin.service.js.map │ ├── auth.service.js │ ├── auth.service.js.map │ ├── index.js │ ├── index.js.map │ ├── post.service.js │ └── post.service.js.map │ └── utils │ ├── generateSecretKey.js │ ├── generateSecretKey.js.map │ ├── getImageExtension.js │ ├── getImageExtension.js.map │ ├── index.js │ ├── index.js.map │ ├── isValidMongooseObjectId.js │ ├── isValidMongooseObjectId.js.map │ ├── response.js │ ├── response.js.map │ ├── sendEmail.js │ └── sendEmail.js.map ├── docker-compose.yml ├── jest.config.js ├── nodemon.json ├── package-lock.json ├── package.json ├── public └── uploads │ ├── posts │ ├── postImage-1669466910020.png │ └── postImage-1670340044006.png │ └── users │ ├── admin1.png │ ├── admin2.png │ ├── tem3.png │ └── temp.png ├── src ├── api │ └── index.ts ├── app.ts ├── configs │ ├── custom-environment-variables.config.ts │ ├── db.config.ts │ └── indes.ts ├── controllers │ ├── admin.controller.ts │ ├── auth.controller.ts │ ├── index.ts │ └── post.controller.ts ├── index.ts ├── interfaces │ ├── ErrorResponse.ts │ ├── MessageResponse.ts │ ├── Post.ts │ ├── User.ts │ └── index.ts ├── middlewares │ ├── auth │ │ ├── checkIsAdmin.ts │ │ ├── checkIsAuth.ts │ │ ├── index.ts │ │ └── verifyRefreshToken.ts │ ├── errors │ │ ├── errorHandler.ts │ │ ├── index.ts │ │ └── notFound.ts │ ├── file-upload │ │ ├── index.ts │ │ └── uploadImage.middleware.ts │ ├── index.ts │ ├── sort-filter-pagination │ │ ├── index.ts │ │ └── postsFeatures.middleware.ts │ └── validation │ │ ├── authValidation │ │ ├── index.ts │ │ ├── userSchema.ts │ │ └── userValidation.ts │ │ └── validator.ts ├── models │ ├── Post.model.ts │ ├── Token.model.ts │ ├── User.model.ts │ └── index.ts ├── public │ └── uploads │ │ ├── postImage-1619543798929.jpeg │ │ ├── postImage-1619639718502.jpeg │ │ ├── postImage-1619640393778.jpeg │ │ ├── postImage-1619640530261.png │ │ ├── postImage-1619641184290.jpeg │ │ └── postImage-1619641382057.jpeg ├── routes │ ├── admin.route.ts │ ├── auth.route.ts │ ├── index.ts │ └── post.route.ts ├── services │ ├── admin.service.ts │ ├── auth.service.ts │ ├── index.ts │ └── post.service.ts └── utils │ ├── generateSecretKey.ts │ ├── getImageExtension.ts │ ├── index.ts │ ├── isValidMongooseObjectId.ts │ ├── mockedData │ └── data.json │ ├── response.ts │ └── sendEmail.ts ├── swagger └── swagger.yaml ├── tsconfig.json └── tsconfig.prod.json /.env.example: -------------------------------------------------------------------------------- 1 | MONGODB_CONNECTION_STRING = "MONGODB CONNECTION URL" 2 | 3 | TOKEN_SECRET = "TOKEN SECRET" 4 | 5 | WEBSITE_URL = "WEBSITE URL" 6 | 7 | API_VERSION ="API VERSION" 8 | 9 | JWT_EXPIRE_TIME = "JWT EXPIRE TIME" 10 | 11 | SEND_GRID_API_KEY = "YOUR SEND GRID API KEY" 12 | 13 | ADMIN_SEND_GRID_EMAIL = "YOUR SEND GRID Email" 14 | 15 | ADMIN_ROLE = "ADD ADMIN ROLE HERE" 16 | 17 | ADMIN_EMAIL = "ADD ADMIN EMAIL here" 18 | 19 | NODE_ENV = "development" 20 | 21 | CLIENT_URL = "Your client web url" 22 | 23 | REST_PASSWORD_LINK_EXPIRE_TIME = 'Rest password email link expire time' 24 | ACCESS_TOKEN_SECRET_KEY = "Your access token secret key" 25 | 26 | REFRESH_TOKEN_SECRET_KEY = "Your refresh token secret key" 27 | 28 | ACCESS_TOKEN_KEY_EXPIRE_TIME = 'Your access token secret key expiration date (1h)' 29 | 30 | REFRESH_TOKEN_KEY_EXPIRE_TIME = 'Your refresh token secret key expiration date (1y)' 31 | 32 | JWT_ISSUER = 'Your webside url or your email' 33 | 34 | ACCESS_TOKEN_PRIVATE_KEY = 'this is just for testing(todo)' 35 | 36 | ACCESS_TOKEN_PUBLIC_KEY = 'this is just for testing(todo)' 37 | 38 | REFRESH_TOKEN_PUBLIC_KEY = '' 39 | REFRESH_TOKEN_PRIVATE_KEY = '' -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | coverage -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "jest": true, 5 | "es2021": true, 6 | "node": true 7 | }, 8 | "parser": "@typescript-eslint/parser", 9 | "parserOptions": { 10 | "project": ["./tsconfig.json"] 11 | }, 12 | "extends": [ 13 | "eslint:recommended", 14 | "plugin:@typescript-eslint/recommended", 15 | "airbnb-base", 16 | "plugin:prettier/recommended", 17 | "plugin:import/errors", 18 | "plugin:import/warnings", 19 | "plugin:import/typescript" 20 | ], 21 | "plugins": ["@typescript-eslint", "prettier", "simple-import-sort", "import"], 22 | "rules": { 23 | "prettier/prettier": "error", 24 | "import/extensions": "off", 25 | "import/no-unresolved": "error", 26 | "no-underscore-dangle": "off", 27 | "no-console": "off", 28 | "@typescript-eslint/ban-ts-comment": "off", 29 | "@typescript-eslint/no-explicit-any": "off", 30 | "consistent-return": "off", 31 | "func-names": "off", 32 | "import/named": 2, 33 | "import/namespace": 2, 34 | "import/default": 2, 35 | "import/export": 2, 36 | "import/no-cycle": "off", 37 | "import/first": "error", 38 | "import/newline-after-import": "error", 39 | "import/no-duplicates": "error", 40 | "simple-import-sort/exports": "error", 41 | "import/order": [ 42 | "error", 43 | { 44 | "groups": [ 45 | ["builtin", "external"], 46 | ["internal", "parent", "sibling", "index"] 47 | ] 48 | } 49 | ] 50 | }, 51 | "settings": { 52 | "import/parsers": { 53 | "@typescript-eslint/parser": [".ts"] 54 | }, 55 | "import/resolver": { 56 | "typescript": { 57 | "alwaysTryTypes": true, // always try to resolve types under `@types` directory even it doesn't contain any source code, like `@types/unist` 58 | // Choose from one of the "project" configs below or omit to use /tsconfig.json by default 59 | // use /path/to/folder/tsconfig.json 60 | "project": "./tsconfig.json" 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | coverage -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "printWidth": 120, 4 | "singleQuote": true, 5 | "trailingComma": "es5", 6 | "semi": true 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "colorize.languages": [ 3 | "css", 4 | "sass", 5 | "scss", 6 | "less", 7 | "postcss", 8 | "sss", 9 | "stylus", 10 | "xml", 11 | "svg", 12 | "json", 13 | "ts", 14 | "js", 15 | "tsx", 16 | "jsx" 17 | ], 18 | "editor.formatOnPaste": true, 19 | "editor.formatOnSave": true, 20 | "editor.defaultFormatter": "esbenp.prettier-vscode", 21 | "editor.codeActionsOnSave": { 22 | "source.fixAll.eslint": true, 23 | "source.fixAll.format": true 24 | }, 25 | "cSpell.words": ["ENDPOIN", "semibold"] 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License Copyright (c) 2020 CJ R. 2 | 3 | Permission is hereby granted, free 4 | of charge, to any person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, copy, modify, merge, 7 | publish, distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to the 9 | following conditions: 10 | 11 | The above copyright notice and this permission notice 12 | (including the next paragraph) shall be included in all copies or substantial 13 | portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO 18 | EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: npm start 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # open-source-blog-api 2 | 3 | Free Open source REST API built with | TypeScript + Nodejs + Express + Mongodb ⚡️ Made with developer experience first Prettier + ESLint + VSCode setup. 4 | 5 | > - C.R.U.D, Filter, Paginate, Sort, image upload, and Search API 6 | 7 | # Table of contents 8 | 9 | - [Author](#Author) 10 | - [Demo](#Demo) 11 | - [Technologies](#Technologies) 12 | - [Contributing](#Contributing) 13 | - [Status](#status) 14 | - [Features](#Features) 15 | - [Related Projects](#Related_Projects) 16 | - [Support](#Support) 17 | - [Feedback](#Feedback) 18 | - [Screenshots](#Screenshots) 19 | - [Deployment](#Deployment) 20 | 21 | # Author 22 | 23 | ### @Saddam Arbaa 24 | 25 | # Technologies 26 | 27 | - TypeScript 28 | - Node.js 29 | - Express 30 | - MongoDB 31 | - JSON Web Token (JWT) 32 | - bcryptjs 33 | - jest 34 | - supertest 35 | - Heroku Hosting 36 | 37 | # Demo 38 | 39 | ### LIVE API Demo 40 | 41 | ### Front-End REPO 42 | 43 | ### LIVE Webside DEMO 44 | 45 | ## Testing Email: testverstion@gmail.com 46 | 47 | ## Testing Password: 12345test 48 | 49 | # Features 50 | 51 | ##### (Users) 52 | 53 | - Complete user authentication 54 | - Users can sign in 55 | - Users can sign out 56 | - Users can verify email 57 | - Users can Change Password 58 | - View all post 59 | - View post detail 60 | - Filter posts by category 61 | - Search for posts 62 | - Posts pagination 63 | - Limit posts 64 | 65 | ##### (Admin) 66 | 67 | - Complete Admin Authorization 68 | - Add post 69 | - Update post 70 | - Delete post 71 | - Add Users (todo) 72 | - Update Users (todo) 73 | - Delete Users 74 | - Update User Role (todo) 75 | 76 | # Contributing 77 | 78 | Contributions are always welcome! 79 | 80 | # Deployment 81 | 82 | To deploy this project on Heroku Flow the Flowing documentation Deploying Node.js Apps on Heroku 83 | 84 | # Related_Projects 85 | 86 | ### Blog built with | React Js + Next Js + Node.js + Express + MongoDB + CSS Modules + Vercel Hosting 87 | 88 | #### Blog REPO 89 | 90 | #### LIVE Webside DEMO 91 | 92 | ### Open Source Ecommerce API built with | Nodejs + Express + Mongodb + JWT authentication (CRUD operations, search, sort, filter, image upload and pagination) 93 | 94 | #### LIVE API 95 | 96 | #### API REPO 97 | 98 | ### Twitter API built with | Nodejs + Express + Mongodb 99 | 100 | #### LIVE API Demo 101 | 102 | #### API REPO 103 | 104 | #### Front-End REPO 105 | 106 | #### LIVE Webside DEMO 107 | 108 | ### Netflix API built with | Nodejs + Express + Mongodb 109 | 110 | #### API REPO 111 | 112 | #### LIVE API Demo 113 | 114 | # Support 115 | 116 | For support, email saddamarbaas@gmail.com. 117 | 118 | # Feedback 119 | 120 | If you have any feedback, please reach out to me at saddamarbaas@gmail.com 121 | 122 | Twitter 123 | https://twitter.com/ArbaaSaddam/ 124 | 125 | Linkedin. 126 | https://www.linkedin.com/in/saddamarbaa/ 127 | 128 | Github 129 | https://github.com/saddamarbaa 130 | 131 | Instagram 132 | https://www.instagram.com/saddam.dev/ 133 | 134 | Facebook 135 | https://www.facebook.com/saddam.arbaa 136 | 137 | # Status 138 | 139 | Project is: in progress I'm working on it in my free time 140 | 141 | # Screenshots 142 | 143 | ## My Blog Software Requirements 144 | 145 | https://docs.google.com/document/d/1lZvacY90Yo19QcnJxRJyy1AAZkTi0Vi5qXHTtptqAiU/edit 146 | 147 | ![image](https://user-images.githubusercontent.com/51326421/111891042-f857f580-8a21-11eb-8bb9-310f0c666f91.png) 148 | 149 | ## Business Requirements 150 | 151 | ![image](https://user-images.githubusercontent.com/51326421/111891112-b4192500-8a22-11eb-92e9-20854d336b57.png) 152 | 153 | ## Technical Requirements 154 | 155 | ![image](https://user-images.githubusercontent.com/51326421/111891149-33a6f400-8a23-11eb-9f98-bea822a938f3.png) 156 | 157 | ## My Blog SUser Flow 158 | 159 | https://app.diagrams.net/#G1DYvf-0FWMjC2nDzFbvAgbJ03Zg8DLfRZ 160 | 161 | ![image](https://user-images.githubusercontent.com/51326421/111890990-5b955800-8a21-11eb-89db-3f552bd8f7ff.png) 162 | 163 | ## Blog App: Wireframe 164 | 165 | https://app.diagrams.net/#G1Wo8rd6DVJUyCwp7aC6kLpvMkBM3Mgh8l 166 | 167 | ## responsive on large screens(Home Page) 168 | 169 | ![image](https://user-images.githubusercontent.com/51326421/198089229-140a67d9-5cbc-42ea-b871-c84437bbebbe.png) 170 | 171 | ## responsive on mobile and tablet screens 172 | 173 | ![image](https://user-images.githubusercontent.com/51326421/198090336-7f9db2bf-6f5f-4c77-84ea-74025d027e55.png) 174 | 175 | ## post detail page 176 | 177 | ![image](https://user-images.githubusercontent.com/51326421/198090667-46907f31-58d1-44d8-a995-bea487ec9458.png) 178 | 179 | ## Edit new post page 180 | 181 | ![image](https://user-images.githubusercontent.com/51326421/198096430-5c5928b0-f39d-44c0-ad80-ab887615a743.png) 182 | 183 | ## Edit post page 184 | 185 | ![image](https://user-images.githubusercontent.com/51326421/198090907-759c57f7-c3ca-4d9e-bdd7-5f57bfcb57ac.png) 186 | 187 | ## Login Page 188 | 189 | ![image](https://user-images.githubusercontent.com/51326421/198091036-5306633d-60da-4c9b-8457-ef2e54c5ba0b.png) 190 | 191 | ![image](https://user-images.githubusercontent.com/51326421/198091134-4582d1b6-33ed-403f-9f33-2544ee9372e7.png) 192 | 193 | ![image](https://user-images.githubusercontent.com/51326421/198091226-a97c21f4-7661-4614-a6ca-e7b98aacf068.png) 194 | 195 | ## Register page 196 | 197 | ![image](https://user-images.githubusercontent.com/51326421/198091354-d8d03db0-97c1-4315-8a43-e8fb6351b230.png) 198 | 199 | ![image](https://user-images.githubusercontent.com/51326421/198091554-d18d0adf-2a79-42cb-8d83-33920e2ba3d3.png) 200 | 201 | ## Forgot password page 202 | 203 | ![image](https://user-images.githubusercontent.com/51326421/198091856-c917f9b5-17a8-4aa6-b91e-f1636cfee361.png) 204 | 205 | ![image](https://user-images.githubusercontent.com/51326421/198092467-0e393c59-fb00-48ad-9c93-55b116794f1d.png) 206 | 207 | ## Reset password page 208 | 209 | ![image](https://user-images.githubusercontent.com/51326421/198092583-0437999c-dc3e-4a5a-ac47-7f1eac4bba8d.png) 210 | -------------------------------------------------------------------------------- /__mocks__/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | // Todo mocking test 3 | -------------------------------------------------------------------------------- /__tests__/api.test.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | 3 | import app from '@src/app'; 4 | 5 | describe('GET /api/v1', () => { 6 | it('responds with a json message', (done) => { 7 | request(app).get('/api/v1').set('Accept', 'application/json').expect('Content-Type', /json/).expect( 8 | 200, 9 | { 10 | success: false, 11 | error: true, 12 | message: 'Welcome to blog API', 13 | status: 200, 14 | data: null, 15 | }, 16 | done 17 | ); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /__tests__/app.test.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | 3 | import app from '@src/app'; 4 | 5 | describe('app', () => { 6 | it('responds with a not found message', (done) => { 7 | request(app) 8 | .get('/what-is-this-even') 9 | .set('Accept', 'application/json') 10 | .expect('Content-Type', /json/) 11 | .expect(404, done); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /__tests__/posts.test.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | 3 | import app from '@src/app'; 4 | 5 | describe('GET /api/v1/posts', () => { 6 | it('responds with an array of posts', async () => 7 | request(app) 8 | .get('/api/v1/posts') 9 | .set('Accept', 'application/json') 10 | .expect('Content-Type', /json/) 11 | .expect(200) 12 | .then((response) => { 13 | expect(response.body.data).toHaveProperty('length'); 14 | expect(response.body.data.length).toBe(100); 15 | expect(response.body.data[0]).toHaveProperty('userId'); 16 | expect(response.body.data[0]).toHaveProperty('title'); 17 | })); 18 | }); 19 | -------------------------------------------------------------------------------- /dist/src/api/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const express_1 = __importDefault(require("express")); 7 | const post_route_1 = __importDefault(require("@src/routes/post.route")); 8 | const auth_route_1 = __importDefault(require("@src/routes/auth.route")); 9 | const admin_route_1 = __importDefault(require("@src/routes/admin.route")); 10 | const index_1 = __importDefault(require("@src/routes/index")); 11 | const router = express_1.default.Router(); 12 | router.use('/', index_1.default); 13 | router.use('/posts', post_route_1.default); 14 | router.use('/admin', admin_route_1.default); 15 | router.use('/auth', auth_route_1.default); 16 | exports.default = router; 17 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/api/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":";;;;;AAAA,sDAA8B;AAE9B,wEAAgD;AAChD,wEAAgD;AAChD,0EAAkD;AAClD,8DAAiD;AAEjD,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAEhC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,eAAgB,CAAC,CAAC;AAClC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,oBAAU,CAAC,CAAC;AACjC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,qBAAW,CAAC,CAAC;AAClC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAU,CAAC,CAAC;AAEhC,kBAAe,MAAM,CAAC"} -------------------------------------------------------------------------------- /dist/src/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const express_1 = __importDefault(require("express")); 7 | const morgan_1 = __importDefault(require("morgan")); 8 | const helmet_1 = __importDefault(require("helmet")); 9 | const cors_1 = __importDefault(require("cors")); 10 | const dotenv_safe_1 = __importDefault(require("dotenv-safe")); 11 | const cookie_parser_1 = __importDefault(require("cookie-parser")); 12 | const swagger_ui_express_1 = __importDefault(require("swagger-ui-express")); 13 | const yamljs_1 = __importDefault(require("yamljs")); 14 | const api_1 = __importDefault(require("@src/api")); 15 | const middlewares_1 = require("@src/middlewares"); 16 | const swaggerDocument = yamljs_1.default.load(`${process.cwd()}/swagger/swagger.yaml`); 17 | dotenv_safe_1.default.config(); 18 | const app = (0, express_1.default)(); 19 | app.use((0, morgan_1.default)('dev')); 20 | app.use('/api-docs', swagger_ui_express_1.default.serve, swagger_ui_express_1.default.setup(swaggerDocument)); 21 | app.use(express_1.default.json()); 22 | app.use(express_1.default.urlencoded({ extended: true })); 23 | app.use((0, cookie_parser_1.default)()); 24 | app.use((0, helmet_1.default)({ 25 | crossOriginResourcePolicy: false, 26 | crossOriginEmbedderPolicy: false, 27 | crossOriginOpenerPolicy: false, 28 | })); 29 | app.use((0, cors_1.default)()); 30 | app.use('/static', express_1.default.static('public')); 31 | app.use('/api/v1', api_1.default); 32 | app.use(middlewares_1.notFoundMiddleware); 33 | app.use(middlewares_1.errorHandlerMiddleware); 34 | exports.default = app; 35 | //# sourceMappingURL=app.js.map -------------------------------------------------------------------------------- /dist/src/app.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":";;;;;AACA,sDAA8B;AAC9B,oDAA4B;AAC5B,oDAA4B;AAC5B,gDAAwB;AACxB,8DAAiC;AACjC,kEAAyC;AACzC,4EAA2C;AAC3C,oDAA0B;AAG1B,mDAA2B;AAG3B,kDAA8E;AAE9E,MAAM,eAAe,GAAG,gBAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;AAK3E,qBAAM,CAAC,MAAM,EAAE,CAAC;AAGhB,MAAM,GAAG,GAAoC,IAAA,iBAAO,GAAE,CAAC;AAIvD,GAAG,CAAC,GAAG,CAAC,IAAA,gBAAM,EAAC,KAAK,CAAC,CAAC,CAAC;AACvB,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,4BAAS,CAAC,KAAK,EAAE,4BAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;AACxE,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACxB,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAChD,GAAG,CAAC,GAAG,CAAC,IAAA,uBAAY,GAAE,CAAC,CAAC;AACxB,GAAG,CAAC,GAAG,CACL,IAAA,gBAAM,EAAC;IACL,yBAAyB,EAAE,KAAK;IAChC,yBAAyB,EAAE,KAAK;IAChC,uBAAuB,EAAE,KAAK;CAC/B,CAAC,CACH,CAAC;AACF,GAAG,CAAC,GAAG,CAAC,IAAA,cAAI,GAAE,CAAC,CAAC;AAEhB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,iBAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAG7C,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,aAAG,CAAC,CAAC;AACxB,GAAG,CAAC,GAAG,CAAC,gCAAkB,CAAC,CAAC;AAC5B,GAAG,CAAC,GAAG,CAAC,oCAAsB,CAAC,CAAC;AAEhC,kBAAe,GAAG,CAAC"} -------------------------------------------------------------------------------- /dist/src/configs/custom-environment-variables.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.environmentConfig = void 0; 7 | const dotenv_safe_1 = __importDefault(require("dotenv-safe")); 8 | dotenv_safe_1.default.config(); 9 | exports.environmentConfig = { 10 | MONGODB_CONNECTION_STRING: process.env.MONGODB_CONNECTION_STRING, 11 | TOKEN_SECRET: process.env.TOKEN_SECRET, 12 | WEBSITE_URL: process.env.WEBSITE_URL, 13 | API_VERSION: process.env.API_VERSION, 14 | JWT_EXPIRE_TIME: process.env.JWT_EXPIRE_TIME, 15 | PORT: process.env.PORT || 8000, 16 | SEND_GRID_API_KEY: process.env.SEND_GRID_API_KEY, 17 | ADMIN_SEND_GRID_EMAIL: process.env.ADMIN_SEND_GRID_EMAIL, 18 | ADMIN_ROLE: process.env.ADMIN_ROLE, 19 | ADMIN_EMAIL: process.env.ADMIN_EMAIL, 20 | NODE_ENV: process.env.NODE_ENV || 'development', 21 | CLIENT_URL: process.env.CLIENT_URL, 22 | ACCESS_TOKEN_SECRET_KEY: process.env.ACCESS_TOKEN_SECRET_KEY, 23 | REFRESH_TOKEN_SECRET_KEY: process.env.REFRESH_TOKEN_SECRET_KEY, 24 | ACCESS_TOKEN_KEY_EXPIRE_TIME: process.env.ACCESS_TOKEN_KEY_EXPIRE_TIME, 25 | REFRESH_TOKEN_KEY_EXPIRE_TIME: process.env.REFRESH_TOKEN_KEY_EXPIRE_TIME, 26 | JWT_ISSUER: process.env.JWT_ISSUER, 27 | REST_PASSWORD_LINK_EXPIRE_TIME: process.env.REST_PASSWORD_LINK_EXPIRE_TIME, 28 | }; 29 | exports.default = exports.environmentConfig; 30 | //# sourceMappingURL=custom-environment-variables.config.js.map -------------------------------------------------------------------------------- /dist/src/configs/custom-environment-variables.config.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"custom-environment-variables.config.js","sourceRoot":"","sources":["../../../src/configs/custom-environment-variables.config.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAiC;AAEjC,qBAAM,CAAC,MAAM,EAAE,CAAC;AAEH,QAAA,iBAAiB,GAAG;IAC/B,yBAAyB,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;IAChE,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;IACtC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;IACpC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;IACpC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;IAC5C,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI;IAC9B,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IAChD,qBAAqB,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;IACxD,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;IAClC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;IACpC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;IAC/C,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;IAClC,uBAAuB,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB;IAC5D,wBAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB;IAC9D,4BAA4B,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;IACtE,6BAA6B,EAAE,OAAO,CAAC,GAAG,CAAC,6BAA6B;IACxE,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;IAClC,8BAA8B,EAAE,OAAO,CAAC,GAAG,CAAC,8BAA8B;CAC3E,CAAC;AAEF,kBAAe,yBAAiB,CAAC"} -------------------------------------------------------------------------------- /dist/src/configs/db.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.connectDB = void 0; 7 | const mongoose_1 = __importDefault(require("mongoose")); 8 | const connectDB = (MONGODB_URI) => { 9 | mongoose_1.default.connection.on('connected', () => { 10 | console.log('MongoDB database connection established successfully'); 11 | }); 12 | mongoose_1.default.connection.on('reconnected', () => { 13 | console.log('Mongo Connection Reestablished'); 14 | }); 15 | mongoose_1.default.connection.on('error', (error) => { 16 | console.log('MongoDB connection error. Please make sure MongoDB is running: '); 17 | console.log(`Mongo Connection ERROR: ${error}`); 18 | }); 19 | mongoose_1.default.connection.on('close', () => { 20 | console.log('Mongo Connection Closed...'); 21 | }); 22 | mongoose_1.default.connection.on('disconnected', () => { 23 | console.log('MongoDB database connection is disconnected...'); 24 | console.log('Trying to reconnect to Mongo ...'); 25 | setTimeout(() => { 26 | mongoose_1.default.connect(MONGODB_URI, { 27 | keepAlive: true, 28 | socketTimeoutMS: 3000, 29 | connectTimeoutMS: 3000, 30 | useNewUrlParser: true, 31 | useUnifiedTopology: true, 32 | }); 33 | }, 3000); 34 | }); 35 | process.on('SIGINT', () => { 36 | mongoose_1.default.connection.close(() => { 37 | console.log('MongoDB database connection is disconnected due to app termination...'); 38 | process.exit(0); 39 | }); 40 | }); 41 | mongoose_1.default.connect(MONGODB_URI, { 42 | keepAlive: true, 43 | useNewUrlParser: true, 44 | useUnifiedTopology: true, 45 | }); 46 | return mongoose_1.default.connect(MONGODB_URI); 47 | }; 48 | exports.connectDB = connectDB; 49 | exports.default = exports.connectDB; 50 | //# sourceMappingURL=db.config.js.map -------------------------------------------------------------------------------- /dist/src/configs/db.config.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"db.config.js","sourceRoot":"","sources":["../../../src/configs/db.config.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA2D;AAGpD,MAAM,SAAS,GAAG,CAAC,WAAgB,EAAE,EAAE;IAE5C,kBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QACvC,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,kBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;QACzC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAGH,kBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QAC/C,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAGH,kBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACnC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAGH,kBAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;QAC1C,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,UAAU,CAAC,GAAG,EAAE;YACd,kBAAQ,CAAC,OAAO,CAAC,WAAW,EAAE;gBAC5B,SAAS,EAAE,IAAI;gBACf,eAAe,EAAE,IAAI;gBACrB,gBAAgB,EAAE,IAAI;gBACtB,eAAe,EAAE,IAAI;gBACrB,kBAAkB,EAAE,IAAI;aACP,CAAC,CAAC;QACvB,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IAGH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,kBAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE;YAC7B,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;YACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAGH,kBAAQ,CAAC,OAAO,CAAC,WAAW,EAAE;QAC5B,SAAS,EAAE,IAAI;QACf,eAAe,EAAE,IAAI;QACrB,kBAAkB,EAAE,IAAI;KACP,CAAC,CAAC;IAErB,OAAO,kBAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;AACvC,CAAC,CAAC;AApDW,QAAA,SAAS,aAoDpB;AAEF,kBAAe,iBAAS,CAAC"} -------------------------------------------------------------------------------- /dist/src/configs/indes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./custom-environment-variables.config"), exports); 18 | __exportStar(require("./db.config"), exports); 19 | //# sourceMappingURL=indes.js.map -------------------------------------------------------------------------------- /dist/src/configs/indes.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"indes.js","sourceRoot":"","sources":["../../../src/configs/indes.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wEAAsD;AACtD,8CAA4B"} -------------------------------------------------------------------------------- /dist/src/controllers/admin.controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getUsersController = void 0; 4 | const services_1 = require("@src/services"); 5 | const getUsersController = (req, res, next) => (0, services_1.getUsersService)(req, res, next); 6 | exports.getUsersController = getUsersController; 7 | exports.default = { 8 | getUsersController: exports.getUsersController, 9 | }; 10 | //# sourceMappingURL=admin.controller.js.map -------------------------------------------------------------------------------- /dist/src/controllers/admin.controller.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"admin.controller.js","sourceRoot":"","sources":["../../../src/controllers/admin.controller.ts"],"names":[],"mappings":";;;AAEA,4CAAgD;AAEzC,MAAM,kBAAkB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAAC,IAAA,0BAAe,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAA1G,QAAA,kBAAkB,sBAAwF;AAEvH,kBAAe;IACb,kBAAkB,EAAlB,0BAAkB;CACnB,CAAC"} -------------------------------------------------------------------------------- /dist/src/controllers/auth.controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.resetPasswordController = exports.sendForgotPasswordMailController = exports.refreshTokenController = exports.verifyEmailController = exports.getAuthProfileController = exports.removeAuthController = exports.updateAuthController = exports.logoutController = exports.loginController = exports.signupController = void 0; 4 | const services_1 = require("@src/services"); 5 | const signupController = (req, res, next) => (0, services_1.signupService)(req, res, next); 6 | exports.signupController = signupController; 7 | const loginController = (req, res, next) => (0, services_1.loginService)(req, res, next); 8 | exports.loginController = loginController; 9 | const logoutController = (req, res, next) => (0, services_1.logoutService)(req, res, next); 10 | exports.logoutController = logoutController; 11 | const updateAuthController = (req, res, next) => (0, services_1.updateAuthService)(req, res, next); 12 | exports.updateAuthController = updateAuthController; 13 | const removeAuthController = (req, res, next) => (0, services_1.removeAuthService)(req, res, next); 14 | exports.removeAuthController = removeAuthController; 15 | const getAuthProfileController = (req, res, next) => (0, services_1.getAuthProfileService)(req, res, next); 16 | exports.getAuthProfileController = getAuthProfileController; 17 | const verifyEmailController = (req, res, next) => (0, services_1.verifyEmailService)(req, res, next); 18 | exports.verifyEmailController = verifyEmailController; 19 | const refreshTokenController = async (req, res, next) => (0, services_1.refreshTokenService)(req, res, next); 20 | exports.refreshTokenController = refreshTokenController; 21 | const sendForgotPasswordMailController = async (req, res, next) => (0, services_1.sendForgotPasswordMailService)(req, res, next); 22 | exports.sendForgotPasswordMailController = sendForgotPasswordMailController; 23 | const resetPasswordController = async (req, res, next) => (0, services_1.resetPasswordService)(req, res, next); 24 | exports.resetPasswordController = resetPasswordController; 25 | exports.default = { 26 | signupController: exports.signupController, 27 | loginController: exports.loginController, 28 | logoutController: exports.logoutController, 29 | updateAuthController: exports.updateAuthController, 30 | removeAuthController: exports.removeAuthController, 31 | verifyEmailController: exports.verifyEmailController, 32 | refreshTokenController: exports.refreshTokenController, 33 | sendForgotPasswordMailController: exports.sendForgotPasswordMailController, 34 | resetPasswordController: exports.resetPasswordController, 35 | getAuthProfileController: exports.getAuthProfileController, 36 | }; 37 | //# sourceMappingURL=auth.controller.js.map -------------------------------------------------------------------------------- /dist/src/controllers/auth.controller.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"auth.controller.js","sourceRoot":"","sources":["../../../src/controllers/auth.controller.ts"],"names":[],"mappings":";;;AAEA,4CAWuB;AAGhB,MAAM,gBAAgB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAAC,IAAA,wBAAa,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAAtG,QAAA,gBAAgB,oBAAsF;AAE5G,MAAM,eAAe,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAAC,IAAA,uBAAY,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAApG,QAAA,eAAe,mBAAqF;AAE1G,MAAM,gBAAgB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAAC,IAAA,wBAAa,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAAtG,QAAA,gBAAgB,oBAAsF;AAE5G,MAAM,oBAAoB,GAAG,CAAC,GAAoC,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAC9G,IAAA,4BAAiB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AADvB,QAAA,oBAAoB,wBACG;AAE7B,MAAM,oBAAoB,GAAG,CAAC,GAAoC,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAC9G,IAAA,4BAAiB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AADvB,QAAA,oBAAoB,wBACG;AAE7B,MAAM,wBAAwB,GAAG,CAAC,GAAoC,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAClH,IAAA,gCAAqB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAD3B,QAAA,wBAAwB,4BACG;AAEjC,MAAM,qBAAqB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CACvF,IAAA,6BAAkB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AADxB,QAAA,qBAAqB,yBACG;AAE9B,MAAM,sBAAsB,GAAmB,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAA,8BAAmB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAAvG,QAAA,sBAAsB,0BAAiF;AAE7G,MAAM,gCAAgC,GAAmB,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CACvF,IAAA,wCAA6B,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AADnC,QAAA,gCAAgC,oCACG;AAEzC,MAAM,uBAAuB,GAAmB,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAA,+BAAoB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAAzG,QAAA,uBAAuB,2BAAkF;AAEtH,kBAAe;IACb,gBAAgB,EAAhB,wBAAgB;IAChB,eAAe,EAAf,uBAAe;IACf,gBAAgB,EAAhB,wBAAgB;IAChB,oBAAoB,EAApB,4BAAoB;IACpB,oBAAoB,EAApB,4BAAoB;IACpB,qBAAqB,EAArB,6BAAqB;IACrB,sBAAsB,EAAtB,8BAAsB;IACtB,gCAAgC,EAAhC,wCAAgC;IAChC,uBAAuB,EAAvB,+BAAuB;IACvB,wBAAwB,EAAxB,gCAAwB;CACzB,CAAC"} -------------------------------------------------------------------------------- /dist/src/controllers/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./admin.controller"), exports); 18 | __exportStar(require("./auth.controller"), exports); 19 | __exportStar(require("./post.controller"), exports); 20 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/controllers/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,oDAAkC;AAClC,oDAAkC"} -------------------------------------------------------------------------------- /dist/src/controllers/post.controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.editPostController = exports.deletePostController = exports.createPostController = exports.getPostController = exports.getPostsController = void 0; 4 | const services_1 = require("@src/services"); 5 | const getPostsController = (req, res) => (0, services_1.getPostsService)(req, res); 6 | exports.getPostsController = getPostsController; 7 | const getPostController = (req, res, next) => (0, services_1.getPostService)(req, res, next); 8 | exports.getPostController = getPostController; 9 | const createPostController = (req, res, next) => (0, services_1.createPostService)(req, res, next); 10 | exports.createPostController = createPostController; 11 | const deletePostController = (req, res, next) => (0, services_1.deletePostService)(req, res, next); 12 | exports.deletePostController = deletePostController; 13 | const editPostController = (req, res, next) => (0, services_1.editPostService)(req, res, next); 14 | exports.editPostController = editPostController; 15 | exports.default = { 16 | getPostsController: exports.getPostsController, 17 | createPostController: exports.createPostController, 18 | getPostController: exports.getPostController, 19 | deletePostController: exports.deletePostController, 20 | editPostController: exports.editPostController, 21 | }; 22 | //# sourceMappingURL=post.controller.js.map -------------------------------------------------------------------------------- /dist/src/controllers/post.controller.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"post.controller.js","sourceRoot":"","sources":["../../../src/controllers/post.controller.ts"],"names":[],"mappings":";;;AAEA,4CAAuH;AAGhH,MAAM,kBAAkB,GAAG,CAAC,GAAY,EAAE,GAAwB,EAAE,EAAE,CAAC,IAAA,0BAAe,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAA3F,QAAA,kBAAkB,sBAAyE;AACjG,MAAM,iBAAiB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAAC,IAAA,yBAAc,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAAxG,QAAA,iBAAiB,qBAAuF;AAC9G,MAAM,oBAAoB,GAAG,CAAC,GAAoC,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAC9G,IAAA,4BAAiB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AADvB,QAAA,oBAAoB,wBACG;AAC7B,MAAM,oBAAoB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CACtF,IAAA,4BAAiB,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AADvB,QAAA,oBAAoB,wBACG;AAC7B,MAAM,kBAAkB,GAAG,CAAC,GAAoC,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE,CAC5G,IAAA,0BAAe,EAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AADrB,QAAA,kBAAkB,sBACG;AAElC,kBAAe;IACb,kBAAkB,EAAlB,0BAAkB;IAClB,oBAAoB,EAApB,4BAAoB;IACpB,iBAAiB,EAAjB,yBAAiB;IACjB,oBAAoB,EAApB,4BAAoB;IACpB,kBAAkB,EAAlB,0BAAkB;CACnB,CAAC"} -------------------------------------------------------------------------------- /dist/src/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const app_1 = __importDefault(require("@src/app")); 7 | const custom_environment_variables_config_1 = require("@src/configs/custom-environment-variables.config"); 8 | const db_config_1 = require("@src/configs/db.config"); 9 | const start = async () => { 10 | try { 11 | await (0, db_config_1.connectDB)(custom_environment_variables_config_1.environmentConfig.MONGODB_CONNECTION_STRING); 12 | console.log('MongoDB database connection established successfully to... '); 13 | app_1.default?.listen(custom_environment_variables_config_1.environmentConfig.PORT, () => { 14 | console.log(`Listening: http://localhost:${custom_environment_variables_config_1.environmentConfig.PORT}`); 15 | }); 16 | } 17 | catch (error) { 18 | console.log('MongoDB connection error. Please make sure MongoDB is running: '); 19 | } 20 | }; 21 | start(); 22 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;AAAA,mDAA2B;AAC3B,0GAAqF;AACrF,sDAAmD;AAGnD,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;IACvB,IAAI;QACF,MAAM,IAAA,qBAAS,EAAC,uDAAiB,CAAC,yBAAyB,CAAC,CAAC;QAE7D,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;QAE3E,aAAG,EAAE,MAAM,CAAC,uDAAiB,CAAC,IAAI,EAAE,GAAG,EAAE;YACvC,OAAO,CAAC,GAAG,CAAC,+BAA+B,uDAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;KACJ;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;KAChF;AACH,CAAC,CAAC;AAGF,KAAK,EAAE,CAAC"} -------------------------------------------------------------------------------- /dist/src/interfaces/ErrorResponse.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=ErrorResponse.js.map -------------------------------------------------------------------------------- /dist/src/interfaces/ErrorResponse.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ErrorResponse.js","sourceRoot":"","sources":["../../../src/interfaces/ErrorResponse.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/src/interfaces/MessageResponse.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=MessageResponse.js.map -------------------------------------------------------------------------------- /dist/src/interfaces/MessageResponse.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"MessageResponse.js","sourceRoot":"","sources":["../../../src/interfaces/MessageResponse.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/src/interfaces/Post.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=Post.js.map -------------------------------------------------------------------------------- /dist/src/interfaces/Post.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Post.js","sourceRoot":"","sources":["../../../src/interfaces/Post.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/src/interfaces/User.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | //# sourceMappingURL=User.js.map -------------------------------------------------------------------------------- /dist/src/interfaces/User.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"User.js","sourceRoot":"","sources":["../../../src/interfaces/User.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/src/interfaces/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./ErrorResponse"), exports); 18 | __exportStar(require("./MessageResponse"), exports); 19 | __exportStar(require("./Post"), exports); 20 | __exportStar(require("./User"), exports); 21 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/interfaces/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kDAAgC;AAChC,oDAAkC;AAClC,yCAAuB;AACvB,yCAAuB"} -------------------------------------------------------------------------------- /dist/src/middlewares/auth/checkIsAdmin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.isAdmin = void 0; 7 | const http_errors_1 = __importDefault(require("http-errors")); 8 | const custom_environment_variables_config_1 = require("@src/configs/custom-environment-variables.config"); 9 | const isAdmin = async (req, res, next) => { 10 | const user = req?.user; 11 | const adminUser = user && user.role === custom_environment_variables_config_1.environmentConfig.ADMIN_ROLE && custom_environment_variables_config_1.environmentConfig?.ADMIN_EMAIL?.includes(`${user?.email}`); 12 | if (!adminUser) { 13 | return next((0, http_errors_1.default)(403, `Auth Failed (Unauthorized)`)); 14 | } 15 | next(); 16 | }; 17 | exports.isAdmin = isAdmin; 18 | exports.default = { isAdmin: exports.isAdmin }; 19 | //# sourceMappingURL=checkIsAdmin.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/auth/checkIsAdmin.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"checkIsAdmin.js","sourceRoot":"","sources":["../../../../src/middlewares/auth/checkIsAdmin.ts"],"names":[],"mappings":";;;;;;AACA,8DAA0C;AAE1C,0GAAqF;AAG9E,MAAM,OAAO,GAAG,KAAK,EAAE,GAAkB,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACrF,MAAM,IAAI,GAAG,GAAG,EAAE,IAAI,CAAC;IAEvB,MAAM,SAAS,GACb,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,uDAAiB,CAAC,UAAU,IAAI,uDAAiB,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEnH,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,IAAI,CAAC,IAAA,qBAAe,EAAC,GAAG,EAAE,4BAA4B,CAAC,CAAC,CAAC;KACjE;IAED,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAXW,QAAA,OAAO,WAWlB;AAEF,kBAAe,EAAE,OAAO,EAAP,eAAO,EAAE,CAAC"} -------------------------------------------------------------------------------- /dist/src/middlewares/auth/checkIsAuth.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | exports.isAuth = void 0; 30 | const jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); 31 | const http_errors_1 = __importStar(require("http-errors")); 32 | const User_model_1 = __importDefault(require("@src/models/User.model")); 33 | const custom_environment_variables_config_1 = require("@src/configs/custom-environment-variables.config"); 34 | const isAuth = async (req, res, next) => { 35 | const authHeader = (req && req.headers.authorization) || (req && req.headers.Authorization); 36 | const token = (authHeader && authHeader.split(' ')[1]) || req?.cookies?.authToken || ''; 37 | if (!token) { 38 | return next((0, http_errors_1.default)(401, 'Auth Failed (Invalid Credentials)')); 39 | } 40 | jsonwebtoken_1.default.verify(token, custom_environment_variables_config_1.environmentConfig.ACCESS_TOKEN_SECRET_KEY, async (err, decodedUser) => { 41 | if (err) { 42 | const errorMessage = err.name === 'JsonWebTokenError' ? 'Auth Failed (Unauthorized)' : err.message; 43 | return next((0, http_errors_1.default)(403, errorMessage)); 44 | } 45 | try { 46 | const decodedUserInDB = await User_model_1.default.findOne({ _id: decodedUser?.userId }); 47 | if (!decodedUserInDB) { 48 | return next((0, http_errors_1.default)(403, `Auth Failed (Unauthorized)`)); 49 | } 50 | req.user = decodedUserInDB; 51 | next(); 52 | } 53 | catch (error) { 54 | return next(http_errors_1.InternalServerError); 55 | } 56 | }); 57 | }; 58 | exports.isAuth = isAuth; 59 | exports.default = { isAuth: exports.isAuth }; 60 | //# sourceMappingURL=checkIsAuth.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/auth/checkIsAuth.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"checkIsAuth.js","sourceRoot":"","sources":["../../../../src/middlewares/auth/checkIsAuth.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gEAAiD;AAEjD,2DAAmE;AAEnE,wEAA0C;AAC1C,0GAAqF;AAG9E,MAAM,MAAM,GAAG,KAAK,EAAE,GAAiB,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACnF,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAG,CAAC,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;IAExF,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,IAAI,CAAC,IAAA,qBAAe,EAAC,GAAG,EAAE,mCAAmC,CAAC,CAAC,CAAC;KACxE;IAED,sBAAG,CAAC,MAAM,CACR,KAAK,EACL,uDAAiB,CAAC,uBAAqC,EACvD,KAAK,EAAE,GAAwB,EAAE,WAAgB,EAAE,EAAE;QACnD,IAAI,GAAG,EAAE;YAEP,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;YAEnG,OAAO,IAAI,CAAC,IAAA,qBAAe,EAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;SACjD;QAED,IAAI;YACF,MAAM,eAAe,GAAG,MAAM,oBAAI,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;YAEzE,IAAI,CAAC,eAAe,EAAE;gBACpB,OAAO,IAAI,CAAC,IAAA,qBAAe,EAAC,GAAG,EAAE,4BAA4B,CAAC,CAAC,CAAC;aACjE;YAGD,GAAG,CAAC,IAAI,GAAG,eAAwB,CAAC;YAGpC,IAAI,EAAE,CAAC;SACR;QAAC,OAAO,KAAK,EAAE;YACd,OAAO,IAAI,CAAC,iCAAmB,CAAC,CAAC;SAClC;IACH,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AApCW,QAAA,MAAM,UAoCjB;AAEF,kBAAe,EAAE,MAAM,EAAN,cAAM,EAAE,CAAC"} -------------------------------------------------------------------------------- /dist/src/middlewares/auth/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./checkIsAdmin"), exports); 18 | __exportStar(require("./checkIsAuth"), exports); 19 | __exportStar(require("./verifyRefreshToken"), exports); 20 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/auth/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/middlewares/auth/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,gDAA8B;AAC9B,uDAAqC"} -------------------------------------------------------------------------------- /dist/src/middlewares/auth/verifyRefreshToken.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.verifyRefreshToken = void 0; 7 | const jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); 8 | const custom_environment_variables_config_1 = require("@src/configs/custom-environment-variables.config"); 9 | const verifyRefreshToken = async function (refreshToken) { 10 | return new Promise(function (resolve, reject) { 11 | jsonwebtoken_1.default.verify(refreshToken, custom_environment_variables_config_1.environmentConfig.REFRESH_TOKEN_SECRET_KEY, (err, payload) => { 12 | if (err) { 13 | return reject(err); 14 | } 15 | console.log(payload.aud); 16 | const userId = payload.aud; 17 | resolve(userId); 18 | }); 19 | }); 20 | }; 21 | exports.verifyRefreshToken = verifyRefreshToken; 22 | exports.default = exports.verifyRefreshToken; 23 | //# sourceMappingURL=verifyRefreshToken.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/auth/verifyRefreshToken.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"verifyRefreshToken.js","sourceRoot":"","sources":["../../../../src/middlewares/auth/verifyRefreshToken.ts"],"names":[],"mappings":";;;;;;AAAA,gEAAiD;AAEjD,0GAAqF;AAE9E,MAAM,kBAAkB,GAAG,KAAK,WAAW,YAAiB;IACjE,OAAO,IAAI,OAAO,CAAC,UAAU,OAAO,EAAE,MAAM;QAC1C,sBAAG,CAAC,MAAM,CACR,YAAY,EACZ,uDAAiB,CAAC,wBAAsC,EACxD,CAAC,GAAwB,EAAE,OAAY,EAAE,EAAE;YACzC,IAAI,GAAG,EAAE;gBACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;aACpB;YAED,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACzB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAhBW,QAAA,kBAAkB,sBAgB7B;AAEF,kBAAe,0BAAkB,CAAC"} -------------------------------------------------------------------------------- /dist/src/middlewares/errors/errorHandler.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.errorHandlerMiddleware = void 0; 4 | const errorHandlerMiddleware = (error, req, res, next) => { 5 | const statusCode = error.statusCode || 500; 6 | res?.status(statusCode); 7 | res?.status(statusCode).send({ 8 | data: null, 9 | success: false, 10 | error: true, 11 | message: error.message || 'Internal Server Error', 12 | status: statusCode, 13 | stack: process.env.NODE_ENV === 'production' ? '' : error.stack, 14 | }); 15 | }; 16 | exports.errorHandlerMiddleware = errorHandlerMiddleware; 17 | exports.default = exports.errorHandlerMiddleware; 18 | //# sourceMappingURL=errorHandler.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/errors/errorHandler.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../../../src/middlewares/errors/errorHandler.ts"],"names":[],"mappings":";;;AAGO,MAAM,sBAAsB,GAAwB,CACzD,KAAK,EACL,GAAG,EACH,GAA4B,EAE5B,IAAkB,EAClB,EAAE;IACF,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;IAC3C,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC3B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,uBAAuB;QACjD,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK;KAChE,CAAC,CAAC;AACL,CAAC,CAAC;AAjBW,QAAA,sBAAsB,0BAiBjC;AAEF,kBAAe,8BAAsB,CAAC"} -------------------------------------------------------------------------------- /dist/src/middlewares/errors/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./errorHandler"), exports); 18 | __exportStar(require("./notFound"), exports); 19 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/errors/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/middlewares/errors/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B;AAC/B,6CAA2B"} -------------------------------------------------------------------------------- /dist/src/middlewares/errors/notFound.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.notFoundMiddleware = void 0; 4 | function notFoundMiddleware(req, res, next) { 5 | res.status(404); 6 | const error = new Error(`Route - ${req.originalUrl} Not Found`); 7 | next(error); 8 | } 9 | exports.notFoundMiddleware = notFoundMiddleware; 10 | exports.default = notFoundMiddleware; 11 | //# sourceMappingURL=notFound.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/errors/notFound.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"notFound.js","sourceRoot":"","sources":["../../../../src/middlewares/errors/notFound.ts"],"names":[],"mappings":";;;AAEA,SAAgB,kBAAkB,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IAChF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,WAAW,aAAa,CAAC,CAAC;IAEjE,IAAI,CAAC,KAAK,CAAC,CAAC;AACd,CAAC;AALD,gDAKC;AAED,kBAAe,kBAAkB,CAAC"} -------------------------------------------------------------------------------- /dist/src/middlewares/file-upload/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./uploadImage.middleware"), exports); 18 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/file-upload/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/middlewares/file-upload/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC"} -------------------------------------------------------------------------------- /dist/src/middlewares/file-upload/uploadImage.middleware.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.uploadImage = exports.fileStorage = void 0; 7 | const multer_1 = __importDefault(require("multer")); 8 | const utils_1 = require("@src/utils"); 9 | exports.fileStorage = multer_1.default.diskStorage({ 10 | destination: (request, file, callback) => { 11 | callback(null, 'public/uploads/posts'); 12 | }, 13 | filename: (req, file, callback) => { 14 | callback(null, `${file.fieldname}-${Date.now()}${(0, utils_1.getImageExtension)(file.mimetype)}`); 15 | }, 16 | }); 17 | exports.uploadImage = (0, multer_1.default)({ 18 | storage: exports.fileStorage, 19 | limits: { 20 | fileSize: 1024 * 1024 * 10, 21 | }, 22 | }); 23 | exports.default = { uploadImage: exports.uploadImage }; 24 | //# sourceMappingURL=uploadImage.middleware.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/file-upload/uploadImage.middleware.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"uploadImage.middleware.js","sourceRoot":"","sources":["../../../../src/middlewares/file-upload/uploadImage.middleware.ts"],"names":[],"mappings":";;;;;;AAEA,oDAA4B;AAE5B,sCAA+C;AAOlC,QAAA,WAAW,GAAG,gBAAM,CAAC,WAAW,CAAC;IAC5C,WAAW,EAAE,CAAC,OAAgB,EAAE,IAAyB,EAAE,QAA6B,EAAQ,EAAE;QAChG,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;IACzC,CAAC;IAED,QAAQ,EAAE,CAAC,GAAY,EAAE,IAAyB,EAAE,QAA0B,EAAQ,EAAE;QACtF,QAAQ,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAA,yBAAiB,EAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvF,CAAC;CACF,CAAC,CAAC;AAGU,QAAA,WAAW,GAAG,IAAA,gBAAM,EAAC;IAChC,OAAO,EAAE,mBAAW;IACpB,MAAM,EAAE;QACN,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,EAAE;KAC3B;CACF,CAAC,CAAC;AAEH,kBAAe,EAAE,WAAW,EAAX,mBAAW,EAAE,CAAC"} -------------------------------------------------------------------------------- /dist/src/middlewares/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./auth"), exports); 18 | __exportStar(require("./errors"), exports); 19 | __exportStar(require("./file-upload"), exports); 20 | __exportStar(require("./sort-filter-pagination"), exports); 21 | __exportStar(require("./validation/authValidation"), exports); 22 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/middlewares/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,2CAAyB;AACzB,gDAA8B;AAC9B,2DAAyC;AACzC,8DAA4C"} -------------------------------------------------------------------------------- /dist/src/middlewares/sort-filter-pagination/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./postsFeatures.middleware"), exports); 18 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/sort-filter-pagination/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/middlewares/sort-filter-pagination/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA2C"} -------------------------------------------------------------------------------- /dist/src/middlewares/sort-filter-pagination/postsFeatures.middleware.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.postsPaginationMiddleware = void 0; 7 | const Post_model_1 = __importDefault(require("@src/models/Post.model")); 8 | const postsPaginationMiddleware = () => { 9 | return async (req, res, next) => { 10 | const page = Number(req.query.page) || 1; 11 | const limit = Number(req.query.limit) || 2; 12 | const startIndex = (page - 1) * limit; 13 | const endIndex = page * limit; 14 | const results = { 15 | currentPage: { 16 | page, 17 | limit, 18 | }, 19 | totalDocs: 0, 20 | }; 21 | const totalCount = await Post_model_1.default.countDocuments().exec(); 22 | results.totalDocs = totalCount; 23 | if (endIndex < totalCount) { 24 | results.next = { 25 | page: page + 1, 26 | limit, 27 | }; 28 | } 29 | if (startIndex > 0) { 30 | results.previous = { 31 | page: page - 1, 32 | limit, 33 | }; 34 | } 35 | results.totalPages = Math.ceil(totalCount / limit); 36 | results.lastPage = Math.ceil(totalCount / limit); 37 | const sort = {}; 38 | if (req.query.sortBy && req.query.orderBy) { 39 | sort[req.query.sortBy] = req.query.orderBy.toLowerCase() === 'desc' ? -1 : 1; 40 | } 41 | else { 42 | sort.createdAt = -1; 43 | } 44 | let filter = {}; 45 | if (req.query.filterBy && req.query.category) { 46 | console.log(req.query.category.toLowerCase()); 47 | if (req.query.category.toLowerCase() === 'sports') { 48 | filter.$or = [{ category: 'sports' }]; 49 | } 50 | else if (req.query.category.toLowerCase() === 'coding') { 51 | filter.$or = [{ category: 'coding' }]; 52 | } 53 | else if (req.query.category.toLowerCase() === 'typescript') { 54 | filter.$or = [{ category: 'typescript' }]; 55 | } 56 | else if (req.query.category.toLowerCase() === 'nodejs') { 57 | filter.$or = [{ category: 'nodejs' }]; 58 | } 59 | else if (req.query.category.toLowerCase() === 'all') { 60 | filter = {}; 61 | } 62 | else { 63 | filter = {}; 64 | } 65 | } 66 | if (req.query.search) { 67 | filter = { 68 | $or: [ 69 | { title: { $regex: req.query.search } }, 70 | { content: { $regex: req.query.search } }, 71 | { category: { $regex: req.query.search } }, 72 | ], 73 | }; 74 | } 75 | try { 76 | results.results = await Post_model_1.default 77 | .find(filter) 78 | .select('title content postImage author createdAt updatedAt, category') 79 | .populate('author', 'name firstName lastName surname email dateOfBirth gender joinedDate isVerified profileImage mobileNumber status role companyName acceptTerms nationality favoriteAnimal address bio') 80 | .limit(limit) 81 | .sort(sort) 82 | .skip(startIndex) 83 | .exec(); 84 | res.paginatedResults = results; 85 | next(); 86 | } 87 | catch (error) { 88 | return next(error); 89 | } 90 | }; 91 | }; 92 | exports.postsPaginationMiddleware = postsPaginationMiddleware; 93 | exports.default = exports.postsPaginationMiddleware; 94 | //# sourceMappingURL=postsFeatures.middleware.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/sort-filter-pagination/postsFeatures.middleware.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"postsFeatures.middleware.js","sourceRoot":"","sources":["../../../../src/middlewares/sort-filter-pagination/postsFeatures.middleware.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/src/middlewares/validation/authValidation/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./userSchema"), exports); 18 | __exportStar(require("./userValidation"), exports); 19 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/validation/authValidation/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/middlewares/validation/authValidation/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,mDAAiC"} -------------------------------------------------------------------------------- /dist/src/middlewares/validation/authValidation/userSchema.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.userSchema = void 0; 7 | const joi_1 = __importDefault(require("joi")); 8 | const joi_objectid_1 = __importDefault(require("joi-objectid")); 9 | const vaildObjectId = (0, joi_objectid_1.default)(joi_1.default); 10 | exports.userSchema = { 11 | signupUser: joi_1.default.object({ 12 | name: joi_1.default.string().min(3).max(15).required(), 13 | email: joi_1.default.string().email().required(), 14 | password: joi_1.default.string().min(6).required(), 15 | confirmPassword: joi_1.default.string().required().valid(joi_1.default.ref('password')), 16 | firstName: joi_1.default.string().min(3).max(15), 17 | lastName: joi_1.default.string().min(3).max(15), 18 | familyName: joi_1.default.string().min(3).max(15), 19 | companyName: joi_1.default.string(), 20 | dateOfBirth: joi_1.default.string(), 21 | mobileNumber: joi_1.default.string(), 22 | gender: joi_1.default.string(), 23 | profileImage: joi_1.default.string(), 24 | role: joi_1.default.string(), 25 | favoriteAnimal: joi_1.default.string(), 26 | nationality: joi_1.default.string(), 27 | isVerified: joi_1.default.boolean(), 28 | isDeleted: joi_1.default.boolean(), 29 | status: joi_1.default.string(), 30 | bio: joi_1.default.string().min(10).max(300), 31 | jobTitle: joi_1.default.string().min(2).max(300), 32 | address: joi_1.default.string(), 33 | acceptTerms: joi_1.default.boolean(), 34 | confirmationCode: joi_1.default.string(), 35 | }), 36 | loginUser: joi_1.default.object({ 37 | email: joi_1.default.string().email().required(), 38 | password: joi_1.default.string().min(6).required(), 39 | }), 40 | updateUser: joi_1.default.object({ 41 | name: joi_1.default.string().min(3).max(15), 42 | email: joi_1.default.string().email(), 43 | firstName: joi_1.default.string().min(3).max(15), 44 | lastName: joi_1.default.string().min(3).max(15), 45 | familyName: joi_1.default.string().min(3).max(15), 46 | companyName: joi_1.default.string(), 47 | dateOfBirth: joi_1.default.string(), 48 | mobileNumber: joi_1.default.string(), 49 | gender: joi_1.default.string(), 50 | profileImage: joi_1.default.string(), 51 | role: joi_1.default.string(), 52 | favoriteAnimal: joi_1.default.string(), 53 | nationality: joi_1.default.string(), 54 | isVerified: joi_1.default.boolean(), 55 | isDeleted: joi_1.default.boolean(), 56 | status: joi_1.default.string(), 57 | bio: joi_1.default.string().min(10).max(300), 58 | jobTitle: joi_1.default.string().min(2).max(300), 59 | address: joi_1.default.string(), 60 | acceptTerms: joi_1.default.boolean(), 61 | confirmationCode: joi_1.default.string(), 62 | }), 63 | verifyUserMail: joi_1.default.object({ 64 | token: joi_1.default.string().min(3).max(300).required(), 65 | userId: vaildObjectId().required(), 66 | }), 67 | refreshToken: joi_1.default.object({ 68 | refreshToken: joi_1.default.string().min(3).max(300).required(), 69 | }), 70 | sendVerificationMail: joi_1.default.object({ 71 | email: joi_1.default.string().email().required(), 72 | }), 73 | resetPassword: joi_1.default.object({ 74 | token: joi_1.default.string().min(3).max(300).required(), 75 | userId: vaildObjectId().required(), 76 | password: joi_1.default.string().min(6).required(), 77 | confirmPassword: joi_1.default.string().required().valid(joi_1.default.ref('password')), 78 | }), 79 | }; 80 | exports.default = exports.userSchema; 81 | //# sourceMappingURL=userSchema.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/validation/authValidation/userSchema.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"userSchema.js","sourceRoot":"","sources":["../../../../../src/middlewares/validation/authValidation/userSchema.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/src/middlewares/validation/authValidation/userValidation.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.resetPasswordValidation = exports.sendVerificationMailValidation = exports.refreshTokenValidation = exports.verifyUserMailValidation = exports.updateUserValidation = exports.loginUserValidation = exports.signupUserValidation = void 0; 7 | const mongoose_1 = __importDefault(require("mongoose")); 8 | const validator_1 = __importDefault(require("../validator")); 9 | const userSchema_1 = require("./userSchema"); 10 | const signupUserValidation = (req, res, next) => (0, validator_1.default)(userSchema_1.userSchema.signupUser, req.body, next); 11 | exports.signupUserValidation = signupUserValidation; 12 | const loginUserValidation = (req, res, next) => (0, validator_1.default)(userSchema_1.userSchema.loginUser, req.body, next); 13 | exports.loginUserValidation = loginUserValidation; 14 | const updateUserValidation = (req, res, next) => (0, validator_1.default)(userSchema_1.userSchema.updateUser, req.body, next); 15 | exports.updateUserValidation = updateUserValidation; 16 | const verifyUserMailValidation = (req, res, next) => { 17 | console.log(mongoose_1.default.Types.ObjectId.isValid(req.params.userId)); 18 | return (0, validator_1.default)(userSchema_1.userSchema.verifyUserMail, req.params, next); 19 | }; 20 | exports.verifyUserMailValidation = verifyUserMailValidation; 21 | const refreshTokenValidation = (req, res, next) => (0, validator_1.default)(userSchema_1.userSchema.refreshToken, req.body, next); 22 | exports.refreshTokenValidation = refreshTokenValidation; 23 | const sendVerificationMailValidation = (req, res, next) => (0, validator_1.default)(userSchema_1.userSchema.sendVerificationMail, req.body, next); 24 | exports.sendVerificationMailValidation = sendVerificationMailValidation; 25 | const resetPasswordValidation = (req, res, next) => (0, validator_1.default)(userSchema_1.userSchema.resetPassword, { ...req.body, ...req.params }, next); 26 | exports.resetPasswordValidation = resetPasswordValidation; 27 | //# sourceMappingURL=userValidation.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/validation/authValidation/userValidation.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"userValidation.js","sourceRoot":"","sources":["../../../../../src/middlewares/validation/authValidation/userValidation.ts"],"names":[],"mappings":";;;;;;AACA,wDAAgC;AAChC,6DAAqC;AACrC,6CAA0C;AAEnC,MAAM,oBAAoB,GAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CACrE,IAAA,mBAAS,EAAC,uBAAU,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AADtC,QAAA,oBAAoB,wBACkB;AAE5C,MAAM,mBAAmB,GAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAA,mBAAS,EAAC,uBAAU,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAA1G,QAAA,mBAAmB,uBAAuF;AAEhH,MAAM,oBAAoB,GAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CACrE,IAAA,mBAAS,EAAC,uBAAU,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AADtC,QAAA,oBAAoB,wBACkB;AAE5C,MAAM,wBAAwB,GAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACzE,OAAO,CAAC,GAAG,CAAC,kBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,OAAO,IAAA,mBAAS,EAAC,uBAAU,CAAC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAChE,CAAC,CAAC;AAHW,QAAA,wBAAwB,4BAGnC;AAEK,MAAM,sBAAsB,GAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CACvE,IAAA,mBAAS,EAAC,uBAAU,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AADxC,QAAA,sBAAsB,0BACkB;AAE9C,MAAM,8BAA8B,GAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAC/E,IAAA,mBAAS,EAAC,uBAAU,CAAC,oBAAoB,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AADhD,QAAA,8BAA8B,kCACkB;AAEtD,MAAM,uBAAuB,GAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CACxE,IAAA,mBAAS,EAAC,uBAAU,CAAC,aAAa,EAAE,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;AAD/D,QAAA,uBAAuB,2BACwC"} -------------------------------------------------------------------------------- /dist/src/middlewares/validation/validator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const http_errors_1 = __importDefault(require("http-errors")); 7 | const validator = async (schemaName, body, next) => { 8 | const value = await schemaName.validate(body, { 9 | abortEarly: false, 10 | allowUnknown: true, 11 | stripUnknown: true, 12 | }); 13 | try { 14 | value.error ? next((0, http_errors_1.default)(422, value.error.details[0].message)) : next(); 15 | } 16 | catch (error) { 17 | console.log(error); 18 | } 19 | }; 20 | exports.default = validator; 21 | //# sourceMappingURL=validator.js.map -------------------------------------------------------------------------------- /dist/src/middlewares/validation/validator.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../../src/middlewares/validation/validator.ts"],"names":[],"mappings":";;;;;AAAA,8DAA0C;AAI1C,MAAM,SAAS,GAAG,KAAK,EAAE,UAA4B,EAAE,IAAY,EAAE,IAAkB,EAAE,EAAE;IACzF,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE;QAC5C,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,IAAI;QAEF,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAA,qBAAe,EAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;KACnF;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC"} -------------------------------------------------------------------------------- /dist/src/models/Post.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | exports.PostSchema = void 0; 27 | const mongoose_1 = __importStar(require("mongoose")); 28 | exports.PostSchema = new mongoose_1.Schema({ 29 | title: { 30 | type: String, 31 | trim: true, 32 | required: [true, 'Please provide title'], 33 | }, 34 | content: { 35 | type: String, 36 | trim: true, 37 | required: [true, 'Please provide post description'], 38 | }, 39 | postImage: { type: String, required: true }, 40 | author: { 41 | type: mongoose_1.default.Schema.Types.ObjectId, 42 | ref: 'User', 43 | required: [true, 'author is required'], 44 | }, 45 | category: { 46 | type: String, 47 | lowercase: true, 48 | enum: ['coding', 'sports', 'nodejs', 'all', 'typescript'], 49 | default: 'all', 50 | trim: true, 51 | }, 52 | }, { 53 | timestamps: true, 54 | versionKey: false, 55 | }); 56 | exports.default = mongoose_1.default.models.Post || mongoose_1.default.model('Post', exports.PostSchema); 57 | //# sourceMappingURL=Post.model.js.map -------------------------------------------------------------------------------- /dist/src/models/Post.model.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Post.model.js","sourceRoot":"","sources":["../../../src/models/Post.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qDAA4C;AAI/B,QAAA,UAAU,GAAiB,IAAI,iBAAM,CAChD;IACE,KAAK,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,IAAI;QAEV,QAAQ,EAAE,CAAC,IAAI,EAAE,sBAAsB,CAAC;KACzC;IACD,OAAO,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,IAAI;QAEV,QAAQ,EAAE,CAAC,IAAI,EAAE,iCAAiC,CAAC;KACpD;IACD,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC3C,MAAM,EAAE;QAEN,IAAI,EAAE,kBAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ;QACpC,GAAG,EAAE,MAAM;QACX,QAAQ,EAAE,CAAC,IAAI,EAAE,oBAAoB,CAAC;KACvC;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,IAAI;QACf,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,CAAC;QACzD,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,IAAI;KACX;CACF,EAED;IACE,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,KAAK;CAClB,CACF,CAAC;AAEF,kBAAe,kBAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,kBAAQ,CAAC,KAAK,CAAO,MAAM,EAAE,kBAAU,CAAC,CAAC"} -------------------------------------------------------------------------------- /dist/src/models/Token.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | exports.TokenSchema = void 0; 30 | const mongoose_1 = __importStar(require("mongoose")); 31 | const crypto_1 = __importDefault(require("crypto")); 32 | const jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); 33 | exports.TokenSchema = new mongoose_1.default.Schema({ 34 | userId: { 35 | type: mongoose_1.Schema.Types.ObjectId, 36 | required: true, 37 | ref: 'User', 38 | }, 39 | resetPasswordToken: { 40 | type: String, 41 | required: false, 42 | }, 43 | resetPasswordExpires: { 44 | type: Date, 45 | required: false, 46 | }, 47 | emailVerificationToken: { 48 | type: String, 49 | required: false, 50 | }, 51 | emailVerificationExpiresToken: { 52 | type: Date, 53 | required: false, 54 | }, 55 | accessToken: { 56 | type: String, 57 | required: false, 58 | }, 59 | refreshToken: { 60 | type: String, 61 | required: false, 62 | }, 63 | }, { timestamps: true }); 64 | exports.TokenSchema.methods.generatePasswordReset = function () { 65 | this.resetPasswordToken = crypto_1.default.randomBytes(32).toString('hex'); 66 | this.resetPasswordExpires = Date.now() + 3600000; 67 | }; 68 | exports.TokenSchema.methods.generateEmailVerificationToken = function () { 69 | this.emailVerificationToken = crypto_1.default.randomBytes(32).toString('hex'); 70 | this.emailVerificationExpiresToken = Date.now() + 3600000; 71 | }; 72 | exports.TokenSchema.methods.generateToken = function (payload, secret, signOptions) { 73 | return new Promise(function (resolve, reject) { 74 | jsonwebtoken_1.default.sign(payload, secret, signOptions, (err, encoded) => { 75 | if (err === null && encoded !== undefined) { 76 | resolve(encoded); 77 | } 78 | else { 79 | reject(err); 80 | } 81 | }); 82 | }); 83 | }; 84 | exports.TokenSchema.post('save', function () { 85 | console.log('Token is been Save ', this); 86 | }); 87 | exports.default = mongoose_1.default.models.Token || mongoose_1.default.model('Token', exports.TokenSchema); 88 | //# sourceMappingURL=Token.model.js.map -------------------------------------------------------------------------------- /dist/src/models/Token.model.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Token.model.js","sourceRoot":"","sources":["../../../src/models/Token.model.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qDAA4C;AAC5C,oDAA4B;AAC5B,gEAA+B;AAkBlB,QAAA,WAAW,GAA2B,IAAI,kBAAQ,CAAC,MAAM,CACpE;IACE,MAAM,EAAE;QACN,IAAI,EAAE,iBAAM,CAAC,KAAK,CAAC,QAAQ;QAC3B,QAAQ,EAAE,IAAI;QACd,GAAG,EAAE,MAAM;KACZ;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,KAAK;KAChB;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,KAAK;KAChB;IACD,sBAAsB,EAAE;QACtB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,KAAK;KAChB;IACD,6BAA6B,EAAE;QAC7B,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,KAAK;KAChB;IACD,WAAW,EAAE;QACX,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,KAAK;KAChB;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,KAAK;KAChB;CACF,EAED,EAAE,UAAU,EAAE,IAAI,EAAE,CACrB,CAAC;AAGF,mBAAW,CAAC,OAAO,CAAC,qBAAqB,GAAG;IAC1C,IAAI,CAAC,kBAAkB,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjE,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;AACnD,CAAC,CAAC;AAGF,mBAAW,CAAC,OAAO,CAAC,8BAA8B,GAAG;IACnD,IAAI,CAAC,sBAAsB,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrE,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;AAC5D,CAAC,CAAC;AAGF,mBAAW,CAAC,OAAO,CAAC,aAAa,GAAG,UAClC,OAA0C,EAC1C,MAAc,EACd,WAAgB;IAEhB,OAAO,IAAI,OAAO,CAAC,UAAU,OAAO,EAAE,MAAM;QAC1C,sBAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,GAAiB,EAAE,OAA2B,EAAE,EAAE;YACxF,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE;gBACzC,OAAO,CAAC,OAAO,CAAC,CAAC;aAClB;iBAAM;gBACL,MAAM,CAAC,GAAG,CAAC,CAAC;aACb;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,mBAAW,CAAC,IAAI,CAAC,MAAM,EAAE;IACvB,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,kBAAe,kBAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,kBAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,mBAAW,CAAC,CAAC"} -------------------------------------------------------------------------------- /dist/src/models/User.model.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const bcrypt_1 = __importDefault(require("bcrypt")); 7 | const mongoose_1 = require("mongoose"); 8 | const jsonwebtoken_1 = __importDefault(require("jsonwebtoken")); 9 | const validator_1 = __importDefault(require("validator")); 10 | const custom_environment_variables_config_1 = require("@src/configs/custom-environment-variables.config"); 11 | const UserSchema = new mongoose_1.Schema({ 12 | name: { 13 | type: String, 14 | trim: true, 15 | lowercase: true, 16 | required: [true, 'Please provide name'], 17 | minLength: [3, "Name can't be smaller than 3 characters"], 18 | maxLength: [15, "Name can't be greater than 15 characters"], 19 | }, 20 | firstName: { 21 | type: String, 22 | trim: true, 23 | lowercase: true, 24 | required: [false, 'Please provide first name'], 25 | minLength: [3, "Name can't be smaller than 3 characters"], 26 | maxLength: [15, "Name can't be greater than 15 characters"], 27 | }, 28 | lastName: { 29 | type: String, 30 | required: [false, 'Please provide last name'], 31 | minLength: [3, "Name can't be smaller than 3 characters"], 32 | maxLength: [15, "Name can't be greater than 15 characters"], 33 | trim: true, 34 | lowercase: true, 35 | }, 36 | familyName: { 37 | type: String, 38 | required: false, 39 | trim: true, 40 | minlength: [3, "Name can't be smaller than 3 characters"], 41 | maxLength: [30, "Name can't be greater than 30 characters"], 42 | lowercase: true, 43 | }, 44 | email: { 45 | type: String, 46 | required: true, 47 | trim: true, 48 | lowercase: true, 49 | validate: [validator_1.default.isEmail, 'Please provide a valid email'], 50 | maxLength: [128, "Email can't be greater than 128 characters"], 51 | }, 52 | password: { 53 | type: String, 54 | required: [true, 'Please provide password'], 55 | minlength: [6, 'Password must be more than 6 characters'], 56 | trim: true, 57 | }, 58 | confirmPassword: { 59 | type: String, 60 | required: [true, 'Please provide confirmed Password'], 61 | minlength: [6, 'Password must be more than 6 characters'], 62 | trim: true, 63 | }, 64 | companyName: { 65 | type: String, 66 | required: false, 67 | trim: true, 68 | minlength: [3, "Company Name can't be smaller than 3 characters"], 69 | maxLength: [30, "Company Name can't be greater than 30 characters"], 70 | lowercase: true, 71 | }, 72 | dateOfBirth: { 73 | type: String, 74 | maxLength: 15, 75 | trim: true, 76 | }, 77 | mobileNumber: { 78 | type: String, 79 | required: false, 80 | maxLength: [5, "mobileNumber can't be greater than 15 characters"], 81 | trim: true, 82 | }, 83 | gender: { type: String, trim: true, lowercase: true }, 84 | joinedDate: { 85 | type: Date, 86 | default: new Date(), 87 | trim: true, 88 | }, 89 | profileImage: { 90 | type: String, 91 | required: false, 92 | default: '/static/uploads/users/temp.png', 93 | lowercase: true, 94 | }, 95 | role: { 96 | type: String, 97 | trim: true, 98 | lowercase: true, 99 | enum: ['user', 'guide', 'admin'], 100 | default: 'user', 101 | }, 102 | favoriteAnimal: { 103 | type: String, 104 | required: false, 105 | trim: true, 106 | minlength: [3, "Favorite Animal can't be smaller than 3 characters"], 107 | maxLength: [35, "Favorite Animal can't be greater than 15 characters"], 108 | lowercase: true, 109 | }, 110 | nationality: { 111 | type: String, 112 | trim: true, 113 | required: false, 114 | lowercase: true, 115 | }, 116 | isVerified: { 117 | type: Boolean, 118 | default: false, 119 | required: false, 120 | }, 121 | isDeleted: { 122 | type: Boolean, 123 | default: false, 124 | }, 125 | status: { 126 | type: String, 127 | enum: ['pending', 'active'], 128 | default: 'pending', 129 | required: false, 130 | trim: true, 131 | lowercase: true, 132 | }, 133 | bio: { 134 | type: String, 135 | required: false, 136 | trim: true, 137 | minlength: [10, "Bio can't be smaller than 10 characters"], 138 | maxLength: [300, "Bio can't be greater than 300 characters"], 139 | lowercase: true, 140 | }, 141 | jobTitle: { 142 | type: String, 143 | required: false, 144 | trim: true, 145 | lowercase: true, 146 | minlength: [2, "Job Title can't be smaller than 3 characters"], 147 | maxLength: [30, "Job Title can't be greater than 15 characters"], 148 | }, 149 | address: { 150 | type: String, 151 | required: false, 152 | trim: true, 153 | lowercase: true, 154 | }, 155 | acceptTerms: { type: Boolean, required: false, default: false }, 156 | confirmationCode: { type: String, require: false, index: true, unique: true, sparse: true }, 157 | resetPasswordToken: { 158 | type: String, 159 | required: false, 160 | }, 161 | resetPasswordExpires: { 162 | type: Date, 163 | required: false, 164 | }, 165 | }, { 166 | timestamps: true, 167 | }); 168 | UserSchema.methods.comparePassword = async function (candidatePassword) { 169 | const isMatch = await bcrypt_1.default.compare(candidatePassword, this.password); 170 | return isMatch; 171 | }; 172 | UserSchema.pre('save', async function (next) { 173 | console.log('Middleware called before saving the user is', this); 174 | const user = this; 175 | if (user.isModified('password')) { 176 | const salt = await bcrypt_1.default.genSalt(12); 177 | user.password = await bcrypt_1.default.hash(user.password, salt); 178 | user.confirmPassword = await bcrypt_1.default.hash(user.password, salt); 179 | } 180 | next(); 181 | }); 182 | UserSchema.post('save', function () { 183 | console.log('Middleware called after saving the user is (User is been Save )', this); 184 | }); 185 | UserSchema.methods.createJWT = function () { 186 | const payload = { 187 | userId: this._id, 188 | email: this.email, 189 | name: this.firstName, 190 | dateOfBirth: this.dateOfBirth, 191 | gender: this.gender, 192 | role: this.role, 193 | }; 194 | return jsonwebtoken_1.default.sign(payload, custom_environment_variables_config_1.environmentConfig.TOKEN_SECRET, { 195 | expiresIn: custom_environment_variables_config_1.environmentConfig.JWT_EXPIRE_TIME, 196 | }); 197 | }; 198 | exports.default = mongoose_1.models.User || (0, mongoose_1.model)('User', UserSchema); 199 | //# sourceMappingURL=User.model.js.map -------------------------------------------------------------------------------- /dist/src/models/User.model.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"User.model.js","sourceRoot":"","sources":["../../../src/models/User.model.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/src/models/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./Post.model"), exports); 18 | __exportStar(require("./Token.model"), exports); 19 | __exportStar(require("./User.model"), exports); 20 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/models/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,gDAA8B;AAC9B,+CAA6B"} -------------------------------------------------------------------------------- /dist/src/routes/admin.route.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | const express_1 = __importDefault(require("express")); 6 | const middlewares_1 = require("@src/middlewares"); 7 | const controllers_1 = require("@src/controllers"); 8 | const router = express_1.default.Router(); 9 | router.get('/users', middlewares_1.isAuth, middlewares_1.isAdmin, controllers_1.getUsersController); 10 | module.exports = router; 11 | //# sourceMappingURL=admin.route.js.map -------------------------------------------------------------------------------- /dist/src/routes/admin.route.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"admin.route.js","sourceRoot":"","sources":["../../../src/routes/admin.route.ts"],"names":[],"mappings":";;;;AAAA,sDAA8B;AAE9B,kDAAmD;AACnD,kDAAsD;AAEtD,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAEhC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,oBAAM,EAAE,qBAAO,EAAE,gCAAkB,CAAC,CAAC;AAE1D,iBAAS,MAAM,CAAC"} -------------------------------------------------------------------------------- /dist/src/routes/auth.route.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | const express_1 = __importDefault(require("express")); 6 | const middlewares_1 = require("@src/middlewares"); 7 | const controllers_1 = require("@src/controllers"); 8 | const router = express_1.default.Router(); 9 | router.post('/signup', middlewares_1.signupUserValidation, controllers_1.signupController); 10 | router.post('/login', middlewares_1.loginUserValidation, controllers_1.loginController); 11 | router.post('/logout', middlewares_1.refreshTokenValidation, controllers_1.logoutController); 12 | router.patch('/update/:userId', middlewares_1.updateUserValidation, middlewares_1.isAuth, controllers_1.updateAuthController); 13 | router.delete('/remove/:userId', middlewares_1.isAuth, controllers_1.removeAuthController); 14 | router.get('/verify-email/:userId/:token', middlewares_1.verifyUserMailValidation, controllers_1.verifyEmailController); 15 | router.post('/refresh-token', middlewares_1.refreshTokenValidation, controllers_1.refreshTokenController); 16 | router.post('/forget-password', middlewares_1.sendVerificationMailValidation, controllers_1.sendForgotPasswordMailController); 17 | router.post('/reset-password/:userId/:token', middlewares_1.resetPasswordValidation, controllers_1.resetPasswordController); 18 | router.get('/me', middlewares_1.isAuth, controllers_1.getAuthProfileController); 19 | module.exports = router; 20 | //# sourceMappingURL=auth.route.js.map -------------------------------------------------------------------------------- /dist/src/routes/auth.route.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"auth.route.js","sourceRoot":"","sources":["../../../src/routes/auth.route.ts"],"names":[],"mappings":";;;;AAAA,sDAA8B;AAE9B,kDAS0B;AAC1B,kDAW0B;AAE1B,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAEhC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,kCAAoB,EAAE,8BAAgB,CAAC,CAAC;AAC/D,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,iCAAmB,EAAE,6BAAe,CAAC,CAAC;AAC5D,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,oCAAsB,EAAE,8BAAgB,CAAC,CAAC;AACjE,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,kCAAoB,EAAE,oBAAM,EAAE,kCAAoB,CAAC,CAAC;AACpF,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,oBAAM,EAAE,kCAAoB,CAAC,CAAC;AAC/D,MAAM,CAAC,GAAG,CAAC,8BAA8B,EAAE,sCAAwB,EAAE,mCAAqB,CAAC,CAAC;AAC5F,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,oCAAsB,EAAE,oCAAsB,CAAC,CAAC;AAC9E,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,4CAA8B,EAAE,8CAAgC,CAAC,CAAC;AAClG,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,qCAAuB,EAAE,qCAAuB,CAAC,CAAC;AAChG,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,oBAAM,EAAE,sCAAwB,CAAC,CAAC;AAEpD,iBAAS,MAAM,CAAC"} -------------------------------------------------------------------------------- /dist/src/routes/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | const express_1 = __importDefault(require("express")); 6 | const utils_1 = require("../utils"); 7 | const router = express_1.default.Router(); 8 | router.get('/healthChecker', (req, res) => { 9 | const message = 'Welcome to blog API'; 10 | res.send((0, utils_1.response)({ data: null, success: false, error: true, message, status: 200 })); 11 | }); 12 | module.exports = router; 13 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/routes/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/routes/index.ts"],"names":[],"mappings":";;;;AAAA,sDAAqD;AAErD,oCAAoC;AAGpC,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAGhC,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAAY,EAAE,GAA8B,EAAE,EAAE;IAC5E,MAAM,OAAO,GAAG,qBAAqB,CAAC;IACtC,GAAG,CAAC,IAAI,CAAC,IAAA,gBAAQ,EAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC9F,CAAC,CAAC,CAAC;AAEH,iBAAS,MAAM,CAAC"} -------------------------------------------------------------------------------- /dist/src/routes/post.route.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | const express_1 = __importDefault(require("express")); 6 | const controllers_1 = require("@src/controllers"); 7 | const middlewares_1 = require("@src/middlewares"); 8 | const router = express_1.default.Router(); 9 | router.get('/', (0, middlewares_1.postsPaginationMiddleware)(), controllers_1.getPostsController); 10 | router.get('/:postId', controllers_1.getPostController); 11 | router.post('/', middlewares_1.isAuth, middlewares_1.isAdmin, middlewares_1.uploadImage.single('postImage'), controllers_1.createPostController); 12 | router.delete('/:postId', middlewares_1.isAuth, middlewares_1.isAdmin, controllers_1.deletePostController); 13 | router.patch('/:postId', middlewares_1.isAuth, middlewares_1.isAdmin, middlewares_1.uploadImage.single('postImage'), controllers_1.editPostController); 14 | module.exports = router; 15 | //# sourceMappingURL=post.route.js.map -------------------------------------------------------------------------------- /dist/src/routes/post.route.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"post.route.js","sourceRoot":"","sources":["../../../src/routes/post.route.ts"],"names":[],"mappings":";;;;AAAA,sDAA8B;AAE9B,kDAM0B;AAC1B,kDAA2F;AAE3F,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAEhC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAA,uCAAyB,GAAE,EAAE,gCAAkB,CAAC,CAAC;AACjE,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,+BAAiB,CAAC,CAAC;AAC1C,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAM,EAAE,qBAAO,EAAE,yBAAW,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,kCAAoB,CAAC,CAAC;AACzF,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,oBAAM,EAAE,qBAAO,EAAE,kCAAoB,CAAC,CAAC;AACjE,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,oBAAM,EAAE,qBAAO,EAAE,yBAAW,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,gCAAkB,CAAC,CAAC;AAE/F,iBAAS,MAAM,CAAC"} -------------------------------------------------------------------------------- /dist/src/services/admin.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.getUsersService = void 0; 7 | const http_errors_1 = require("http-errors"); 8 | const User_model_1 = __importDefault(require("@src/models/User.model")); 9 | const utils_1 = require("@src/utils"); 10 | const getUsersService = async (req, res, next) => { 11 | try { 12 | const users = await User_model_1.default.find().select('name firstName lastName surname email dateOfBirth gender joinedDate isVerified profileImage mobileNumber status role companyName acceptTerms nationality favoriteAnimal address profileImage bio mobileNumber createdAt updatedAt'); 13 | const data = { 14 | user: users, 15 | }; 16 | return res.status(200).json((0, utils_1.response)({ 17 | data, 18 | success: true, 19 | error: false, 20 | message: `Success`, 21 | status: 200, 22 | })); 23 | } 24 | catch (error) { 25 | return next(http_errors_1.InternalServerError); 26 | } 27 | }; 28 | exports.getUsersService = getUsersService; 29 | exports.default = { 30 | getUsersService: exports.getUsersService, 31 | }; 32 | //# sourceMappingURL=admin.service.js.map -------------------------------------------------------------------------------- /dist/src/services/admin.service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"admin.service.js","sourceRoot":"","sources":["../../../src/services/admin.service.ts"],"names":[],"mappings":";;;;;;AACA,6CAAkD;AAElD,wEAA0C;AAC1C,sCAAsC;AAE/B,MAAM,eAAe,GAAmB,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IACtE,IAAI;QACF,MAAM,KAAK,GAAG,MAAM,oBAAI,CAAC,IAAI,EAAE,CAAC,MAAM,CACpC,8OAA8O,CAC/O,CAAC;QAEF,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,KAAK;SACZ,CAAC;QAEF,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CACzB,IAAA,gBAAQ,EAAc;YACpB,IAAI;YACJ,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,GAAG;SACZ,CAAC,CACH,CAAC;KACH;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,IAAI,CAAC,iCAAmB,CAAC,CAAC;KAClC;AACH,CAAC,CAAC;AAtBW,QAAA,eAAe,mBAsB1B;AAEF,kBAAe;IACb,eAAe,EAAf,uBAAe;CAChB,CAAC"} -------------------------------------------------------------------------------- /dist/src/services/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./admin.service"), exports); 18 | __exportStar(require("./auth.service"), exports); 19 | __exportStar(require("./post.service"), exports); 20 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/services/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kDAAgC;AAChC,iDAA+B;AAC/B,iDAA+B"} -------------------------------------------------------------------------------- /dist/src/services/post.service.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.editPostService = exports.deletePostService = exports.getPostService = exports.createPostService = exports.getPostsService = void 0; 7 | const Post_model_1 = __importDefault(require("@src/models/Post.model")); 8 | const utils_1 = require("@src/utils"); 9 | const getPostsService = async (_req, res) => { 10 | if (res?.paginatedResults) { 11 | const { results, next, previous, currentPage, totalDocs, totalPages, lastPage } = res.paginatedResults; 12 | const responseObject = { 13 | totalDocs: totalDocs || 0, 14 | totalPages: totalPages || 0, 15 | lastPage: lastPage || 0, 16 | count: results?.length || 0, 17 | currentPage: currentPage || 0, 18 | }; 19 | if (next) { 20 | responseObject.nextPage = next; 21 | } 22 | if (previous) { 23 | responseObject.prevPage = previous; 24 | } 25 | responseObject.posts = results?.map((doc) => { 26 | return { 27 | _id: doc?._id, 28 | title: doc?.title, 29 | content: doc?.content, 30 | category: doc?.category, 31 | postImage: doc?.postImage, 32 | createdAt: doc?.createdAt, 33 | updatedAt: doc?.updatedAt, 34 | author: doc?.author, 35 | }; 36 | }); 37 | return res.status(200).send((0, utils_1.response)({ 38 | success: true, 39 | error: false, 40 | message: 'Successful Found posts', 41 | status: 200, 42 | data: responseObject, 43 | })); 44 | } 45 | }; 46 | exports.getPostsService = getPostsService; 47 | const createPostService = async (req, res, next) => { 48 | const { title, content, category } = req.body; 49 | if (!req.file) { 50 | res.status(422).send((0, utils_1.response)({ 51 | data: null, 52 | success: false, 53 | error: true, 54 | message: `Invalid request (Please upload Image)`, 55 | status: 422, 56 | })); 57 | } 58 | const userId = req?.user?._id || ''; 59 | const postData = new Post_model_1.default({ 60 | title, 61 | content, 62 | category, 63 | postImage: `/static/uploads/posts/${req?.file?.filename}`, 64 | author: userId, 65 | }); 66 | try { 67 | const createdPost = await Post_model_1.default.create(postData); 68 | return res.status(201).send((0, utils_1.response)({ 69 | data: createdPost, 70 | success: true, 71 | error: false, 72 | message: 'Successfully added new post', 73 | status: 201, 74 | })); 75 | } 76 | catch (error) { 77 | return next(error); 78 | } 79 | }; 80 | exports.createPostService = createPostService; 81 | const getPostService = async (req, res, next) => { 82 | if (!(0, utils_1.isValidMongooseObjectId)(req.params.postId) || !req.params.postId) { 83 | return res.status(422).send((0, utils_1.response)({ 84 | data: null, 85 | success: false, 86 | error: true, 87 | message: `Invalid request`, 88 | status: 422, 89 | })); 90 | } 91 | try { 92 | const doc = await Post_model_1.default.findById(req.params.postId); 93 | if (!doc) { 94 | return res.status(400).send((0, utils_1.response)({ 95 | data: [], 96 | success: false, 97 | error: true, 98 | message: `Failed to find post by given ID ${req.params.postId}`, 99 | status: 400, 100 | })); 101 | } 102 | const data = { 103 | post: { 104 | _id: doc?._id, 105 | title: doc?.title, 106 | content: doc?.content, 107 | postImage: doc?.postImage, 108 | createdAt: doc?.createdAt, 109 | updatedAt: doc?.updatedAt, 110 | author: doc?.author, 111 | category: doc?.category, 112 | }, 113 | }; 114 | return res.status(200).send((0, utils_1.response)({ 115 | success: true, 116 | error: false, 117 | message: `Successfully Found post by given id: ${req.params.postId}`, 118 | status: 200, 119 | data, 120 | })); 121 | } 122 | catch (error) { 123 | console.log('error', error); 124 | return next(error); 125 | } 126 | }; 127 | exports.getPostService = getPostService; 128 | const deletePostService = async (req, res, next) => { 129 | if (!(0, utils_1.isValidMongooseObjectId)(req.params.postId) || !req.params.postId) { 130 | return res.status(422).send((0, utils_1.response)({ 131 | data: null, 132 | success: false, 133 | error: true, 134 | message: `Invalid request`, 135 | status: 422, 136 | })); 137 | } 138 | try { 139 | const toBeDeletedPost = await Post_model_1.default.findByIdAndRemove({ 140 | _id: req.params.postId, 141 | }); 142 | if (!toBeDeletedPost) { 143 | return res.status(400).send((0, utils_1.response)({ 144 | data: null, 145 | success: false, 146 | error: true, 147 | message: `Failed to delete post by given ID ${req.params.postId}`, 148 | status: 400, 149 | })); 150 | } 151 | return res.status(200).json((0, utils_1.response)({ 152 | data: null, 153 | success: true, 154 | error: false, 155 | message: `Successfully deleted post by ID ${req.params.postId}`, 156 | status: 200, 157 | })); 158 | } 159 | catch (error) { 160 | return next(error); 161 | } 162 | }; 163 | exports.deletePostService = deletePostService; 164 | const editPostService = async (req, res, next) => { 165 | const { title, content, category } = req.body; 166 | if (!(0, utils_1.isValidMongooseObjectId)(req.params.postId) || !req.params.postId) { 167 | return res.status(422).send((0, utils_1.response)({ 168 | data: null, 169 | success: false, 170 | error: true, 171 | message: `Invalid request`, 172 | status: 422, 173 | })); 174 | } 175 | try { 176 | const toBeUpdatedPost = await Post_model_1.default.findById(req.params.postId); 177 | if (!toBeUpdatedPost) { 178 | return res.status(400).send((0, utils_1.response)({ 179 | data: null, 180 | success: false, 181 | error: true, 182 | message: `Failed to update post by given ID ${req.params.postId}`, 183 | status: 400, 184 | })); 185 | } 186 | toBeUpdatedPost.title = title || toBeUpdatedPost.title; 187 | toBeUpdatedPost.content = content || toBeUpdatedPost.content; 188 | toBeUpdatedPost.postImage = !req.file ? toBeUpdatedPost.postImage : `/static/uploads/posts/${req?.file?.filename}`; 189 | toBeUpdatedPost.category = category || toBeUpdatedPost?.category; 190 | const updatedPost = await toBeUpdatedPost.save(); 191 | return res.status(200).json((0, utils_1.response)({ 192 | data: { 193 | post: updatedPost, 194 | }, 195 | success: true, 196 | error: false, 197 | message: `Successfully updated post by ID ${req.params.postId}`, 198 | status: 200, 199 | })); 200 | } 201 | catch (error) { 202 | return next(error); 203 | } 204 | }; 205 | exports.editPostService = editPostService; 206 | exports.default = { getPostsService: exports.getPostsService, getPostService: exports.getPostService, createPostService: exports.createPostService, editPostService: exports.editPostService }; 207 | //# sourceMappingURL=post.service.js.map -------------------------------------------------------------------------------- /dist/src/services/post.service.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"post.service.js","sourceRoot":"","sources":["../../../src/services/post.service.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /dist/src/utils/generateSecretKey.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.key2 = exports.key1 = void 0; 7 | const crypto_1 = __importDefault(require("crypto")); 8 | exports.key1 = crypto_1.default.randomBytes(32).toString('hex'); 9 | exports.key2 = crypto_1.default.randomBytes(32).toString('hex'); 10 | console.table({ key1: exports.key1, key2: exports.key2 }); 11 | exports.default = { key1: exports.key1, key2: exports.key2 }; 12 | //# sourceMappingURL=generateSecretKey.js.map -------------------------------------------------------------------------------- /dist/src/utils/generateSecretKey.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"generateSecretKey.js","sourceRoot":"","sources":["../../../src/utils/generateSecretKey.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAEf,QAAA,IAAI,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9C,QAAA,IAAI,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC3D,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAJ,YAAI,EAAE,IAAI,EAAJ,YAAI,EAAE,CAAC,CAAC;AAE9B,kBAAe,EAAE,IAAI,EAAJ,YAAI,EAAE,IAAI,EAAJ,YAAI,EAAE,CAAC"} -------------------------------------------------------------------------------- /dist/src/utils/getImageExtension.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.getImageExtension = void 0; 4 | const getImageExtension = (mimetype) => { 5 | switch (mimetype) { 6 | case 'image/png': 7 | return '.png'; 8 | case 'image/PNG': 9 | return '.PNG'; 10 | case 'image/jpg': 11 | return '.jpg'; 12 | case 'image/JPG': 13 | return '.JPG'; 14 | case 'image/JPEG': 15 | return '.JPEG'; 16 | case 'image/jpeg': 17 | return '.jpeg'; 18 | case 'image/webp': 19 | return '.webp'; 20 | default: 21 | return false; 22 | } 23 | }; 24 | exports.getImageExtension = getImageExtension; 25 | exports.default = exports.getImageExtension; 26 | //# sourceMappingURL=getImageExtension.js.map -------------------------------------------------------------------------------- /dist/src/utils/getImageExtension.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"getImageExtension.js","sourceRoot":"","sources":["../../../src/utils/getImageExtension.ts"],"names":[],"mappings":";;;AACO,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACpD,QAAQ,QAAQ,EAAE;QAChB,KAAK,WAAW;YACd,OAAO,MAAM,CAAC;QAChB,KAAK,WAAW;YACd,OAAO,MAAM,CAAC;QAChB,KAAK,WAAW;YACd,OAAO,MAAM,CAAC;QAChB,KAAK,WAAW;YACd,OAAO,MAAM,CAAC;QAChB,KAAK,YAAY;YACf,OAAO,OAAO,CAAC;QACjB,KAAK,YAAY;YACf,OAAO,OAAO,CAAC;QACjB,KAAK,YAAY;YACf,OAAO,OAAO,CAAC;QACjB;YACE,OAAO,KAAK,CAAC;KAChB;AACH,CAAC,CAAC;AAnBW,QAAA,iBAAiB,qBAmB5B;AAEF,kBAAe,yBAAiB,CAAC"} -------------------------------------------------------------------------------- /dist/src/utils/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __exportStar = (this && this.__exportStar) || function(m, exports) { 14 | for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 15 | }; 16 | Object.defineProperty(exports, "__esModule", { value: true }); 17 | __exportStar(require("./generateSecretKey"), exports); 18 | __exportStar(require("./getImageExtension"), exports); 19 | __exportStar(require("./isValidMongooseObjectId"), exports); 20 | __exportStar(require("./response"), exports); 21 | __exportStar(require("./sendEmail"), exports); 22 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/src/utils/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,sDAAoC;AACpC,4DAA0C;AAC1C,6CAA2B;AAC3B,8CAA4B"} -------------------------------------------------------------------------------- /dist/src/utils/isValidMongooseObjectId.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.isValidMongooseObjectId = void 0; 4 | const mongoose_1 = require("mongoose"); 5 | const isValidMongooseObjectId = (id) => { 6 | if (mongoose_1.Types.ObjectId.isValid(id)) { 7 | if (String(new mongoose_1.Types.ObjectId(id)) === id) 8 | return true; 9 | return false; 10 | } 11 | return false; 12 | }; 13 | exports.isValidMongooseObjectId = isValidMongooseObjectId; 14 | exports.default = exports.isValidMongooseObjectId; 15 | //# sourceMappingURL=isValidMongooseObjectId.js.map -------------------------------------------------------------------------------- /dist/src/utils/isValidMongooseObjectId.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"isValidMongooseObjectId.js","sourceRoot":"","sources":["../../../src/utils/isValidMongooseObjectId.ts"],"names":[],"mappings":";;;AAAA,uCAAiC;AAE1B,MAAM,uBAAuB,GAAG,CAAC,EAAU,EAAW,EAAE;IAC7D,IAAI,gBAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;QAC9B,IAAI,MAAM,CAAC,IAAI,gBAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QACvD,OAAO,KAAK,CAAC;KACd;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AANW,QAAA,uBAAuB,2BAMlC;AAEF,kBAAe,+BAAuB,CAAC"} -------------------------------------------------------------------------------- /dist/src/utils/response.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.response = void 0; 4 | const response = ({ data, success, error, message, status }) => { 5 | return { 6 | success, 7 | error, 8 | message, 9 | status, 10 | data, 11 | }; 12 | }; 13 | exports.response = response; 14 | exports.default = exports.response; 15 | //# sourceMappingURL=response.js.map -------------------------------------------------------------------------------- /dist/src/utils/response.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/utils/response.ts"],"names":[],"mappings":";;;AAEO,MAAM,QAAQ,GAAG,CAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAgB,EAAE,EAAE;IACrF,OAAO;QACL,OAAO;QACP,KAAK;QACL,OAAO;QACP,MAAM;QACN,IAAI;KACL,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,QAAQ,YAQnB;AAEF,kBAAe,gBAAQ,CAAC"} -------------------------------------------------------------------------------- /dist/src/utils/sendEmail.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"sendEmail.js","sourceRoot":"","sources":["../../../src/utils/sendEmail.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | // Todo 2 | // Setting up Redis and MongoDB with Docker Compose 3 | // Connect to Redis Docker Container 4 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | coverageDirectory: 'coverage', 5 | coverageThreshold: { 6 | global: { 7 | branches: 0, 8 | functions: 0, 9 | lines: 0, 10 | statements: 0, 11 | }, 12 | }, 13 | collectCoverageFrom: ['src/**/*.{js,ts}'], 14 | moduleNameMapper: { 15 | '@src/(.*)': '/src/$1', 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src", "swagger"], 3 | "ext": "ts,js,json,yaml,jsx", 4 | "ignore": ["node_modules", "coverage", "dist"], 5 | "exec": "ts-node -r ts-node/register/transpile-only -r tsconfig-paths/register ./src/index.ts", 6 | "restartable": "rs", 7 | "env": { 8 | "NODE_ENV": "development" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blog-ap", 3 | "version": "1.2.0", 4 | "description": "Blog API Written in Node.js, Express, MongoDB, JSON Web Token (JWT) Authentication, Mongoose, Middleware Authentication.", 5 | "main": "src/index.ts", 6 | "scripts": { 7 | "nodemon": "nodemon", 8 | "prod": "node -r ts-node/register/transpile-only -r tsconfig-paths/register ./dist/src/index.js", 9 | "dev": "nodemon -r ts-node/register/transpile-only -r tsconfig-paths/register ./src/index.ts", 10 | "build": "tsc -p tsconfig.prod.json", 11 | "lint": "eslint --fix", 12 | "check-types": "tsc --pretty --noEmit", 13 | "check-format": "prettier --check .", 14 | "check-lint": "eslint . --ext ts --ext tsx", 15 | "format": "prettier --write .", 16 | "test": "jest", 17 | "test:watch": "jest --watch", 18 | "test:coverage": "jest --coverage", 19 | "test-all": "npm run check-format && npm run check-lint && npm run check-types && npm run test", 20 | "start": "node -r ts-node/register/transpile-only -r tsconfig-paths/register ./dist/src/index.js", 21 | "postinstall": "tsc" 22 | }, 23 | "engines": { 24 | "node": "v14.17.0" 25 | }, 26 | "keywords": [], 27 | "author": "Saddam Arbaa", 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/saddamarbaa/blog-api.git" 31 | }, 32 | "license": "MIT", 33 | "dependencies": { 34 | "axios": "^1.1.2", 35 | "bcrypt": "^5.1.0", 36 | "body-parser": "^1.20.1", 37 | "cookie-parser": "^1.4.6", 38 | "cors": "^2.8.5", 39 | "dotenv-safe": "^8.2.0", 40 | "express": "^4.18.1", 41 | "helmet": "^5.1.1", 42 | "http-errors": "^2.0.0", 43 | "joi": "^17.6.3", 44 | "joi-objectid": "^4.0.2", 45 | "jsonwebtoken": "^8.5.1", 46 | "mongodb": "^4.10.0", 47 | "mongoose": "^6.6.5", 48 | "morgan": "^1.10.0", 49 | "multer": "^1.4.5-lts.1", 50 | "nodemailer": "^6.8.0", 51 | "nodemailer-sendgrid-transport": "^0.2.0", 52 | "supertest": "^6.2.4", 53 | "swagger-jsdoc": "^6.2.5", 54 | "swagger-ui-express": "^4.6.0", 55 | "ts-jest": "^28.0.8", 56 | "ts-node": "^10.9.1", 57 | "tsconfig-paths": "^4.1.0", 58 | "typescript": "^4.7.4", 59 | "validator": "^13.7.0", 60 | "yamljs": "^0.3.0" 61 | }, 62 | "devDependencies": { 63 | "@types/bcrypt": "^5.0.0", 64 | "@types/bcryptjs": "^2.4.2", 65 | "@types/cookie-parser": "^1.4.3", 66 | "@types/cors": "^2.8.12", 67 | "@types/dotenv-safe": "^8.1.2", 68 | "@types/express": "^4.17.13", 69 | "@types/express-serve-static-core": "^4.17.31", 70 | "@types/http-errors": "^1.8.2", 71 | "@types/jest": "^28.1.8", 72 | "@types/jsonwebtoken": "^8.5.9", 73 | "@types/morgan": "^1.9.3", 74 | "@types/multer": "^1.4.7", 75 | "@types/node": "^18.11.0", 76 | "@types/nodemailer": "^6.4.6", 77 | "@types/supertest": "^2.0.12", 78 | "@types/swagger-jsdoc": "^6.0.1", 79 | "@types/swagger-ui-express": "^4.1.3", 80 | "@types/validator": "^13.7.7", 81 | "@types/yamljs": "^0.2.31", 82 | "@typescript-eslint/eslint-plugin": "^5.39.0", 83 | "@typescript-eslint/parser": "^5.39.0", 84 | "eslint": "^8.25.0", 85 | "eslint-config-airbnb-base": "^15.0.0", 86 | "eslint-config-airbnb-typescript": "^17.0.0", 87 | "eslint-config-prettier": "^8.5.0", 88 | "eslint-import-resolver-typescript": "^3.5.1", 89 | "eslint-plugin-import": "^2.26.0", 90 | "eslint-plugin-prettier": "^4.2.1", 91 | "eslint-plugin-simple-import-sort": "^8.0.0", 92 | "jest": "^28.1.3", 93 | "nodemon": "^2.0.19", 94 | "prettier": "^2.7.1" 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /public/uploads/posts/postImage-1669466910020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/public/uploads/posts/postImage-1669466910020.png -------------------------------------------------------------------------------- /public/uploads/posts/postImage-1670340044006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/public/uploads/posts/postImage-1670340044006.png -------------------------------------------------------------------------------- /public/uploads/users/admin1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/public/uploads/users/admin1.png -------------------------------------------------------------------------------- /public/uploads/users/admin2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/public/uploads/users/admin2.png -------------------------------------------------------------------------------- /public/uploads/users/tem3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/public/uploads/users/tem3.png -------------------------------------------------------------------------------- /public/uploads/users/temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/public/uploads/users/temp.png -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | 3 | import postRoutes from '@src/routes/post.route'; 4 | import authRoutes from '@src/routes/auth.route'; 5 | import adminRoutes from '@src/routes/admin.route'; 6 | import healthCheckRoute from '@src/routes/index'; 7 | 8 | const router = express.Router(); 9 | 10 | router.use('/', healthCheckRoute); 11 | router.use('/posts', postRoutes); 12 | router.use('/admin', adminRoutes); 13 | router.use('/auth', authRoutes); 14 | 15 | export default router; 16 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | // Import all the dependencies 2 | import express from 'express'; 3 | import morgan from 'morgan'; 4 | import helmet from 'helmet'; 5 | import cors from 'cors'; 6 | import dotenv from 'dotenv-safe'; 7 | import cookieParser from 'cookie-parser'; 8 | import swaggerUi from 'swagger-ui-express'; 9 | import YAML from 'yamljs'; 10 | 11 | // Import Routes 12 | import api from '@src/api'; 13 | 14 | // Import Middlewares 15 | import { errorHandlerMiddleware, notFoundMiddleware } from '@src/middlewares'; 16 | 17 | const swaggerDocument = YAML.load(`${process.cwd()}/swagger/swagger.yaml`); 18 | 19 | // const swaggerDocument = YAML.load('./docs/swagger.yaml'); 20 | 21 | // Access Environment variables 22 | dotenv.config(); 23 | 24 | // Initialize app with express 25 | const app: express.Application | undefined = express(); 26 | 27 | // Load App Middleware 28 | 29 | app.use(morgan('dev')); 30 | app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); 31 | app.use(express.json()); 32 | app.use(express.urlencoded({ extended: true })); 33 | app.use(cookieParser()); 34 | app.use( 35 | helmet({ 36 | crossOriginResourcePolicy: false, 37 | crossOriginEmbedderPolicy: false, 38 | crossOriginOpenerPolicy: false, 39 | }) 40 | ); 41 | app.use(cors()); 42 | // Serve all static files inside public directory. 43 | app.use('/static', express.static('public')); 44 | 45 | // Routes which Should handle the requests 46 | app.use('/api/v1', api); 47 | app.use(notFoundMiddleware); 48 | app.use(errorHandlerMiddleware); 49 | 50 | export default app; 51 | -------------------------------------------------------------------------------- /src/configs/custom-environment-variables.config.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv-safe'; 2 | 3 | dotenv.config(); 4 | 5 | export const environmentConfig = { 6 | MONGODB_CONNECTION_STRING: process.env.MONGODB_CONNECTION_STRING, 7 | TOKEN_SECRET: process.env.TOKEN_SECRET, 8 | WEBSITE_URL: process.env.WEBSITE_URL, 9 | API_VERSION: process.env.API_VERSION, 10 | JWT_EXPIRE_TIME: process.env.JWT_EXPIRE_TIME, 11 | PORT: process.env.PORT || 8000, 12 | SEND_GRID_API_KEY: process.env.SEND_GRID_API_KEY, 13 | ADMIN_SEND_GRID_EMAIL: process.env.ADMIN_SEND_GRID_EMAIL, 14 | ADMIN_ROLE: process.env.ADMIN_ROLE, 15 | ADMIN_EMAIL: process.env.ADMIN_EMAIL, 16 | NODE_ENV: process.env.NODE_ENV || 'development', 17 | CLIENT_URL: process.env.CLIENT_URL, 18 | ACCESS_TOKEN_SECRET_KEY: process.env.ACCESS_TOKEN_SECRET_KEY, 19 | REFRESH_TOKEN_SECRET_KEY: process.env.REFRESH_TOKEN_SECRET_KEY, 20 | ACCESS_TOKEN_KEY_EXPIRE_TIME: process.env.ACCESS_TOKEN_KEY_EXPIRE_TIME, 21 | REFRESH_TOKEN_KEY_EXPIRE_TIME: process.env.REFRESH_TOKEN_KEY_EXPIRE_TIME, 22 | JWT_ISSUER: process.env.JWT_ISSUER, 23 | REST_PASSWORD_LINK_EXPIRE_TIME: process.env.REST_PASSWORD_LINK_EXPIRE_TIME, 24 | }; 25 | 26 | export default environmentConfig; 27 | -------------------------------------------------------------------------------- /src/configs/db.config.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { ConnectOptions, Error } from 'mongoose'; 2 | 3 | // Connecting to MongoDB(Connecting to the Database) 4 | export const connectDB = (MONGODB_URI: any) => { 5 | // @event connected: Emitted when this connection successfully connects to the db. May be emitted multiple times in reconnected scenarios 6 | mongoose.connection.on('connected', () => { 7 | console.log('MongoDB database connection established successfully'); 8 | }); 9 | 10 | mongoose.connection.on('reconnected', () => { 11 | console.log('Mongo Connection Reestablished'); 12 | }); 13 | 14 | // @event error: Emitted when an error occurs on this connection. 15 | mongoose.connection.on('error', (error: Error) => { 16 | console.log('MongoDB connection error. Please make sure MongoDB is running: '); 17 | console.log(`Mongo Connection ERROR: ${error}`); 18 | }); 19 | 20 | // @event close 21 | mongoose.connection.on('close', () => { 22 | console.log('Mongo Connection Closed...'); 23 | }); 24 | 25 | // @event disconnected: Emitted after getting disconnected from the db 26 | mongoose.connection.on('disconnected', () => { 27 | console.log('MongoDB database connection is disconnected...'); 28 | console.log('Trying to reconnect to Mongo ...'); 29 | setTimeout(() => { 30 | mongoose.connect(MONGODB_URI, { 31 | keepAlive: true, 32 | socketTimeoutMS: 3000, 33 | connectTimeoutMS: 3000, 34 | useNewUrlParser: true, 35 | useUnifiedTopology: true, 36 | } as ConnectOptions); 37 | }, 3000); 38 | }); 39 | 40 | // @event close: Emitted after we disconnected and onClose executed on all of this connections models. 41 | process.on('SIGINT', () => { 42 | mongoose.connection.close(() => { 43 | console.log('MongoDB database connection is disconnected due to app termination...'); 44 | process.exit(0); // close database connection 45 | }); 46 | }); 47 | 48 | // mongoose.connect return promise 49 | mongoose.connect(MONGODB_URI, { 50 | keepAlive: true, 51 | useNewUrlParser: true, 52 | useUnifiedTopology: true, 53 | } as ConnectOptions); 54 | 55 | return mongoose.connect(MONGODB_URI); 56 | }; 57 | 58 | export default connectDB; 59 | -------------------------------------------------------------------------------- /src/configs/indes.ts: -------------------------------------------------------------------------------- 1 | export * from './custom-environment-variables.config'; 2 | export * from './db.config'; 3 | -------------------------------------------------------------------------------- /src/controllers/admin.controller.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express'; 2 | 3 | import { getUsersService } from '@src/services'; 4 | 5 | export const getUsersController = (req: Request, res: Response, next: NextFunction) => getUsersService(req, res, next); 6 | 7 | export default { 8 | getUsersController, 9 | }; 10 | -------------------------------------------------------------------------------- /src/controllers/auth.controller.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction, RequestHandler } from 'express'; 2 | 3 | import { 4 | signupService, 5 | loginService, 6 | logoutService, 7 | verifyEmailService, 8 | refreshTokenService, 9 | sendForgotPasswordMailService, 10 | resetPasswordService, 11 | removeAuthService, 12 | updateAuthService, 13 | getAuthProfileService, 14 | } from '@src/services'; 15 | import { AuthenticatedRequestBody, IUser } from '@src/interfaces'; 16 | 17 | export const signupController = (req: Request, res: Response, next: NextFunction) => signupService(req, res, next); 18 | 19 | export const loginController = (req: Request, res: Response, next: NextFunction) => loginService(req, res, next); 20 | 21 | export const logoutController = (req: Request, res: Response, next: NextFunction) => logoutService(req, res, next); 22 | 23 | export const updateAuthController = (req: AuthenticatedRequestBody, res: Response, next: NextFunction) => 24 | updateAuthService(req, res, next); 25 | 26 | export const removeAuthController = (req: AuthenticatedRequestBody, res: Response, next: NextFunction) => 27 | removeAuthService(req, res, next); 28 | 29 | export const getAuthProfileController = (req: AuthenticatedRequestBody, res: Response, next: NextFunction) => 30 | getAuthProfileService(req, res, next); 31 | 32 | export const verifyEmailController = (req: Request, res: Response, next: NextFunction) => 33 | verifyEmailService(req, res, next); 34 | 35 | export const refreshTokenController: RequestHandler = async (req, res, next) => refreshTokenService(req, res, next); 36 | 37 | export const sendForgotPasswordMailController: RequestHandler = async (req, res, next) => 38 | sendForgotPasswordMailService(req, res, next); 39 | 40 | export const resetPasswordController: RequestHandler = async (req, res, next) => resetPasswordService(req, res, next); 41 | 42 | export default { 43 | signupController, 44 | loginController, 45 | logoutController, 46 | updateAuthController, 47 | removeAuthController, 48 | verifyEmailController, 49 | refreshTokenController, 50 | sendForgotPasswordMailController, 51 | resetPasswordController, 52 | getAuthProfileController, 53 | }; 54 | -------------------------------------------------------------------------------- /src/controllers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './admin.controller'; 2 | export * from './auth.controller'; 3 | export * from './post.controller'; 4 | -------------------------------------------------------------------------------- /src/controllers/post.controller.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express'; 2 | 3 | import { createPostService, editPostService, deletePostService, getPostService, getPostsService } from '@src/services'; 4 | import { TPaginationResponse, Post as TPost, AuthenticatedRequestBody } from '@src/interfaces'; 5 | 6 | export const getPostsController = (req: Request, res: TPaginationResponse) => getPostsService(req, res); 7 | export const getPostController = (req: Request, res: Response, next: NextFunction) => getPostService(req, res, next); 8 | export const createPostController = (req: AuthenticatedRequestBody, res: Response, next: NextFunction) => 9 | createPostService(req, res, next); 10 | export const deletePostController = (req: Request, res: Response, next: NextFunction) => 11 | deletePostService(req, res, next); 12 | export const editPostController = (req: AuthenticatedRequestBody, res: Response, next: NextFunction) => 13 | editPostService(req, res, next); 14 | 15 | export default { 16 | getPostsController, 17 | createPostController, 18 | getPostController, 19 | deletePostController, 20 | editPostController, 21 | }; 22 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import app from '@src/app'; 2 | import { environmentConfig } from '@src/configs/custom-environment-variables.config'; 3 | import { connectDB } from '@src/configs/db.config'; 4 | 5 | // Connecting to MongoDB and Starting Server 6 | const start = async () => { 7 | try { 8 | await connectDB(environmentConfig.MONGODB_CONNECTION_STRING); 9 | 10 | console.log('MongoDB database connection established successfully to... '); 11 | 12 | app?.listen(environmentConfig.PORT, () => { 13 | console.log(`Listening: http://localhost:${environmentConfig.PORT}`); 14 | }); 15 | } catch (error) { 16 | console.log('MongoDB connection error. Please make sure MongoDB is running: '); 17 | } 18 | }; 19 | 20 | // Establish http server connection 21 | start(); 22 | -------------------------------------------------------------------------------- /src/interfaces/ErrorResponse.ts: -------------------------------------------------------------------------------- 1 | import MessageResponse from './MessageResponse'; 2 | 3 | export interface ErrorResponse extends MessageResponse { 4 | stack?: string; 5 | } 6 | 7 | export default ErrorResponse; 8 | -------------------------------------------------------------------------------- /src/interfaces/MessageResponse.ts: -------------------------------------------------------------------------------- 1 | export interface ResponseT { 2 | data: T | null; 3 | success: boolean; 4 | error: boolean; 5 | message: string; 6 | status: number; 7 | } 8 | 9 | export default ResponseT; 10 | -------------------------------------------------------------------------------- /src/interfaces/Post.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from 'express'; 2 | import mongoose from 'mongoose'; 3 | 4 | import { IUser } from './User'; 5 | 6 | export interface Post { 7 | title: string; 8 | content: string; 9 | postImage: string; 10 | author: mongoose.Schema.Types.ObjectId; 11 | _id: string; 12 | createdAt?: string; 13 | updatedAt?: string; 14 | category?: string; 15 | } 16 | 17 | export interface AuthenticatedRequestBody extends Request { 18 | body: T; 19 | user?: IUser; 20 | } 21 | 22 | export interface TPage { 23 | page: number; 24 | limit: number; 25 | } 26 | 27 | export interface TPaginationRequest extends Request { 28 | query: { 29 | limit: string; 30 | page: string; 31 | orderBy: string; 32 | sortBy: string; 33 | filterBy: string; 34 | category: string; 35 | search: string; 36 | content: string; 37 | title: string; 38 | }; 39 | } 40 | 41 | export interface TPaginationResponse extends Response { 42 | paginatedResults?: { 43 | results: any; 44 | next: string; 45 | previous: string; 46 | currentPage: string; 47 | totalDocs: string; 48 | totalPages: string; 49 | lastPage: string; 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /src/interfaces/User.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { Document, Schema } from 'mongoose'; 3 | 4 | export interface IUser extends Document { 5 | firstName: string; 6 | lastName: string; 7 | email: string; 8 | name: string; 9 | password: string; 10 | confirmPassword: string; 11 | role?: string; 12 | acceptTerms: boolean; 13 | familyName?: string; 14 | mobileNumber?: string; 15 | bio?: string; 16 | favoriteAnimal?: string; 17 | nationality?: string; 18 | companyName?: string; 19 | profileImage?: any; 20 | jobTitle?: string; 21 | status?: string; 22 | isVerified?: boolean; 23 | isDeleted?: boolean; 24 | address?: string; 25 | dateOfBirth?: string; 26 | createdAt?: string; 27 | updatedAt?: string; 28 | emailVerificationLinkToken?: string; 29 | token?: string; 30 | accessToken?: string; 31 | refreshToken?: string; 32 | gender?: string; 33 | joinedDate?: string; 34 | confirmationCode?: string; 35 | resetPasswordToken?: string; 36 | resetPasswordExpires?: string; 37 | userId?: Schema.Types.ObjectId; 38 | } 39 | 40 | export interface IRequestUser extends Request { 41 | user: IUser; 42 | } 43 | 44 | export interface IAuthRequest extends Request { 45 | headers: { authorization?: string; Authorization?: string }; 46 | cookies: { authToken?: string }; 47 | user?: IUser; 48 | } 49 | 50 | export interface IAuthRefreshTokenRequest extends Request { 51 | headers: { authorization?: string; Authorization?: string }; 52 | cookies: { authToken?: string }; 53 | accessToken?: string; 54 | refreshToken?: string; 55 | } 56 | -------------------------------------------------------------------------------- /src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ErrorResponse'; 2 | export * from './MessageResponse'; 3 | export * from './Post'; 4 | export * from './User'; 5 | -------------------------------------------------------------------------------- /src/middlewares/auth/checkIsAdmin.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Response } from 'express'; 2 | import createHttpError from 'http-errors'; 3 | 4 | import { environmentConfig } from '@src/configs/custom-environment-variables.config'; 5 | import { IAuthRequest as IAdminRequest } from '@src/interfaces'; 6 | 7 | export const isAdmin = async (req: IAdminRequest, res: Response, next: NextFunction) => { 8 | const user = req?.user; 9 | 10 | const adminUser = 11 | user && user.role === environmentConfig.ADMIN_ROLE && environmentConfig?.ADMIN_EMAIL?.includes(`${user?.email}`); 12 | 13 | if (!adminUser) { 14 | return next(createHttpError(403, `Auth Failed (Unauthorized)`)); 15 | } 16 | 17 | next(); 18 | }; 19 | 20 | export default { isAdmin }; 21 | -------------------------------------------------------------------------------- /src/middlewares/auth/checkIsAuth.ts: -------------------------------------------------------------------------------- 1 | import jwt, { VerifyErrors } from 'jsonwebtoken'; 2 | import { NextFunction, Response } from 'express'; 3 | import createHttpError, { InternalServerError } from 'http-errors'; 4 | 5 | import User from '@src/models/User.model'; 6 | import { environmentConfig } from '@src/configs/custom-environment-variables.config'; 7 | import { IAuthRequest, IUser } from '@src/interfaces'; 8 | 9 | export const isAuth = async (req: IAuthRequest, res: Response, next: NextFunction) => { 10 | const authHeader = (req && req.headers.authorization) || (req && req.headers.Authorization); 11 | const token = (authHeader && authHeader.split(' ')[1]) || req?.cookies?.authToken || ''; 12 | 13 | if (!token) { 14 | return next(createHttpError(401, 'Auth Failed (Invalid Credentials)')); 15 | } 16 | 17 | jwt.verify( 18 | token, 19 | environmentConfig.ACCESS_TOKEN_SECRET_KEY as jwt.Secret, 20 | async (err: VerifyErrors | null, decodedUser: any) => { 21 | if (err) { 22 | // JsonWebTokenError or token has expired 23 | const errorMessage = err.name === 'JsonWebTokenError' ? 'Auth Failed (Unauthorized)' : err.message; 24 | 25 | return next(createHttpError(403, errorMessage)); 26 | } 27 | 28 | try { 29 | const decodedUserInDB = await User.findOne({ _id: decodedUser?.userId }); 30 | 31 | if (!decodedUserInDB) { 32 | return next(createHttpError(403, `Auth Failed (Unauthorized)`)); 33 | } 34 | // console.log('The Authorized Admin is ', user); 35 | // req.user = user as IUser; 36 | req.user = decodedUserInDB as IUser; 37 | 38 | // if we did success go to the next middleware 39 | next(); 40 | } catch (error) { 41 | return next(InternalServerError); 42 | } 43 | } 44 | ); 45 | }; 46 | 47 | export default { isAuth }; 48 | -------------------------------------------------------------------------------- /src/middlewares/auth/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkIsAdmin'; 2 | export * from './checkIsAuth'; 3 | export * from './verifyRefreshToken'; 4 | -------------------------------------------------------------------------------- /src/middlewares/auth/verifyRefreshToken.ts: -------------------------------------------------------------------------------- 1 | import jwt, { VerifyErrors } from 'jsonwebtoken'; 2 | 3 | import { environmentConfig } from '@src/configs/custom-environment-variables.config'; 4 | 5 | export const verifyRefreshToken = async function (refreshToken: any): Promise { 6 | return new Promise(function (resolve, reject) { 7 | jwt.verify( 8 | refreshToken, 9 | environmentConfig.REFRESH_TOKEN_SECRET_KEY as jwt.Secret, 10 | (err: VerifyErrors | null, payload: any) => { 11 | if (err) { 12 | return reject(err); 13 | } 14 | 15 | console.log(payload.aud); 16 | const userId = payload.aud; 17 | resolve(userId); 18 | } 19 | ); 20 | }); 21 | }; 22 | 23 | export default verifyRefreshToken; 24 | -------------------------------------------------------------------------------- /src/middlewares/errors/errorHandler.ts: -------------------------------------------------------------------------------- 1 | import { ErrorRequestHandler, NextFunction, Response } from 'express'; 2 | import { ErrorResponse } from '@src/interfaces'; 3 | 4 | export const errorHandlerMiddleware: ErrorRequestHandler = ( 5 | error, 6 | req, 7 | res: Response, 8 | // eslint-disable-next-line no-unused-vars 9 | next: NextFunction 10 | ) => { 11 | const statusCode = error.statusCode || 500; 12 | res?.status(statusCode); 13 | res?.status(statusCode).send({ 14 | data: null, 15 | success: false, 16 | error: true, 17 | message: error.message || 'Internal Server Error', 18 | status: statusCode, 19 | stack: process.env.NODE_ENV === 'production' ? '' : error.stack, 20 | }); 21 | }; 22 | 23 | export default errorHandlerMiddleware; 24 | -------------------------------------------------------------------------------- /src/middlewares/errors/index.ts: -------------------------------------------------------------------------------- 1 | export * from './errorHandler'; 2 | export * from './notFound'; 3 | -------------------------------------------------------------------------------- /src/middlewares/errors/notFound.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | 3 | export function notFoundMiddleware(req: Request, res: Response, next: NextFunction) { 4 | res.status(404); 5 | const error = new Error(`Route - ${req.originalUrl} Not Found`); 6 | 7 | next(error); 8 | } 9 | 10 | export default notFoundMiddleware; 11 | -------------------------------------------------------------------------------- /src/middlewares/file-upload/index.ts: -------------------------------------------------------------------------------- 1 | export * from './uploadImage.middleware'; 2 | -------------------------------------------------------------------------------- /src/middlewares/file-upload/uploadImage.middleware.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { Request, Express } from 'express'; 3 | import multer from 'multer'; 4 | 5 | import { getImageExtension } from '@src/utils'; 6 | 7 | type DestinationCallback = (error: Error | null, destination: string) => void; 8 | type FileNameCallback = (error: Error | null, filename: string) => void; 9 | 10 | // Set Storage Engine 11 | // Configuring and validating the upload 12 | export const fileStorage = multer.diskStorage({ 13 | destination: (request: Request, file: Express.Multer.File, callback: DestinationCallback): void => { 14 | callback(null, 'public/uploads/posts'); 15 | }, 16 | 17 | filename: (req: Request, file: Express.Multer.File, callback: FileNameCallback): void => { 18 | callback(null, `${file.fieldname}-${Date.now()}${getImageExtension(file.mimetype)}`); 19 | }, 20 | }); 21 | 22 | // Initialize upload variable 23 | export const uploadImage = multer({ 24 | storage: fileStorage, 25 | limits: { 26 | fileSize: 1024 * 1024 * 10, // accept files up 10 mgb 27 | }, 28 | }); 29 | 30 | export default { uploadImage }; 31 | -------------------------------------------------------------------------------- /src/middlewares/index.ts: -------------------------------------------------------------------------------- 1 | export * from './auth'; 2 | export * from './errors'; 3 | export * from './file-upload'; 4 | export * from './sort-filter-pagination'; 5 | export * from './validation/authValidation'; 6 | -------------------------------------------------------------------------------- /src/middlewares/sort-filter-pagination/index.ts: -------------------------------------------------------------------------------- 1 | export * from './postsFeatures.middleware'; 2 | -------------------------------------------------------------------------------- /src/middlewares/sort-filter-pagination/postsFeatures.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction } from 'express'; 2 | 3 | import model from '@src/models/Post.model'; 4 | import { TPaginationRequest, TPaginationResponse } from '@src/interfaces'; 5 | 6 | export const postsPaginationMiddleware = () => { 7 | return async (req: TPaginationRequest, res: TPaginationResponse, next: NextFunction) => { 8 | const page = Number(req.query.page) || 1; 9 | const limit = Number(req.query.limit) || 2; 10 | const startIndex = (page - 1) * limit; 11 | const endIndex = page * limit; 12 | 13 | const results: any = { 14 | currentPage: { 15 | page, 16 | limit, 17 | }, 18 | totalDocs: 0, 19 | }; 20 | 21 | const totalCount = await model.countDocuments().exec(); 22 | results.totalDocs = totalCount; 23 | 24 | if (endIndex < totalCount) { 25 | results.next = { 26 | page: page + 1, 27 | limit, 28 | }; 29 | } 30 | 31 | if (startIndex > 0) { 32 | results.previous = { 33 | page: page - 1, 34 | limit, 35 | }; 36 | } 37 | 38 | results.totalPages = Math.ceil(totalCount / limit); 39 | results.lastPage = Math.ceil(totalCount / limit); 40 | 41 | // Sort 42 | const sort: any = {}; 43 | 44 | // Sort 45 | if (req.query.sortBy && req.query.orderBy) { 46 | sort[req.query.sortBy] = req.query.orderBy.toLowerCase() === 'desc' ? -1 : 1; 47 | } else { 48 | sort.createdAt = -1; 49 | } 50 | 51 | // Filter 52 | let filter: any = {}; 53 | if (req.query.filterBy && req.query.category) { 54 | console.log(req.query.category.toLowerCase()); 55 | if (req.query.category.toLowerCase() === 'sports') { 56 | filter.$or = [{ category: 'sports' }]; 57 | } else if (req.query.category.toLowerCase() === 'coding') { 58 | filter.$or = [{ category: 'coding' }]; 59 | } else if (req.query.category.toLowerCase() === 'typescript') { 60 | filter.$or = [{ category: 'typescript' }]; 61 | } else if (req.query.category.toLowerCase() === 'nodejs') { 62 | filter.$or = [{ category: 'nodejs' }]; 63 | } else if (req.query.category.toLowerCase() === 'all') { 64 | filter = {}; 65 | } else { 66 | filter = {}; 67 | } 68 | } 69 | 70 | // Search 71 | if (req.query.search) { 72 | filter = { 73 | $or: [ 74 | { title: { $regex: req.query.search } }, 75 | { content: { $regex: req.query.search } }, 76 | { category: { $regex: req.query.search } }, 77 | ], 78 | }; 79 | } 80 | 81 | try { 82 | results.results = await model 83 | .find(filter) 84 | .select('title content postImage author createdAt updatedAt, category') 85 | .populate( 86 | 'author', 87 | 'name firstName lastName surname email dateOfBirth gender joinedDate isVerified profileImage mobileNumber status role companyName acceptTerms nationality favoriteAnimal address bio' 88 | ) 89 | .limit(limit) 90 | .sort(sort) 91 | .skip(startIndex) 92 | .exec(); 93 | 94 | // Add paginated Results to the request 95 | 96 | res.paginatedResults = results; 97 | next(); 98 | } catch (error) { 99 | return next(error); 100 | } 101 | }; 102 | }; 103 | 104 | export default postsPaginationMiddleware; 105 | -------------------------------------------------------------------------------- /src/middlewares/validation/authValidation/index.ts: -------------------------------------------------------------------------------- 1 | export * from './userSchema'; 2 | export * from './userValidation'; 3 | -------------------------------------------------------------------------------- /src/middlewares/validation/authValidation/userSchema.ts: -------------------------------------------------------------------------------- 1 | import Joi from 'joi'; 2 | // @ts-ignore 3 | import JoiObjectId from 'joi-objectid'; 4 | 5 | const vaildObjectId = JoiObjectId(Joi); 6 | 7 | export const userSchema = { 8 | signupUser: Joi.object({ 9 | name: Joi.string().min(3).max(15).required(), 10 | email: Joi.string().email().required(), 11 | password: Joi.string().min(6).required(), 12 | confirmPassword: Joi.string().required().valid(Joi.ref('password')), 13 | firstName: Joi.string().min(3).max(15), 14 | lastName: Joi.string().min(3).max(15), 15 | familyName: Joi.string().min(3).max(15), 16 | companyName: Joi.string(), 17 | dateOfBirth: Joi.string(), 18 | mobileNumber: Joi.string(), 19 | gender: Joi.string(), 20 | profileImage: Joi.string(), 21 | role: Joi.string(), 22 | favoriteAnimal: Joi.string(), 23 | nationality: Joi.string(), 24 | isVerified: Joi.boolean(), 25 | isDeleted: Joi.boolean(), 26 | status: Joi.string(), 27 | bio: Joi.string().min(10).max(300), 28 | jobTitle: Joi.string().min(2).max(300), 29 | address: Joi.string(), 30 | acceptTerms: Joi.boolean(), 31 | confirmationCode: Joi.string(), 32 | }), 33 | loginUser: Joi.object({ 34 | email: Joi.string().email().required(), 35 | password: Joi.string().min(6).required(), 36 | }), 37 | updateUser: Joi.object({ 38 | name: Joi.string().min(3).max(15), 39 | email: Joi.string().email(), 40 | firstName: Joi.string().min(3).max(15), 41 | lastName: Joi.string().min(3).max(15), 42 | familyName: Joi.string().min(3).max(15), 43 | companyName: Joi.string(), 44 | dateOfBirth: Joi.string(), 45 | mobileNumber: Joi.string(), 46 | gender: Joi.string(), 47 | profileImage: Joi.string(), 48 | role: Joi.string(), 49 | favoriteAnimal: Joi.string(), 50 | nationality: Joi.string(), 51 | isVerified: Joi.boolean(), 52 | isDeleted: Joi.boolean(), 53 | status: Joi.string(), 54 | bio: Joi.string().min(10).max(300), 55 | jobTitle: Joi.string().min(2).max(300), 56 | address: Joi.string(), 57 | acceptTerms: Joi.boolean(), 58 | confirmationCode: Joi.string(), 59 | }), 60 | verifyUserMail: Joi.object({ 61 | token: Joi.string().min(3).max(300).required(), 62 | userId: vaildObjectId().required(), 63 | }), 64 | refreshToken: Joi.object({ 65 | refreshToken: Joi.string().min(3).max(300).required(), 66 | }), 67 | sendVerificationMail: Joi.object({ 68 | email: Joi.string().email().required(), 69 | }), 70 | resetPassword: Joi.object({ 71 | token: Joi.string().min(3).max(300).required(), 72 | userId: vaildObjectId().required(), 73 | password: Joi.string().min(6).required(), 74 | confirmPassword: Joi.string().required().valid(Joi.ref('password')), 75 | }), 76 | }; 77 | 78 | export default userSchema; 79 | -------------------------------------------------------------------------------- /src/middlewares/validation/authValidation/userValidation.ts: -------------------------------------------------------------------------------- 1 | import { RequestHandler } from 'express'; 2 | import mongoose from 'mongoose'; 3 | import validator from '../validator'; 4 | import { userSchema } from './userSchema'; 5 | 6 | export const signupUserValidation: RequestHandler = (req, res, next) => 7 | validator(userSchema.signupUser, req.body, next); 8 | 9 | export const loginUserValidation: RequestHandler = (req, res, next) => validator(userSchema.loginUser, req.body, next); 10 | 11 | export const updateUserValidation: RequestHandler = (req, res, next) => 12 | validator(userSchema.updateUser, req.body, next); 13 | 14 | export const verifyUserMailValidation: RequestHandler = (req, res, next) => { 15 | console.log(mongoose.Types.ObjectId.isValid(req.params.userId)); 16 | return validator(userSchema.verifyUserMail, req.params, next); 17 | }; 18 | 19 | export const refreshTokenValidation: RequestHandler = (req, res, next) => 20 | validator(userSchema.refreshToken, req.body, next); 21 | 22 | export const sendVerificationMailValidation: RequestHandler = (req, res, next) => 23 | validator(userSchema.sendVerificationMail, req.body, next); 24 | 25 | export const resetPasswordValidation: RequestHandler = (req, res, next) => 26 | validator(userSchema.resetPassword, { ...req.body, ...req.params }, next); 27 | -------------------------------------------------------------------------------- /src/middlewares/validation/validator.ts: -------------------------------------------------------------------------------- 1 | import createHttpError from 'http-errors'; 2 | import { NextFunction } from 'express'; 3 | import Joi from 'joi'; 4 | 5 | const validator = async (schemaName: Joi.ObjectSchema, body: object, next: NextFunction) => { 6 | const value = await schemaName.validate(body, { 7 | abortEarly: false, // include all errors 8 | allowUnknown: true, // ignore unknown props 9 | stripUnknown: true, // remove unknown props 10 | }); 11 | 12 | try { 13 | // eslint-disable-next-line no-unused-expressions 14 | value.error ? next(createHttpError(422, value.error.details[0].message)) : next(); 15 | } catch (error) { 16 | console.log(error); 17 | } 18 | }; 19 | 20 | export default validator; 21 | -------------------------------------------------------------------------------- /src/models/Post.model.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from 'mongoose'; 2 | 3 | import { Post } from '@src/interfaces'; 4 | 5 | export const PostSchema: Schema = new Schema( 6 | { 7 | title: { 8 | type: String, 9 | trim: true, 10 | // lowercase: true, 11 | required: [true, 'Please provide title'], 12 | }, 13 | content: { 14 | type: String, 15 | trim: true, 16 | // lowercase: true, 17 | required: [true, 'Please provide post description'], 18 | }, 19 | postImage: { type: String, required: true }, 20 | author: { 21 | // every post shuold blong to user 22 | type: mongoose.Schema.Types.ObjectId, 23 | ref: 'User', // add relationship 24 | required: [true, 'author is required'], 25 | }, 26 | category: { 27 | type: String, 28 | lowercase: true, 29 | enum: ['coding', 'sports', 'nodejs', 'all', 'typescript'], 30 | default: 'all', 31 | trim: true, 32 | }, 33 | }, 34 | 35 | { 36 | timestamps: true, 37 | versionKey: false, 38 | } 39 | ); 40 | 41 | export default mongoose.models.Post || mongoose.model('Post', PostSchema); 42 | -------------------------------------------------------------------------------- /src/models/Token.model.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from 'mongoose'; 2 | import crypto from 'crypto'; 3 | import jwt from 'jsonwebtoken'; 4 | 5 | export interface IToken { 6 | emailVerificationExpiresToken?: string; 7 | emailVerificationToken?: string; 8 | resetPasswordExpires?: string; 9 | resetPasswordToken?: string; 10 | userId: Schema.Types.ObjectId; 11 | accessToken?: string; 12 | refreshToken?: string; 13 | } 14 | 15 | export interface ITokenDocument extends Document, IToken { 16 | generatePasswordReset(): Promise; 17 | generateEmailVerificationToken(): Promise; 18 | generateToken(): Promise; 19 | } 20 | 21 | export const TokenSchema: Schema = new mongoose.Schema( 22 | { 23 | userId: { 24 | type: Schema.Types.ObjectId, 25 | required: true, 26 | ref: 'User', 27 | }, 28 | resetPasswordToken: { 29 | type: String, 30 | required: false, 31 | }, 32 | resetPasswordExpires: { 33 | type: Date, 34 | required: false, 35 | }, 36 | emailVerificationToken: { 37 | type: String, 38 | required: false, 39 | }, 40 | emailVerificationExpiresToken: { 41 | type: Date, 42 | required: false, 43 | }, 44 | accessToken: { 45 | type: String, 46 | required: false, 47 | }, 48 | refreshToken: { 49 | type: String, 50 | required: false, 51 | }, 52 | }, 53 | 54 | { timestamps: true } 55 | ); 56 | 57 | // Generate Password Reset 58 | TokenSchema.methods.generatePasswordReset = function () { 59 | this.resetPasswordToken = crypto.randomBytes(32).toString('hex'); 60 | this.resetPasswordExpires = Date.now() + 3600000; // expires in an hour 61 | }; 62 | 63 | // Generate email verification token 64 | TokenSchema.methods.generateEmailVerificationToken = function () { 65 | this.emailVerificationToken = crypto.randomBytes(32).toString('hex'); 66 | this.emailVerificationExpiresToken = Date.now() + 3600000; // expires in an hour 67 | }; 68 | 69 | // Generate Refresh/Access Token 70 | TokenSchema.methods.generateToken = function ( 71 | payload: { userId: Schema.Types.ObjectId }, 72 | secret: string, 73 | signOptions: any 74 | ): Promise { 75 | return new Promise(function (resolve, reject) { 76 | jwt.sign(payload, secret, signOptions, (err: Error | null, encoded: string | undefined) => { 77 | if (err === null && encoded !== undefined) { 78 | resolve(encoded); 79 | } else { 80 | reject(err); 81 | } 82 | }); 83 | }); 84 | }; 85 | 86 | TokenSchema.post('save', function () { 87 | console.log('Token is been Save ', this); 88 | }); 89 | 90 | export default mongoose.models.Token || mongoose.model('Token', TokenSchema); 91 | -------------------------------------------------------------------------------- /src/models/User.model.ts: -------------------------------------------------------------------------------- 1 | import bcrypt from 'bcrypt'; 2 | import { Schema, Document, model, models } from 'mongoose'; 3 | import jwt from 'jsonwebtoken'; 4 | import validator from 'validator'; 5 | 6 | import { environmentConfig } from '@src/configs/custom-environment-variables.config'; 7 | import { IUser } from '@src/interfaces'; 8 | 9 | export interface IUserDocument extends Document, IUser { 10 | // document level operations 11 | // eslint-disable-next-line no-unused-vars 12 | comparePassword(password: string): Promise; 13 | createJWT(): Promise; 14 | } 15 | 16 | const UserSchema: Schema = new Schema( 17 | { 18 | name: { 19 | type: String, 20 | trim: true, 21 | lowercase: true, 22 | required: [true, 'Please provide name'], 23 | minLength: [3, "Name can't be smaller than 3 characters"], 24 | maxLength: [15, "Name can't be greater than 15 characters"], 25 | }, 26 | firstName: { 27 | type: String, 28 | trim: true, 29 | lowercase: true, 30 | required: [false, 'Please provide first name'], 31 | minLength: [3, "Name can't be smaller than 3 characters"], 32 | maxLength: [15, "Name can't be greater than 15 characters"], 33 | }, 34 | lastName: { 35 | type: String, 36 | required: [false, 'Please provide last name'], 37 | minLength: [3, "Name can't be smaller than 3 characters"], 38 | maxLength: [15, "Name can't be greater than 15 characters"], 39 | trim: true, 40 | lowercase: true, 41 | }, 42 | familyName: { 43 | type: String, 44 | required: false, 45 | trim: true, 46 | minlength: [3, "Name can't be smaller than 3 characters"], 47 | maxLength: [30, "Name can't be greater than 30 characters"], 48 | lowercase: true, 49 | }, 50 | email: { 51 | type: String, 52 | required: true, 53 | trim: true, 54 | lowercase: true, 55 | validate: [validator.isEmail, 'Please provide a valid email'], 56 | maxLength: [128, "Email can't be greater than 128 characters"], 57 | }, 58 | password: { 59 | type: String, 60 | required: [true, 'Please provide password'], 61 | minlength: [6, 'Password must be more than 6 characters'], 62 | trim: true, 63 | }, 64 | confirmPassword: { 65 | type: String, 66 | required: [true, 'Please provide confirmed Password'], 67 | minlength: [6, 'Password must be more than 6 characters'], 68 | trim: true, 69 | }, 70 | companyName: { 71 | type: String, 72 | required: false, 73 | trim: true, 74 | minlength: [3, "Company Name can't be smaller than 3 characters"], 75 | maxLength: [30, "Company Name can't be greater than 30 characters"], 76 | lowercase: true, 77 | }, 78 | dateOfBirth: { 79 | type: String, 80 | maxLength: 15, 81 | trim: true, 82 | }, 83 | mobileNumber: { 84 | type: String, 85 | required: false, 86 | maxLength: [5, "mobileNumber can't be greater than 15 characters"], 87 | // match: [/^(\+\d{1,3}[- ]?)?\d{10}$/, 'Please provide a valid number'], 88 | trim: true, 89 | }, 90 | gender: { type: String, trim: true, lowercase: true }, 91 | joinedDate: { 92 | type: Date, 93 | default: new Date(), 94 | trim: true, 95 | }, 96 | profileImage: { 97 | type: String, 98 | required: false, 99 | default: '/static/uploads/users/temp.png', 100 | lowercase: true, 101 | }, 102 | role: { 103 | type: String, 104 | trim: true, 105 | lowercase: true, 106 | enum: ['user', 'guide', 'admin'], 107 | default: 'user', 108 | }, 109 | favoriteAnimal: { 110 | type: String, 111 | required: false, 112 | trim: true, 113 | minlength: [3, "Favorite Animal can't be smaller than 3 characters"], 114 | maxLength: [35, "Favorite Animal can't be greater than 15 characters"], 115 | lowercase: true, 116 | }, 117 | nationality: { 118 | type: String, 119 | trim: true, 120 | required: false, 121 | lowercase: true, 122 | }, 123 | isVerified: { 124 | type: Boolean, 125 | default: false, 126 | required: false, 127 | }, 128 | isDeleted: { 129 | type: Boolean, 130 | default: false, 131 | }, 132 | status: { 133 | type: String, 134 | enum: ['pending', 'active'], 135 | default: 'pending', 136 | required: false, 137 | trim: true, 138 | lowercase: true, 139 | }, 140 | bio: { 141 | type: String, 142 | required: false, 143 | trim: true, 144 | minlength: [10, "Bio can't be smaller than 10 characters"], 145 | maxLength: [300, "Bio can't be greater than 300 characters"], 146 | lowercase: true, 147 | }, 148 | jobTitle: { 149 | type: String, 150 | required: false, 151 | trim: true, 152 | lowercase: true, 153 | minlength: [2, "Job Title can't be smaller than 3 characters"], 154 | maxLength: [30, "Job Title can't be greater than 15 characters"], 155 | }, 156 | address: { 157 | type: String, 158 | required: false, 159 | trim: true, 160 | lowercase: true, 161 | }, 162 | acceptTerms: { type: Boolean, required: false, default: false }, 163 | confirmationCode: { type: String, require: false, index: true, unique: true, sparse: true }, 164 | resetPasswordToken: { 165 | type: String, 166 | required: false, 167 | }, 168 | resetPasswordExpires: { 169 | type: Date, 170 | required: false, 171 | }, 172 | }, 173 | { 174 | timestamps: true, 175 | } 176 | ); 177 | 178 | UserSchema.methods.comparePassword = async function (candidatePassword: string): Promise { 179 | const isMatch = await bcrypt.compare(candidatePassword, this.password); 180 | return isMatch; 181 | }; 182 | 183 | UserSchema.pre('save', async function (next) { 184 | console.log('Middleware called before saving the user is', this); 185 | // eslint-disable-next-line @typescript-eslint/no-this-alias 186 | const user = this; 187 | if (user.isModified('password')) { 188 | const salt = await bcrypt.genSalt(12); 189 | user.password = await bcrypt.hash(user.password, salt); 190 | user.confirmPassword = await bcrypt.hash(user.password, salt); 191 | } 192 | next(); 193 | }); 194 | 195 | UserSchema.post('save', function () { 196 | console.log('Middleware called after saving the user is (User is been Save )', this); 197 | }); 198 | 199 | UserSchema.methods.createJWT = function () { 200 | const payload = { 201 | userId: this._id, 202 | email: this.email, 203 | name: this.firstName, 204 | dateOfBirth: this.dateOfBirth, 205 | gender: this.gender, 206 | role: this.role, 207 | }; 208 | 209 | return jwt.sign(payload, environmentConfig.TOKEN_SECRET as string, { 210 | expiresIn: environmentConfig.JWT_EXPIRE_TIME, 211 | }); 212 | }; 213 | 214 | export default models.User || model('User', UserSchema); 215 | -------------------------------------------------------------------------------- /src/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Post.model'; 2 | export * from './Token.model'; 3 | export * from './User.model'; 4 | -------------------------------------------------------------------------------- /src/public/uploads/postImage-1619543798929.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/src/public/uploads/postImage-1619543798929.jpeg -------------------------------------------------------------------------------- /src/public/uploads/postImage-1619639718502.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/src/public/uploads/postImage-1619639718502.jpeg -------------------------------------------------------------------------------- /src/public/uploads/postImage-1619640393778.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/src/public/uploads/postImage-1619640393778.jpeg -------------------------------------------------------------------------------- /src/public/uploads/postImage-1619640530261.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/src/public/uploads/postImage-1619640530261.png -------------------------------------------------------------------------------- /src/public/uploads/postImage-1619641184290.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/src/public/uploads/postImage-1619641184290.jpeg -------------------------------------------------------------------------------- /src/public/uploads/postImage-1619641382057.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saddamarbaa/node-express-typescript-social-media-rest-api/689e65e21a4c071a5d2f3c17cab96b6dc275133a/src/public/uploads/postImage-1619641382057.jpeg -------------------------------------------------------------------------------- /src/routes/admin.route.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | 3 | import { isAdmin, isAuth } from '@src/middlewares'; 4 | import { getUsersController } from '@src/controllers'; 5 | 6 | const router = express.Router(); 7 | 8 | router.get('/users', isAuth, isAdmin, getUsersController); 9 | 10 | export = router; 11 | -------------------------------------------------------------------------------- /src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | 3 | import { 4 | isAuth, 5 | loginUserValidation, 6 | refreshTokenValidation, 7 | resetPasswordValidation, 8 | sendVerificationMailValidation, 9 | signupUserValidation, 10 | updateUserValidation, 11 | verifyUserMailValidation, 12 | } from '@src/middlewares'; 13 | import { 14 | loginController, 15 | logoutController, 16 | updateAuthController, 17 | refreshTokenController, 18 | removeAuthController, 19 | resetPasswordController, 20 | sendForgotPasswordMailController, 21 | signupController, 22 | verifyEmailController, 23 | getAuthProfileController, 24 | } from '@src/controllers'; 25 | 26 | const router = express.Router(); 27 | 28 | router.post('/signup', signupUserValidation, signupController); 29 | router.post('/login', loginUserValidation, loginController); 30 | router.post('/logout', refreshTokenValidation, logoutController); 31 | router.patch('/update/:userId', updateUserValidation, isAuth, updateAuthController); 32 | router.delete('/remove/:userId', isAuth, removeAuthController); 33 | router.get('/verify-email/:userId/:token', verifyUserMailValidation, verifyEmailController); 34 | router.post('/refresh-token', refreshTokenValidation, refreshTokenController); 35 | router.post('/forget-password', sendVerificationMailValidation, sendForgotPasswordMailController); 36 | router.post('/reset-password/:userId/:token', resetPasswordValidation, resetPasswordController); 37 | router.get('/me', isAuth, getAuthProfileController); 38 | 39 | export = router; 40 | -------------------------------------------------------------------------------- /src/routes/index.ts: -------------------------------------------------------------------------------- 1 | import express, { Request, Response } from 'express'; 2 | 3 | import { response } from '../utils'; 4 | import { ResponseT } from '../interfaces'; 5 | 6 | const router = express.Router(); 7 | 8 | // GET home page. 9 | router.get('/healthChecker', (req: Request, res: Response>) => { 10 | const message = 'Welcome to blog API'; 11 | res.send(response({ data: null, success: false, error: true, message, status: 200 })); 12 | }); 13 | 14 | export = router; 15 | -------------------------------------------------------------------------------- /src/routes/post.route.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | 3 | import { 4 | createPostController, 5 | getPostsController, 6 | getPostController, 7 | deletePostController, 8 | editPostController, 9 | } from '@src/controllers'; 10 | import { isAdmin, isAuth, postsPaginationMiddleware, uploadImage } from '@src/middlewares'; 11 | 12 | const router = express.Router(); 13 | 14 | router.get('/', postsPaginationMiddleware(), getPostsController); 15 | router.get('/:postId', getPostController); 16 | router.post('/', isAuth, isAdmin, uploadImage.single('postImage'), createPostController); 17 | router.delete('/:postId', isAuth, isAdmin, deletePostController); 18 | router.patch('/:postId', isAuth, isAdmin, uploadImage.single('postImage'), editPostController); 19 | 20 | export = router; 21 | -------------------------------------------------------------------------------- /src/services/admin.service.ts: -------------------------------------------------------------------------------- 1 | import { RequestHandler } from 'express'; 2 | import { InternalServerError } from 'http-errors'; 3 | 4 | import User from '@src/models/User.model'; 5 | import { response } from '@src/utils'; 6 | 7 | export const getUsersService: RequestHandler = async (req, res, next) => { 8 | try { 9 | const users = await User.find().select( 10 | 'name firstName lastName surname email dateOfBirth gender joinedDate isVerified profileImage mobileNumber status role companyName acceptTerms nationality favoriteAnimal address profileImage bio mobileNumber createdAt updatedAt' 11 | ); 12 | 13 | const data = { 14 | user: users, 15 | }; 16 | 17 | return res.status(200).json( 18 | response({ 19 | data, 20 | success: true, 21 | error: false, 22 | message: `Success`, 23 | status: 200, 24 | }) 25 | ); 26 | } catch (error) { 27 | return next(InternalServerError); 28 | } 29 | }; 30 | 31 | export default { 32 | getUsersService, 33 | }; 34 | -------------------------------------------------------------------------------- /src/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './admin.service'; 2 | export * from './auth.service'; 3 | export * from './post.service'; 4 | -------------------------------------------------------------------------------- /src/services/post.service.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | 3 | import Post from '@src/models/Post.model'; 4 | import { isValidMongooseObjectId, response } from '@src/utils'; 5 | import { AuthenticatedRequestBody, Post as TPost, TPaginationResponse } from '@src/interfaces'; 6 | 7 | export const getPostsService = async (_req: Request, res: TPaginationResponse) => { 8 | if (res?.paginatedResults) { 9 | const { results, next, previous, currentPage, totalDocs, totalPages, lastPage } = res.paginatedResults; 10 | const responseObject: any = { 11 | totalDocs: totalDocs || 0, 12 | totalPages: totalPages || 0, 13 | lastPage: lastPage || 0, 14 | count: results?.length || 0, 15 | currentPage: currentPage || 0, 16 | }; 17 | 18 | if (next) { 19 | responseObject.nextPage = next; 20 | } 21 | if (previous) { 22 | responseObject.prevPage = previous; 23 | } 24 | 25 | responseObject.posts = results?.map((doc: TPost) => { 26 | return { 27 | _id: doc?._id, 28 | title: doc?.title, 29 | content: doc?.content, 30 | category: doc?.category, 31 | postImage: doc?.postImage, 32 | createdAt: doc?.createdAt, 33 | updatedAt: doc?.updatedAt, 34 | author: doc?.author, 35 | }; 36 | }); 37 | 38 | return res.status(200).send( 39 | response({ 40 | success: true, 41 | error: false, 42 | message: 'Successful Found posts', 43 | status: 200, 44 | data: responseObject, 45 | }) 46 | ); 47 | } 48 | }; 49 | 50 | export const createPostService = async (req: AuthenticatedRequestBody, res: Response, next: NextFunction) => { 51 | const { title, content, category } = req.body; 52 | 53 | if (!req.file) { 54 | res.status(422).send( 55 | response({ 56 | data: null, 57 | success: false, 58 | error: true, 59 | message: `Invalid request (Please upload Image)`, 60 | status: 422, 61 | }) 62 | ); 63 | } 64 | 65 | const userId = req?.user?._id || ''; 66 | 67 | const postData = new Post({ 68 | title, 69 | content, 70 | category, 71 | postImage: `/static/uploads/posts/${req?.file?.filename}`, 72 | author: userId, 73 | }); 74 | 75 | try { 76 | const createdPost = await Post.create(postData); 77 | 78 | return res.status(201).send( 79 | response({ 80 | data: createdPost, 81 | success: true, 82 | error: false, 83 | message: 'Successfully added new post', 84 | status: 201, 85 | }) 86 | ); 87 | } catch (error) { 88 | return next(error); 89 | } 90 | }; 91 | 92 | export const getPostService = async (req: Request, res: Response, next: NextFunction) => { 93 | if (!isValidMongooseObjectId(req.params.postId) || !req.params.postId) { 94 | return res.status(422).send( 95 | response({ 96 | data: null, 97 | success: false, 98 | error: true, 99 | message: `Invalid request`, 100 | status: 422, 101 | }) 102 | ); 103 | } 104 | 105 | try { 106 | const doc = await Post.findById(req.params.postId); 107 | if (!doc) { 108 | return res.status(400).send( 109 | response<[]>({ 110 | data: [], 111 | success: false, 112 | error: true, 113 | message: `Failed to find post by given ID ${req.params.postId}`, 114 | status: 400, 115 | }) 116 | ); 117 | } 118 | 119 | const data = { 120 | post: { 121 | _id: doc?._id, 122 | title: doc?.title, 123 | content: doc?.content, 124 | postImage: doc?.postImage, 125 | createdAt: doc?.createdAt, 126 | updatedAt: doc?.updatedAt, 127 | author: doc?.author, 128 | category: doc?.category, 129 | }, 130 | }; 131 | 132 | return res.status(200).send( 133 | response<{ post: TPost }>({ 134 | success: true, 135 | error: false, 136 | message: `Successfully Found post by given id: ${req.params.postId}`, 137 | status: 200, 138 | data, 139 | }) 140 | ); 141 | } catch (error) { 142 | console.log('error', error); 143 | return next(error); 144 | } 145 | }; 146 | 147 | export const deletePostService = async (req: Request, res: Response, next: NextFunction) => { 148 | if (!isValidMongooseObjectId(req.params.postId) || !req.params.postId) { 149 | return res.status(422).send( 150 | response({ 151 | data: null, 152 | success: false, 153 | error: true, 154 | message: `Invalid request`, 155 | status: 422, 156 | }) 157 | ); 158 | } 159 | 160 | try { 161 | const toBeDeletedPost = await Post.findByIdAndRemove({ 162 | _id: req.params.postId, 163 | }); 164 | 165 | if (!toBeDeletedPost) { 166 | return res.status(400).send( 167 | response({ 168 | data: null, 169 | success: false, 170 | error: true, 171 | message: `Failed to delete post by given ID ${req.params.postId}`, 172 | status: 400, 173 | }) 174 | ); 175 | } 176 | 177 | return res.status(200).json( 178 | response({ 179 | data: null, 180 | success: true, 181 | error: false, 182 | message: `Successfully deleted post by ID ${req.params.postId}`, 183 | status: 200, 184 | }) 185 | ); 186 | } catch (error) { 187 | return next(error); 188 | } 189 | }; 190 | 191 | export const editPostService = async (req: AuthenticatedRequestBody, res: Response, next: NextFunction) => { 192 | const { title, content, category } = req.body; 193 | if (!isValidMongooseObjectId(req.params.postId) || !req.params.postId) { 194 | return res.status(422).send( 195 | response({ 196 | data: null, 197 | success: false, 198 | error: true, 199 | message: `Invalid request`, 200 | status: 422, 201 | }) 202 | ); 203 | } 204 | 205 | try { 206 | const toBeUpdatedPost = await Post.findById(req.params.postId); 207 | 208 | if (!toBeUpdatedPost) { 209 | return res.status(400).send( 210 | response({ 211 | data: null, 212 | success: false, 213 | error: true, 214 | message: `Failed to update post by given ID ${req.params.postId}`, 215 | status: 400, 216 | }) 217 | ); 218 | } 219 | 220 | toBeUpdatedPost.title = title || toBeUpdatedPost.title; 221 | toBeUpdatedPost.content = content || toBeUpdatedPost.content; 222 | toBeUpdatedPost.postImage = !req.file ? toBeUpdatedPost.postImage : `/static/uploads/posts/${req?.file?.filename}`; 223 | toBeUpdatedPost.category = category || toBeUpdatedPost?.category; 224 | 225 | const updatedPost = await toBeUpdatedPost.save(); 226 | 227 | return res.status(200).json( 228 | response<{ post: TPost }>({ 229 | data: { 230 | post: updatedPost, 231 | }, 232 | success: true, 233 | error: false, 234 | message: `Successfully updated post by ID ${req.params.postId}`, 235 | status: 200, 236 | }) 237 | ); 238 | } catch (error) { 239 | return next(error); 240 | } 241 | }; 242 | 243 | export default { getPostsService, getPostService, createPostService, editPostService }; 244 | -------------------------------------------------------------------------------- /src/utils/generateSecretKey.ts: -------------------------------------------------------------------------------- 1 | import crypto from 'crypto'; 2 | 3 | export const key1 = crypto.randomBytes(32).toString('hex'); 4 | export const key2 = crypto.randomBytes(32).toString('hex'); 5 | console.table({ key1, key2 }); 6 | 7 | export default { key1, key2 }; 8 | -------------------------------------------------------------------------------- /src/utils/getImageExtension.ts: -------------------------------------------------------------------------------- 1 | // Check Image Extension 2 | export const getImageExtension = (mimetype: string) => { 3 | switch (mimetype) { 4 | case 'image/png': 5 | return '.png'; 6 | case 'image/PNG': 7 | return '.PNG'; 8 | case 'image/jpg': 9 | return '.jpg'; 10 | case 'image/JPG': 11 | return '.JPG'; 12 | case 'image/JPEG': 13 | return '.JPEG'; 14 | case 'image/jpeg': 15 | return '.jpeg'; 16 | case 'image/webp': 17 | return '.webp'; 18 | default: 19 | return false; 20 | } 21 | }; 22 | 23 | export default getImageExtension; 24 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './generateSecretKey'; 2 | export * from './getImageExtension'; 3 | export * from './isValidMongooseObjectId'; 4 | export * from './response'; 5 | export * from './sendEmail'; 6 | -------------------------------------------------------------------------------- /src/utils/isValidMongooseObjectId.ts: -------------------------------------------------------------------------------- 1 | import { Types } from 'mongoose'; 2 | 3 | export const isValidMongooseObjectId = (id: string): boolean => { 4 | if (Types.ObjectId.isValid(id)) { 5 | if (String(new Types.ObjectId(id)) === id) return true; 6 | return false; 7 | } 8 | return false; 9 | }; 10 | 11 | export default isValidMongooseObjectId; 12 | -------------------------------------------------------------------------------- /src/utils/mockedData/data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "1615372300349", 4 | "title": "Self-taught developer", 5 | "content": "I'm a self-taught Fullstack Web developer who is passionate about writing code, solving problems, building react App, I Teach Web Development and Documenting my coding journey, I’m looking forward to collaborate on any Open Source project, which I consider interesting or useful.", 6 | "post_image": "uploads/post-image-1615372300349.jpg", 7 | "added_date": "1615372300349" 8 | }, 9 | { 10 | "id": "1614766656226", 11 | "title": "Why learning coding is important?", 12 | "content": "Nowadays with everything being electronic, everything needs to be programmed! \n\nFrom computers, to cars, machines, or anything else it most likely requires programming!\n\nSo as a result, demand for coders keeps increasing year by year, due to all these technological advances!", 13 | "post_image": "uploads/post-image-1614766656226.jpg", 14 | "added_date": "1614766656226" 15 | }, 16 | { 17 | "id": "1613557056226", 18 | "title": "I LOVE JavaScript", 19 | "content": "I have been using JavaScript since the beginning of my coding career!\nI used it to build simple websites and I used it to build large scale applications! \nNow I use it to teach others, as well as create large applications. The possibilities of this language are endless, and the use cases keep increasing every single day! ", 20 | "post_image": "uploads/post-image-1613557056226.png", 21 | "added_date": "1613557056226" 22 | }, 23 | { 24 | "id": "1608718656226", 25 | "title": "My first job as a developer", 26 | "content": "In college, I met a friend at a computer club who was showing a really cool application where you can swipe between different types of clothing!\nBeing very intrigued, I asked my friend if there is any way I can help out and join the team! After some thinking, he told me to finish an assignment, and then they will consider me. Over the weekend, I finished the assignment and was right away told I can join the team, though I would be working for free. That was completely fine for me! ", 27 | "post_image": "uploads/post-image-1608718656226.jpg", 28 | "added_date": "1608718656226" 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /src/utils/response.ts: -------------------------------------------------------------------------------- 1 | import { ResponseT } from '@src/interfaces'; 2 | 3 | export const response = ({ data, success, error, message, status }: ResponseT) => { 4 | return { 5 | success, 6 | error, 7 | message, 8 | status, 9 | data, 10 | }; 11 | }; 12 | 13 | export default response; 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | /* Basic Options */ 5 | "target": "esnext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, 6 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, 7 | "lib": ["dom", "esnext"] /* Specify library files to be included in the compilation. */, 8 | "allowJs": true /* Allow javascript files to be compiled. */, 9 | "outDir": "dist" /* Redirect output structure to the directory. */, 10 | "rootDir": "." /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, 11 | "sourceMap": true, 12 | "removeComments": true /* Do not emit comments to output. */, 13 | /* Strict Type-Checking Options */ 14 | "strict": true /* Enable all strict type-checking options. */, 15 | "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | /* Module Resolution Options */ 17 | "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, 18 | "baseUrl": "./" /* Base directory to resolve non-absolute module names. */, 19 | "paths": { 20 | /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 21 | "@src/*": ["src/*"] 22 | }, 23 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 24 | /* Experimental Options */ 25 | "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 26 | "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 27 | /* Advanced Options */ 28 | "skipLibCheck": true /* Skip type checking of declaration files. */, 29 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 30 | }, 31 | "exclude": ["node_modules", "dist", "coverage"], 32 | "include": ["src"] 33 | } 34 | -------------------------------------------------------------------------------- /tsconfig.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "exclude": ["src/__tests__/", "**/*.test.ts", "**/*.mock.ts"] 4 | } 5 | --------------------------------------------------------------------------------