├── .gitignore ├── DB_TABLES.txt ├── config └── config.json ├── migrations.txt ├── migrations ├── 20190617060224-create-user.js └── 20190617061446-create-user-meta.js ├── models ├── index.js ├── user.js └── user_meta.js ├── package.json ├── routes ├── Controllers │ └── User │ │ └── UserController.js └── index.js ├── server.js └── util └── verifyToken.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .idea 3 | .git 4 | /config/config.json -------------------------------------------------------------------------------- /DB_TABLES.txt: -------------------------------------------------------------------------------- 1 | -------------------- 2 | contact_verification 3 | -------------------- 4 | id 5 | contactNumber -> integer 6 | generatedCode -> integer(5 digit) 7 | status -> string('unused', 'used', 'alreadyUsed') 8 | ================================================= 9 | sequlize cli command: 10 | npx sequelize-cli model:generate --name contact_verification --attributes phone_number:integer,generated_code:integer,status:text,type:string 11 | ================================================= 12 | 13 | 14 | 15 | ---------- 16 | User 17 | ---------- 18 | id 19 | profile_type: string('vet', 'vet shop', 'other') 20 | first_name: string 21 | last_name: string 22 | email: string 23 | password: string 24 | cpf: integer 25 | dob: date 26 | gender: string 27 | monday_opening_door: string 28 | monday_closing_door: string 29 | monday_lunch_from: string 30 | monday_lunch_to: string 31 | tuesday_opening_door: string 32 | tuesday_closing_door: string 33 | tuesday_lunch_from: string 34 | tuesday_lunch_to: string 35 | wednesday_opening_door: string 36 | wednesday_closing_door: string 37 | wednesday_lunch_from: string 38 | wednesday_lunch_to: string 39 | thursday_opening_door: string 40 | thursday_closing_door: string 41 | thursday_lunch_from: string 42 | thursday_lunch_to: string 43 | friday_opening_door: string 44 | friday_closing_door: string 45 | friday_lunch_from: string 46 | friday_lunch_to: string 47 | saturday_opening_door: string 48 | saturday_closing_door: string 49 | saturday_lunch_from: string 50 | saturday_lunch_to: string 51 | sunday_opening_door: string 52 | sunday_closing_door: string 53 | sunday_lunch_from: string 54 | sunday_lunch_to: string 55 | interval: string 56 | monday_flag: boolean 57 | monday_schedule: string 58 | tuesday_flag: boolean 59 | tuesday_schedule: string 60 | wednesday_flag: boolean 61 | wednesday_schedule: string 62 | thursday_flag: boolean 63 | thursday_schedule: string 64 | friday_flag: boolean 65 | friday_schedule: string 66 | saturday_flag: boolean 67 | saturday_schedule: string 68 | sunday_flag: boolean 69 | sunday_schedule: string 70 | twenty_four: boolean 71 | home_service: boolean 72 | number_of_customers_per_schedule: integer 73 | 74 | 75 | ================================================= 76 | sequlize cli command: 77 | npx sequelize-cli model:generate --name user --attributes profile_type:string,first_name:string,last_name:string,email:string,password:string,cpf:integer,dob:date,gender:string,monday_opening_door:string,monday_closing_door:string,monday_lunch_from:string,monday_lunch_to:string,tuesday_opening_door:string,tuesday_closing_door:string,tuesday_lunch_from:string,tuesday_lunch_to:string,wednesday_opening_door:string,wednesday_closing_door:string,wednesday_lunch_from:string,wednesday_lunch_to:string,thursday_opening_door:string,thursday_closing_door:string,thursday_lunch_from:string,thursday_lunch_to:string,friday_opening_door:string,friday_closing_door:string,friday_lunch_from:string,friday_lunch_to:string,saturday_opening_door:string,saturday_closing_door:string,saturday_lunch_from:string,saturday_lunch_to:string,sunday_opening_door:string,sunday_closing_door:string,sunday_lunch_from:string,sunday_lunch_to:string,interval:string,monday_flag:boolean,monday_schedule:string,tuesday_flag:boolean,tuesday_schedule:string,wednesday_flag:boolean,wednesday_schedule:string,thursday_flag:boolean,thursday_schedule:string,friday_flag:boolean,friday_schedule:string,saturday_flag:boolean,saturday_schedule:string,sunday_flag:boolean,sunday_schedule:string,twenty_four:boolean,home_service:boolean,number_of_customers_per_schedule:integer 78 | ================================================= 79 | 80 | -------------- 81 | user_metas 82 | ------------- 83 | id 84 | user_id 85 | meta_key 86 | meta_value 87 | 88 | =========================== 89 | sequlize cli command: 90 | npx sequelize-cli model:generate --name user_meta --attributes user_id:integer,meta_key:string,meta_value:text 91 | 92 | ==================== 93 | 94 | 95 | ----------- 96 | services 97 | ---------- 98 | id 99 | user_id: integer 100 | name: string 101 | category: string 102 | sub_category: string 103 | availability: boolean 104 | price: integer 105 | =========================== 106 | sequlize cli command: 107 | npx sequelize-cli model:generate --name post --attributes name:string,category:string,sub_category:string,availability:boolean,price:integer,user_id:integer 108 | ==================== 109 | 110 | -------------- 111 | user_associate_appointments 112 | ------------- 113 | id 114 | user_id 115 | appointment_id 116 | =========================== 117 | sequlize cli command: 118 | npx sequelize-cli model:generate --name user_associate_appointment --attributes user_id:integer,appointment_id:integer 119 | 120 | ==================== 121 | 122 | 123 | -------------- 124 | appointments 125 | ------------- 126 | id 127 | app_user_id: integer 128 | user_id: integer 129 | service_id: integer 130 | client_name: string 131 | pet_information: string 132 | pet_image_url: string 133 | when: date 134 | price: integer 135 | appointment_record: string 136 | payment_status: boolean 137 | status: string(pending, confirmed, cancelled) 138 | cancelled_status: string 139 | =========================== 140 | sequlize cli command: 141 | npx sequelize-cli model:generate --name post_meta --attributes app_user_id:integer,user_id:integer,service_id:integer,client_name:string,pet_information:string,pet_image_url:string,when:date,price:integer,appointment_record:string,payment_status:boolean,status:string,cancelled_status:string 142 | ==================== 143 | 144 | Run Migrations: 145 | npx sequelize-cli db:migrate 146 | 147 | Undo: 148 | npx sequelize-cli db:migrate:undo 149 | 150 | Undo All: 151 | npx sequelize-cli db:migrate:undo:all 152 | 153 | 154 | Other Properties added in migration: 155 | allowNull: false, 156 | unique: true 157 | references: { model: 'users', key: 'id' } 158 | 159 | indexing in migration: 160 | return queryInterface.createTable('user_meta', { 161 | // columns... 162 | }).then(() => queryInterface.addIndex('user_meta', ['user_id', 'some_one_else'])) 163 | 164 | Association added in Models: 165 | user.hasMany(models.user_meta, {foreignKey: 'user_id'}); 166 | user_meta.belongsTo(models.user, {foreignKey: 'user_id'}); 167 | 168 | user.find({ where: { ...}, include: ['user_meta']}) 169 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "username": "root", 4 | "password": null, 5 | "database": "telas_db", 6 | "host": "127.0.0.1", 7 | "dialect": "mysql" 8 | }, 9 | "test": { 10 | "username": "root", 11 | "password": null, 12 | "database": "telas_db", 13 | "host": "127.0.0.1", 14 | "dialect": "mysql" 15 | }, 16 | "production": { 17 | "username": "root", 18 | "password": null, 19 | "database": "telas_db", 20 | "host": "127.0.0.1", 21 | "dialect": "mysql" 22 | }, 23 | "jwt":{ 24 | "secret":"123456789012345678901234567890" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /migrations.txt: -------------------------------------------------------------------------------- 1 | - npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string,phoneNumber:number(11) 2 | -------------------------------------------------------------------------------- /migrations/20190617060224-create-user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: (queryInterface, Sequelize) => { 4 | return queryInterface.createTable('users', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | profile_type: { 12 | type: Sequelize.STRING 13 | }, 14 | first_name: { 15 | type: Sequelize.STRING, 16 | allowNull: false 17 | }, 18 | last_name: { 19 | type: Sequelize.STRING 20 | }, 21 | email: { 22 | type: Sequelize.STRING, 23 | allowNull: false, 24 | unique: true 25 | }, 26 | password: { 27 | type: Sequelize.STRING, 28 | allowNull: false 29 | }, 30 | cpf: { 31 | type: Sequelize.INTEGER 32 | }, 33 | dob: { 34 | type: Sequelize.DATE 35 | }, 36 | gender: { 37 | type: Sequelize.STRING 38 | }, 39 | monday_opening_door: { 40 | type: Sequelize.STRING 41 | }, 42 | monday_closing_door: { 43 | type: Sequelize.STRING 44 | }, 45 | monday_lunch_from: { 46 | type: Sequelize.STRING 47 | }, 48 | monday_lunch_to: { 49 | type: Sequelize.STRING 50 | }, 51 | tuesday_opening_door: { 52 | type: Sequelize.STRING 53 | }, 54 | tuesday_closing_door: { 55 | type: Sequelize.STRING 56 | }, 57 | tuesday_lunch_from: { 58 | type: Sequelize.STRING 59 | }, 60 | tuesday_lunch_to: { 61 | type: Sequelize.STRING 62 | }, 63 | wednesday_opening_door: { 64 | type: Sequelize.STRING 65 | }, 66 | wednesday_closing_door: { 67 | type: Sequelize.STRING 68 | }, 69 | wednesday_lunch_from: { 70 | type: Sequelize.STRING 71 | }, 72 | wednesday_lunch_to: { 73 | type: Sequelize.STRING 74 | }, 75 | thursday_opening_door: { 76 | type: Sequelize.STRING 77 | }, 78 | thursday_closing_door: { 79 | type: Sequelize.STRING 80 | }, 81 | thursday_lunch_from: { 82 | type: Sequelize.STRING 83 | }, 84 | thursday_lunch_to: { 85 | type: Sequelize.STRING 86 | }, 87 | friday_opening_door: { 88 | type: Sequelize.STRING 89 | }, 90 | friday_closing_door: { 91 | type: Sequelize.STRING 92 | }, 93 | friday_lunch_from: { 94 | type: Sequelize.STRING 95 | }, 96 | friday_lunch_to: { 97 | type: Sequelize.STRING 98 | }, 99 | saturday_opening_door: { 100 | type: Sequelize.STRING 101 | }, 102 | saturday_closing_door: { 103 | type: Sequelize.STRING 104 | }, 105 | saturday_lunch_from: { 106 | type: Sequelize.STRING 107 | }, 108 | saturday_lunch_to: { 109 | type: Sequelize.STRING 110 | }, 111 | sunday_opening_door: { 112 | type: Sequelize.STRING 113 | }, 114 | sunday_closing_door: { 115 | type: Sequelize.STRING 116 | }, 117 | sunday_lunch_from: { 118 | type: Sequelize.STRING 119 | }, 120 | sunday_lunch_to: { 121 | type: Sequelize.STRING 122 | }, 123 | interval: { 124 | type: Sequelize.STRING 125 | }, 126 | monday_flag: { 127 | type: Sequelize.BOOLEAN 128 | }, 129 | monday_schedule: { 130 | type: Sequelize.STRING 131 | }, 132 | tuesday_flag: { 133 | type: Sequelize.BOOLEAN 134 | }, 135 | tuesday_schedule: { 136 | type: Sequelize.STRING 137 | }, 138 | wednesday_flag: { 139 | type: Sequelize.BOOLEAN 140 | }, 141 | wednesday_schedule: { 142 | type: Sequelize.STRING 143 | }, 144 | thursday_flag: { 145 | type: Sequelize.BOOLEAN 146 | }, 147 | thursday_schedule: { 148 | type: Sequelize.STRING 149 | }, 150 | friday_flag: { 151 | type: Sequelize.BOOLEAN 152 | }, 153 | friday_schedule: { 154 | type: Sequelize.STRING 155 | }, 156 | saturday_flag: { 157 | type: Sequelize.BOOLEAN 158 | }, 159 | saturday_schedule: { 160 | type: Sequelize.STRING 161 | }, 162 | sunday_flag: { 163 | type: Sequelize.BOOLEAN 164 | }, 165 | sunday_schedule: { 166 | type: Sequelize.STRING 167 | }, 168 | twenty_four: { 169 | type: Sequelize.BOOLEAN 170 | }, 171 | home_service: { 172 | type: Sequelize.BOOLEAN 173 | }, 174 | number_of_customers_per_schedule: { 175 | type: Sequelize.INTEGER 176 | }, 177 | createdAt: { 178 | allowNull: false, 179 | type: Sequelize.DATE 180 | }, 181 | updatedAt: { 182 | allowNull: false, 183 | type: Sequelize.DATE 184 | } 185 | }); 186 | }, 187 | down: (queryInterface, Sequelize) => { 188 | return queryInterface.dropTable('users'); 189 | } 190 | }; -------------------------------------------------------------------------------- /migrations/20190617061446-create-user-meta.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | up: (queryInterface, Sequelize) => { 4 | return queryInterface.createTable('user_meta', { 5 | id: { 6 | allowNull: false, 7 | autoIncrement: true, 8 | primaryKey: true, 9 | type: Sequelize.INTEGER 10 | }, 11 | user_id: { 12 | type: Sequelize.INTEGER, 13 | references: { model: 'users', key: 'id' }, 14 | allowNull: false 15 | }, 16 | meta_key: { 17 | type: Sequelize.STRING, 18 | allowNull: false 19 | }, 20 | meta_value: { 21 | type: Sequelize.TEXT 22 | }, 23 | createdAt: { 24 | allowNull: false, 25 | type: Sequelize.DATE 26 | }, 27 | updatedAt: { 28 | allowNull: false, 29 | type: Sequelize.DATE 30 | } 31 | }); 32 | }, 33 | down: (queryInterface, Sequelize) => { 34 | return queryInterface.dropTable('user_meta'); 35 | } 36 | }; -------------------------------------------------------------------------------- /models/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const Sequelize = require('sequelize'); 6 | const basename = path.basename(__filename); 7 | const env = process.env.NODE_ENV || 'development'; 8 | const config = require(__dirname + '/../config/config.json')[env]; 9 | const db = {}; 10 | 11 | let sequelize; 12 | if (config.use_env_variable) { 13 | sequelize = new Sequelize(process.env[config.use_env_variable], config); 14 | } else { 15 | sequelize = new Sequelize(config.database, config.username, config.password, config); 16 | } 17 | 18 | fs 19 | .readdirSync(__dirname) 20 | .filter(file => { 21 | return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); 22 | }) 23 | .forEach(file => { 24 | const model = sequelize['import'](path.join(__dirname, file)); 25 | db[model.name] = model; 26 | }); 27 | 28 | Object.keys(db).forEach(modelName => { 29 | if (db[modelName].associate) { 30 | db[modelName].associate(db); 31 | } 32 | }); 33 | 34 | db.sequelize = sequelize; 35 | db.Sequelize = Sequelize; 36 | 37 | module.exports = db; 38 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = (sequelize, DataTypes) => { 3 | const user = sequelize.define('user', { 4 | profile_type: DataTypes.STRING, 5 | first_name: DataTypes.STRING, 6 | last_name: DataTypes.STRING, 7 | email: DataTypes.STRING, 8 | password: DataTypes.STRING, 9 | cpf: DataTypes.INTEGER, 10 | dob: DataTypes.DATE, 11 | gender: DataTypes.STRING, 12 | monday_opening_door: DataTypes.STRING, 13 | monday_closing_door: DataTypes.STRING, 14 | monday_lunch_from: DataTypes.STRING, 15 | monday_lunch_to: DataTypes.STRING, 16 | tuesday_opening_door: DataTypes.STRING, 17 | tuesday_closing_door: DataTypes.STRING, 18 | tuesday_lunch_from: DataTypes.STRING, 19 | tuesday_lunch_to: DataTypes.STRING, 20 | wednesday_opening_door: DataTypes.STRING, 21 | wednesday_closing_door: DataTypes.STRING, 22 | wednesday_lunch_from: DataTypes.STRING, 23 | wednesday_lunch_to: DataTypes.STRING, 24 | thursday_opening_door: DataTypes.STRING, 25 | thursday_closing_door: DataTypes.STRING, 26 | thursday_lunch_from: DataTypes.STRING, 27 | thursday_lunch_to: DataTypes.STRING, 28 | friday_opening_door: DataTypes.STRING, 29 | friday_closing_door: DataTypes.STRING, 30 | friday_lunch_from: DataTypes.STRING, 31 | friday_lunch_to: DataTypes.STRING, 32 | saturday_opening_door: DataTypes.STRING, 33 | saturday_closing_door: DataTypes.STRING, 34 | saturday_lunch_from: DataTypes.STRING, 35 | saturday_lunch_to: DataTypes.STRING, 36 | sunday_opening_door: DataTypes.STRING, 37 | sunday_closing_door: DataTypes.STRING, 38 | sunday_lunch_from: DataTypes.STRING, 39 | sunday_lunch_to: DataTypes.STRING, 40 | interval: DataTypes.STRING, 41 | monday_flag: DataTypes.BOOLEAN, 42 | monday_schedule: DataTypes.STRING, 43 | tuesday_flag: DataTypes.BOOLEAN, 44 | tuesday_schedule: DataTypes.STRING, 45 | wednesday_flag: DataTypes.BOOLEAN, 46 | wednesday_schedule: DataTypes.STRING, 47 | thursday_flag: DataTypes.BOOLEAN, 48 | thursday_schedule: DataTypes.STRING, 49 | friday_flag: DataTypes.BOOLEAN, 50 | friday_schedule: DataTypes.STRING, 51 | saturday_flag: DataTypes.BOOLEAN, 52 | saturday_schedule: DataTypes.STRING, 53 | sunday_flag: DataTypes.BOOLEAN, 54 | sunday_schedule: DataTypes.STRING, 55 | twenty_four: DataTypes.BOOLEAN, 56 | home_service: DataTypes.BOOLEAN, 57 | number_of_customers_per_schedule: DataTypes.INTEGER 58 | }, {}); 59 | user.associate = function(models) { 60 | user.hasMany(models.user_meta, {foreignKey: 'user_id'}); 61 | }; 62 | return user; 63 | }; -------------------------------------------------------------------------------- /models/user_meta.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = (sequelize, DataTypes) => { 3 | const user_meta = sequelize.define('user_meta', { 4 | user_id: DataTypes.INTEGER, 5 | meta_key: DataTypes.STRING, 6 | meta_value: DataTypes.TEXT 7 | }, {}); 8 | user_meta.associate = function(models) { 9 | // associations can be defined here 10 | user_meta.belongsTo(models.user, {foreignKey: 'user_id'}); 11 | }; 12 | return user_meta; 13 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "telas-api", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "nodejs", 11 | "+", 12 | "sequelize", 13 | "+", 14 | "jwt" 15 | ], 16 | "author": "Akash Ahmad", 17 | "license": "ISC", 18 | "dependencies": { 19 | "bcrypt": "^3.0.6", 20 | "body-parser": "^1.19.0", 21 | "cors": "^2.8.5", 22 | "express": "^4.17.0", 23 | "jsonwebtoken": "^8.5.1", 24 | "mysql2": "^1.6.5", 25 | "sequelize": "^5.8.6", 26 | "sequelize-cli": "^5.4.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /routes/Controllers/User/UserController.js: -------------------------------------------------------------------------------- 1 | const db = require("../../../models"); 2 | const bcrypt = require('bcrypt'); 3 | const jsonwebtoken = require('jsonwebtoken'); 4 | const config = require("../../../config/config.json"); 5 | 6 | const UserController = { 7 | //getting data from database 8 | all: (req, res) => { 9 | const response = {}; 10 | try { 11 | db.user.findAll({ 12 | attributes: ['id', ['first_name','firstName'], 'email'], 13 | include: ['user_meta'] 14 | }) 15 | .then(data => { 16 | response.statusCode = 200; 17 | response.body = JSON.stringify({ 18 | message: 'Ok', 19 | data: data 20 | }); 21 | res.status(response.statusCode).send(response.body); 22 | }).catch(err => { 23 | response.statusCode = 500; 24 | response.body = JSON.stringify({err}); 25 | res.status(response.statusCode).send(response.body); 26 | }); 27 | 28 | } catch (err) { 29 | response.statusCode = 500; 30 | response.body = JSON.stringify({err}); 31 | res.status(response.statusCode).send(response.body); 32 | } 33 | }, 34 | getOne: (req, res) => { 35 | const response = {}; 36 | try { 37 | if("undefined" !== req.params.id){ 38 | db.user.findOne({ 39 | attributes: ['id', 'first_name', 'email'], 40 | where: {id: req.params.id} 41 | }).then(data=>{ 42 | response.statusCode = 200; 43 | response.body = JSON.stringify({ 44 | message: 'Ok', 45 | data: data 46 | }); 47 | res.status(response.statusCode).send(response.body); 48 | }) 49 | .catch(err=>{ 50 | response.statusCode = 500; 51 | response.body = JSON.stringify({err}); 52 | res.status(response.statusCode).send(response.body); 53 | }); 54 | } 55 | } catch (err) { 56 | response.statusCode = 500; 57 | response.body = JSON.stringify({err}); 58 | res.status(response.statusCode).send(response.body); 59 | } 60 | }, 61 | create: (req, res) => { 62 | const response = {}; 63 | try { 64 | if(!req.body.firstName){ 65 | response.statusCode = 400; 66 | response.body = JSON.stringify({ 67 | message: 'First Name is required', 68 | data: "", 69 | }); 70 | res.status(response.statusCode).send(response.body); 71 | } 72 | if(!req.body.email){ 73 | response.statusCode = 400; 74 | response.body = JSON.stringify({ 75 | message: 'Email is required', 76 | data: "", 77 | }); 78 | res.status(response.statusCode).send(response.body); 79 | } 80 | if(!req.body.password){ 81 | response.statusCode = 400; 82 | response.body = JSON.stringify({ 83 | message: 'Password is required', 84 | data: "", 85 | }); 86 | res.status(response.statusCode).send(response.body); 87 | } 88 | else { 89 | return db.user.count({ where: { email: req.body.email } }) 90 | .then(count => { 91 | if (count != 0) { 92 | response.statusCode = 400; 93 | response.body = JSON.stringify({ 94 | message: 'Email already Exsist', 95 | data: "", 96 | }); 97 | res.status(response.statusCode).send(response.body); 98 | } 99 | else { 100 | let password = bcrypt.hashSync(req.body.password, 10); 101 | db.user.create({ 102 | first_name: req.body.firstName, 103 | last_name:req.body.lastName, 104 | email:req.body.email, 105 | password: password, 106 | profile_type: req.body.profileType, 107 | cpf: req.body.cpf, 108 | dob: req.body.dob, 109 | gender: req.body.gender, 110 | monday_opening_door: req.body.mondayOpeningDoor, 111 | monday_closing_door: req.body.mondayClosingDoor, 112 | monday_lunch_from: req.body.mondayLunchFrom, 113 | monday_lunch_to: req.body.mondayLunchTo, 114 | tuesday_opening_door: req.body.tuesdayOpeningDoor, 115 | tuesday_closing_door: req.body.tuesdayClosingDoor, 116 | tuesday_lunch_from: req.body.tuesdayLunchFrom, 117 | tuesday_lunch_to: req.body.tuesdayLunchTo, 118 | wednesday_opening_door: req.body.wednesdayOpeningDoor, 119 | wednesday_closing_door: req.body.wednesdayClosingDoor, 120 | wednesday_lunch_from: req.body.wednesdayLunchFrom, 121 | wednesday_lunch_to: req.body.wednesdayLunchTo, 122 | thursday_opening_door: req.body.thursdayOpeningDoor, 123 | thursday_closing_door: req.body.thursdayClosingDoor, 124 | thursday_lunch_from: req.body.thursdayLunchFrom, 125 | thursday_lunch_to: req.body.thursdayLunchTo, 126 | friday_opening_door: req.body.fridayOpeningDoor, 127 | friday_closing_door: req.body.fridayClosingDoor, 128 | friday_lunch_from: req.body.fridayLunchFrom, 129 | friday_lunch_to: req.body.fridayLunchTo, 130 | saturday_opening_door: req.body.saturdayOpeningDoor, 131 | saturday_closing_door: req.body.saturdayClosingDoor, 132 | saturday_lunch_from: req.body.saturdayLunchFrom, 133 | saturday_lunch_to: req.body.saturdayLunchTo, 134 | sunday_opening_door: req.body.sundayOpeningDoor, 135 | sunday_closing_door: req.body.sundayClosingDoor, 136 | sunday_lunch_from: req.body.sundayLunchFrom, 137 | sunday_lunch_to: req.body.sundayLunchTo, 138 | interval: req.body.interval, 139 | monday_flag: req.body.mondayFlag, 140 | monday_schedule: req.body.mondaySchedule, 141 | tuesday_flag: req.body.tuesdayFlag, 142 | tuesday_schedule: req.body.tuesdaySchedule, 143 | wednesday_flag: req.body.wednesdayFlag, 144 | wednesday_schedule: req.body.wednesdaySchedule, 145 | thursday_flag: req.body.thursdayFlag, 146 | thursday_schedule: req.body.thursdaySchedule, 147 | friday_flag: req.body.fridayFlag, 148 | friday_schedule: req.body.fridaySchedule, 149 | saturday_flag: req.body.saturdayFlag, 150 | saturday_schedule: req.body.saturdaySchedule, 151 | sunday_flag: req.body.sundayFlag, 152 | sunday_schedule: req.body.sundaySchedule, 153 | twenty_four: req.body.twentyFour, 154 | home_service: req.body.homeService, 155 | number_of_customers_per_schedule: req.body.numberOfCustomersPerSchedule 156 | }).then(data=>{ 157 | let {meta} = req.body; 158 | if(meta){ 159 | let metaDestructure = []; 160 | if(meta.length>0){ 161 | meta.forEach((item)=>{ 162 | metaDestructure.push({ 163 | user_id : data.id, 164 | meta_key : item.metaKey, 165 | meta_value: item.metaValue 166 | }); 167 | }) 168 | } 169 | db.user_meta.bulkCreate(metaDestructure) 170 | } 171 | // signin user and generate a jwt 172 | const token = jsonwebtoken.sign({ 173 | id: data.id, 174 | email: data.email 175 | }, config.jwt.secret, { expiresIn: '1y' }); 176 | let finalMeta = []; 177 | if(meta){ 178 | db.user_meta.findAll({ 179 | attributes: ['id', ['meta_key','metaKey'],['meta_value','metaValue'],['user_id','userId']], 180 | where: {user_id: data.id} 181 | }).then(metaData=>{ 182 | finalMeta = [...metaData]; 183 | data = { 184 | firstName: data.first_name, 185 | last_name: data.lastName, 186 | email: data.email, 187 | profileType: data.profile_type, 188 | cpf: data.cpf, 189 | dob: data.dob, 190 | gender: data.gender, 191 | mondayOpeningDoor: data.monday_opening_door, 192 | mondayClosingDoor: data.monday_closing_door, 193 | mondayLunchFrom: data.monday_lunch_from, 194 | mondayLunchTo: data.monday_lunch_to, 195 | tuesdayOpeningDoor: data.tuesday_opening_door , 196 | tuesdayClosingDoor: data.tuesday_closing_door , 197 | tuesdayLunchFrom: data.tuesday_lunch_from, 198 | tuesdayLunchTo: data.tuesday_lunch_to, 199 | wednesdayOpeningDoor: data.wednesday_opening_door, 200 | wednesdayClosingDoor: data.wednesday_closing_door , 201 | wednesdayLunchFrom: data.wednesday_lunch_from, 202 | wednesdayLunchTo: data.wednesday_lunch_to, 203 | thursdayOpeningDoor: data.thursday_opening_door, 204 | thursdayClosingDoor: data.thursday_closing_door, 205 | thursdayLunchFrom: data.thursday_lunch_from, 206 | thursdayLunchTo: data.thursday_lunch_to, 207 | fridayOpeningDoor: data.friday_opening_door, 208 | fridayClosingDoor: data.friday_closing_door, 209 | fridayLunchFrom: data.friday_lunch_from, 210 | fridayLunchTo: data.friday_lunch_to, 211 | saturdayOpeningDoor: data.saturday_opening_door, 212 | saturdayClosingDoor: data.saturday_closing_door, 213 | saturdayLunchFrom: data.saturday_lunch_from, 214 | saturdayLunchTo: data.saturday_lunch_to, 215 | sundayOpeningDoor: data.sunday_opening_door , 216 | sundayClosingDoor: data.sunday_closing_door , 217 | sundayLunchFrom: data.sunday_lunch_from , 218 | sundayLunchTo: data.sunday_lunch_to , 219 | interval: data.interval, 220 | mondayFlag: data.monday_flag, 221 | mondaySchedule: data.monday_schedule, 222 | tuesdayFlag: data.tuesday_flag, 223 | tuesdaySchedule: data.tuesday_schedule, 224 | wednesdayFlag: data.wednesday_flag, 225 | wednesdaySchedule: data.wednesday_schedule, 226 | thursdayFlag: data.thursday_flag, 227 | thursdaySchedule: data.thursday_schedule, 228 | fridayFlag: data.friday_flag, 229 | fridaySchedule: data.friday_schedule , 230 | saturdayFlag: data.saturday_flag , 231 | saturdaySchedule: data.saturday_schedule, 232 | sundayFlag: data.sunday_flag , 233 | sundaySchedule: data.sunday_schedule , 234 | twentyFour: data.twenty_four , 235 | homeService: data.home_service , 236 | numberOfCustomersPerSchedule: data.number_of_customers_per_schedule, 237 | meta: finalMeta 238 | }; 239 | response.statusCode = 200; 240 | response.body = JSON.stringify({ 241 | message: 'New User Created', 242 | data: data, 243 | token: token 244 | }); 245 | res.status(response.statusCode).send(response.body); 246 | }) 247 | } 248 | else { 249 | data = { 250 | firstName: data.first_name, 251 | last_name: data.lastName, 252 | email: data.email, 253 | profileType: data.profile_type, 254 | cpf: data.cpf, 255 | dob: data.dob, 256 | gender: data.gender, 257 | mondayOpeningDoor: data.monday_opening_door, 258 | mondayClosingDoor: data.monday_closing_door, 259 | mondayLunchFrom: data.monday_lunch_from, 260 | mondayLunchTo: data.monday_lunch_to, 261 | tuesdayOpeningDoor: data.tuesday_opening_door , 262 | tuesdayClosingDoor: data.tuesday_closing_door , 263 | tuesdayLunchFrom: data.tuesday_lunch_from, 264 | tuesdayLunchTo: data.tuesday_lunch_to, 265 | wednesdayOpeningDoor: data.wednesday_opening_door, 266 | wednesdayClosingDoor: data.wednesday_closing_door , 267 | wednesdayLunchFrom: data.wednesday_lunch_from, 268 | wednesdayLunchTo: data.wednesday_lunch_to, 269 | thursdayOpeningDoor: data.thursday_opening_door, 270 | thursdayClosingDoor: data.thursday_closing_door, 271 | thursdayLunchFrom: data.thursday_lunch_from, 272 | thursdayLunchTo: data.thursday_lunch_to, 273 | fridayOpeningDoor: data.friday_opening_door, 274 | fridayClosingDoor: data.friday_closing_door, 275 | fridayLunchFrom: data.friday_lunch_from, 276 | fridayLunchTo: data.friday_lunch_to, 277 | saturdayOpeningDoor: data.saturday_opening_door, 278 | saturdayClosingDoor: data.saturday_closing_door, 279 | saturdayLunchFrom: data.saturday_lunch_from, 280 | saturdayLunchTo: data.saturday_lunch_to, 281 | sundayOpeningDoor: data.sunday_opening_door , 282 | sundayClosingDoor: data.sunday_closing_door , 283 | sundayLunchFrom: data.sunday_lunch_from , 284 | sundayLunchTo: data.sunday_lunch_to , 285 | interval: data.interval, 286 | mondayFlag: data.monday_flag, 287 | mondaySchedule: data.monday_schedule, 288 | tuesdayFlag: data.tuesday_flag, 289 | tuesdaySchedule: data.tuesday_schedule, 290 | wednesdayFlag: data.wednesday_flag, 291 | wednesdaySchedule: data.wednesday_schedule, 292 | thursdayFlag: data.thursday_flag, 293 | thursdaySchedule: data.thursday_schedule, 294 | fridayFlag: data.friday_flag, 295 | fridaySchedule: data.friday_schedule , 296 | saturdayFlag: data.saturday_flag , 297 | saturdaySchedule: data.saturday_schedule, 298 | sundayFlag: data.sunday_flag , 299 | sundaySchedule: data.sunday_schedule , 300 | twentyFour: data.twenty_four , 301 | homeService: data.home_service , 302 | numberOfCustomersPerSchedule: data.number_of_customers_per_schedule, 303 | meta: finalMeta 304 | }; 305 | response.statusCode = 200; 306 | response.body = JSON.stringify({ 307 | message: 'New User Created', 308 | data: data, 309 | token: token 310 | }); 311 | res.status(response.statusCode).send(response.body); 312 | } 313 | }) 314 | .catch(err=>{ 315 | response.statusCode = 500; 316 | response.body = JSON.stringify({err}); 317 | res.status(response.statusCode).send(response.body); 318 | res.status(response.statusCode).send(response.body); 319 | }); 320 | } 321 | }); 322 | } 323 | } catch (err) { 324 | response.statusCode = 500; 325 | response.body = JSON.stringify({errors:err}); 326 | res.status(response.statusCode).send(response.body); 327 | } 328 | }, 329 | update: (req, res) => { 330 | const response = {}; 331 | try { 332 | let data = []; 333 | if(req.body.hasOwnProperty("password")){ 334 | data["password"] = bcrypt.hashSync(req.body.password, 10); 335 | } 336 | data["firstName"] = req.body.firstName; 337 | data["lastName"] = req.body.lastName; 338 | data["email"] = req.body.email; 339 | let password = bcrypt.hashSync(req.body.password, 10); 340 | db.user.update(data, { 341 | where: { 342 | id:req.params.id 343 | } 344 | }).then(()=>{ 345 | response.statusCode = 200; 346 | response.body = JSON.stringify({ 347 | message: 'User Updated', 348 | data: "" 349 | }); 350 | res.status(response.statusCode).send(response.body); 351 | }) 352 | .catch(err=>{ 353 | response.statusCode = 506; 354 | response.body = JSON.stringify({err}); 355 | console.log(err); 356 | res.status(response.statusCode).send(response.body); 357 | }); 358 | } catch (err) { 359 | response.statusCode = 500; 360 | response.body = JSON.stringify({err}); 361 | res.status(response.statusCode).send(response.body); 362 | } 363 | }, 364 | delete: (req, res) => { 365 | const response = {}; 366 | try { 367 | db.user.destroy({ 368 | where: { 369 | id:req.body.id 370 | } 371 | }).then(()=>{ 372 | response.statusCode = 200; 373 | response.body = JSON.stringify({ 374 | message: 'User Deleted', 375 | data: "" 376 | }); 377 | res.status(response.statusCode).send(response.body); 378 | }) 379 | .catch(err=>{ 380 | response.statusCode = 500; 381 | response.body = JSON.stringify({err}); 382 | res.status(response.statusCode).send(response.body); 383 | }); 384 | } catch (err) { 385 | response.statusCode = 500; 386 | response.body = JSON.stringify({err}); 387 | res.status(response.statusCode).send(response.body); 388 | } 389 | }, 390 | login: (req, res) => { 391 | const response = {}; 392 | try { 393 | db.user.findOne({ 394 | where: { email:req.body.email } 395 | }).then((user)=>{ 396 | if (!user) { 397 | //throw new Error('No user with that email') 398 | response.statusCode = 500; 399 | response.body = JSON.stringify({ 400 | message: 'Incorrect credentials', 401 | data: "" 402 | }); 403 | res.status(response.statusCode).send(response.body); 404 | } 405 | else { 406 | bcrypt.compare(req.body.password, user.password) 407 | .then(valid => { 408 | if (!valid) { 409 | //throw new Error('No user with that email') 410 | response.statusCode = 404; 411 | response.body = JSON.stringify({ 412 | message: 'Incorrect credentials', 413 | data: "" 414 | }); 415 | res.status(response.statusCode).send(response.body); 416 | } 417 | else { 418 | // signin user and generate a jwt 419 | const token = jsonwebtoken.sign({ 420 | id: user.id, 421 | email: user.email, 422 | firstName: user.firstName 423 | }, config.jwt.secret, { expiresIn: '1y' }) 424 | 425 | // return json web token 426 | response.statusCode = 200; 427 | response.body = JSON.stringify({ 428 | message: 'User LoggedIN', 429 | data: "", 430 | token: token 431 | }); 432 | res.status(response.statusCode).send(response.body); 433 | } 434 | }) 435 | } 436 | }) 437 | .catch(err=>{ 438 | response.statusCode = 500; 439 | response.body = JSON.stringify({err}); 440 | res.status(response.statusCode).send(response.body); 441 | }); 442 | } catch (err) { 443 | response.statusCode = 500; 444 | response.body = JSON.stringify({err}); 445 | res.status(response.statusCode).send(response.body); 446 | } 447 | } 448 | }; 449 | module.exports = UserController; -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | const cors = require('cors'); 2 | const bodyParser = require('body-parser'); 3 | // const jwt = require('express-jwt'); 4 | const verifyToken = require("../util/verifyToken"); 5 | 6 | 7 | // const jwt = require('express-jwt'); 8 | 9 | // Import Route Controllers 10 | const users = require('./Controllers/User/UserController'); 11 | 12 | 13 | // authentication middleware 14 | // const authMiddleware = jwt({ 15 | // secret: 'somesuperdupersecret' 16 | // }); 17 | 18 | // Setup Route Bindings 19 | exports = module.exports = function (app) { 20 | 21 | // middlewares 22 | // Configure app for bodyParser() 23 | // lets us grab data from the body of POST 24 | app.use(bodyParser.urlencoded({ extended: true })); 25 | app.use(bodyParser.json()); 26 | app.use(cors()); 27 | 28 | // auth middleware 29 | // const auth = jwt({ 30 | // secret: config.jwt.secret, 31 | // credentialsRequired: false 32 | // }); 33 | // MIDDLEWARE - 34 | // Middleware can be very useful for doing validations. We can log 35 | // things from here or stop the request from continuing in the event 36 | // that the request is not safe. 37 | // middleware to use for all requests 38 | // router.use(function (req, res, next) { 39 | // // console.log('middleware going on...'); 40 | // next(); 41 | // }); 42 | 43 | app.route('/api/users') 44 | .get(users.all) 45 | .post(users.create); 46 | app.get('/api/users/:id', users.getOne); 47 | app.put('/api/users/:id', verifyToken, users.update); 48 | app.post('/api/login', users.login); 49 | }; -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const express = require('express'); 3 | const endpoints = require('./routes'); 4 | 5 | // Set up port for server to listen on 6 | let port = process.env.PORT || 8000; 7 | 8 | /*express is using create a http server*/ 9 | const app = express(); 10 | 11 | // //routes 12 | endpoints(app); 13 | 14 | //Listing port 15 | // Fire up server 16 | // Print friendly message to console 17 | app.listen(port, () => { 18 | console.log('app started at port 8000'); 19 | }); -------------------------------------------------------------------------------- /util/verifyToken.js: -------------------------------------------------------------------------------- 1 | let jwt = require('jsonwebtoken'); 2 | const config = require('../config/config.json'); 3 | 4 | let verifyToken = (req, res, next) => { 5 | const response = {}; 6 | try{ 7 | let token = req.headers['x-access-token'] || req.headers['authorization']; // Express headers are auto converted to lowercase 8 | if (token) { 9 | if (token.startsWith('Bearer ')) { 10 | // Remove Bearer from string 11 | token = token.slice(7, token.length); 12 | } 13 | jwt.verify(token, config.jwt.secret, (err, decoded) => { 14 | console.log(err,decoded); 15 | if (err) { 16 | response.statusCode =401; 17 | response.body = JSON.stringify({ 18 | message: 'Token is not valid', 19 | data: "" 20 | }); 21 | res.status(response.statusCode).send(response.body); 22 | } else { 23 | req.decoded = decoded; 24 | next(); 25 | } 26 | }); 27 | } else { 28 | return res.status(401).json({ 29 | success: false, 30 | message: 'Auth token is not supplied' 31 | }); 32 | } 33 | } 34 | catch(err) { 35 | response.statusCode = 505; 36 | response.body = JSON.stringify({err}); 37 | res.status(response.statusCode).send(response.body); 38 | } 39 | 40 | }; 41 | 42 | module.exports = verifyToken; --------------------------------------------------------------------------------