env variables through different file and optimizing error handling with middleware
This commit is contained in:
+13
-12
@@ -1,16 +1,10 @@
|
|||||||
const Sequelize = require('sequelize'),
|
const Sequelize = require('sequelize'),
|
||||||
DonorsModel = require('../models/donors.model.js'),
|
DonorsModel = require('../models/donors.model.js'),
|
||||||
CampaignsModel = require('../models/campaigns.model.js');
|
GrantsModel = require('../models/grants.model.js');
|
||||||
|
|
||||||
const host = 'am1shyeyqbxzy8gc.cbetxkdyhwsb.us-east-1.rds.amazonaws.com',
|
const connection_uri = process.env.JAWSDB_MARIA_URL;
|
||||||
username = 'fyro63k2989tyibh',
|
|
||||||
password = 'ykjkyenyvxig208z',
|
|
||||||
port = '3306',
|
|
||||||
database = 'n0j9gxnf4ijr7g8t';
|
|
||||||
|
|
||||||
const sequelize = new Sequelize(database, username, password, {
|
const sequelize = new Sequelize(connection_uri, {
|
||||||
host: host,
|
|
||||||
dialect: 'mysql',
|
|
||||||
operatorsAliases: false,
|
operatorsAliases: false,
|
||||||
|
|
||||||
// research for pool/connections
|
// research for pool/connections
|
||||||
@@ -21,17 +15,24 @@ const sequelize = new Sequelize(database, username, password, {
|
|||||||
idle: 10000
|
idle: 10000
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// default options for all models
|
||||||
|
define: {
|
||||||
|
underscored: true, // true: use underscore for automatically added attributes like timestamps below
|
||||||
|
freezeTableName: true, // true: table name/first parameter of define method will be table name
|
||||||
|
timestamps: true // createdAt and updatedAt automatically added
|
||||||
|
},
|
||||||
|
|
||||||
// disable logging; default: console.log
|
// disable logging; default: console.log
|
||||||
logging: false
|
logging: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const db = {};
|
const db = {};
|
||||||
|
|
||||||
//creating tables/models from imported function
|
//creating tables/models from imported functions
|
||||||
const Donors = DonorsModel(sequelize, Sequelize);
|
const Donors = DonorsModel(sequelize, Sequelize);
|
||||||
const Campaigns = CampaignsModel(sequelize, Sequelize);
|
const Grants = GrantsModel(sequelize, Sequelize);
|
||||||
db.donors = Donors;
|
db.donors = Donors;
|
||||||
db.campaigns = Campaigns;
|
db.grants = Grants;
|
||||||
|
|
||||||
db.Sequelize = Sequelize;
|
db.Sequelize = Sequelize;
|
||||||
db.sequelize = sequelize;
|
db.sequelize = sequelize;
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
const db = require('../config/db.config.js'),
|
const db = require('../config/db.config.js'),
|
||||||
bcrypt = require('bcrypt-nodejs'),
|
bcrypt = require('bcrypt-nodejs'),
|
||||||
jwt = require('jsonwebtoken');
|
jwt = require('jsonwebtoken'),
|
||||||
|
errorMaker = require('../helpers/error.maker');
|
||||||
|
|
||||||
const Donors = db.donors;
|
const Donors = db.donors;
|
||||||
|
|
||||||
// Find a Donor by email + login with JWT
|
// Find a Donor by email + login with JWT
|
||||||
exports.login = (req, res) => {
|
exports.login = (req, res, next) => {
|
||||||
Donors.findAll({
|
Donors.findAll({
|
||||||
where: {
|
where: {
|
||||||
email: req.body.email
|
email: req.body.email
|
||||||
@@ -13,15 +14,11 @@ exports.login = (req, res) => {
|
|||||||
})
|
})
|
||||||
.then(donors => {
|
.then(donors => {
|
||||||
if (donors.length < 1) {
|
if (donors.length < 1) {
|
||||||
return res.status(401).json({
|
return next(errorMaker(401, 'Invalid or nonexistent email'));
|
||||||
message: 'Auth failed'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
bcrypt.compare(req.body.password, donors[0].password, (error, result) => {
|
bcrypt.compare(req.body.password, donors[0].password, (error, result) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
return res.status(401).json({
|
return next(error);
|
||||||
message: 'Auth failed'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
const token = jwt.sign(
|
const token = jwt.sign(
|
||||||
@@ -40,16 +37,8 @@ exports.login = (req, res) => {
|
|||||||
token
|
token
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return res.status(401).json({
|
return next(errorMaker(401, 'Invalid user'));
|
||||||
message: 'Auth failed'
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => next(error));
|
||||||
console.log(error);
|
|
||||||
|
|
||||||
return res.status(500).json({
|
|
||||||
error
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,17 +13,13 @@ exports.create = (req, res) => {
|
|||||||
})
|
})
|
||||||
.then(donors => {
|
.then(donors => {
|
||||||
if (donors.length >= 1) {
|
if (donors.length >= 1) {
|
||||||
return res.status(409).json({
|
return next(errorMaker(409, `Email Exists: ${req.body.email}`));
|
||||||
message: 'Email exists'
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// hash and store
|
// hash and store
|
||||||
bcrypt.hash(req.body.password, null, null, function(error, hash) {
|
bcrypt.hash(req.body.password, null, null, function(error, hash) {
|
||||||
// Store hash in your password DB.
|
// Store hash in your password DB.
|
||||||
if (error) {
|
if (error) {
|
||||||
return res.status(500).json({
|
return next(error);
|
||||||
error
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
Donors.create({
|
Donors.create({
|
||||||
first_name: req.body.first_name,
|
first_name: req.body.first_name,
|
||||||
@@ -45,20 +41,12 @@ exports.create = (req, res) => {
|
|||||||
donor
|
donor
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => next(error));
|
||||||
return res.status(500).json({
|
|
||||||
error
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => next(error));
|
||||||
return res.status(500).json({
|
|
||||||
error
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// FETCH all Donors
|
// FETCH all Donors
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = (status, message) => {
|
||||||
|
const error = new Error(message);
|
||||||
|
error.status = status;
|
||||||
|
return error;
|
||||||
|
};
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken'),
|
||||||
|
errorMaker = require('../helpers/error.maker');
|
||||||
|
|
||||||
module.exports = (req, res, next) => {
|
module.exports = (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const token = req.headers.authorization.split(' ')[1];
|
const token = req.headers.authorization.split(' ')[1];
|
||||||
const decoded = jwt.verify(token, process.env.JWT_KEY);
|
const decoded = jwt.verify(token, process.env.JWT_KEY);
|
||||||
req.donorData = decoded; //for use till end of request
|
req.userData = decoded; //for use till end of request
|
||||||
|
|
||||||
next();
|
next();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return res.status(401).json({
|
return next(error);
|
||||||
message: 'Auth failed'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
module.exports = (sequelize, DataTypes) => {
|
|
||||||
const Campaigns = sequelize.define('campaigns', {
|
|
||||||
id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true
|
|
||||||
},
|
|
||||||
first_name: DataTypes.STRING,
|
|
||||||
middle_name: DataTypes.STRING,
|
|
||||||
last_name: DataTypes.STRING,
|
|
||||||
email: DataTypes.STRING,
|
|
||||||
phone: DataTypes.STRING,
|
|
||||||
address: DataTypes.STRING,
|
|
||||||
city: DataTypes.STRING,
|
|
||||||
state: DataTypes.STRING,
|
|
||||||
country: DataTypes.STRING,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
freezeTableName: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return Campaigns;
|
|
||||||
}
|
|
||||||
+30
-36
@@ -1,40 +1,34 @@
|
|||||||
module.exports = (sequelize, DataTypes) => {
|
module.exports = (sequelize, DataTypes) => {
|
||||||
const Donors = sequelize.define(
|
const Donors = sequelize.define('donors', {
|
||||||
'donors',
|
id: {
|
||||||
{
|
type: DataTypes.INTEGER,
|
||||||
id: {
|
primaryKey: true,
|
||||||
type: DataTypes.INTEGER,
|
autoIncrement: true
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true
|
|
||||||
},
|
|
||||||
first_name: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
middle_name: DataTypes.STRING,
|
|
||||||
last_name: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
email: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
isEmail: true,
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
password: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
allowNull: false
|
|
||||||
},
|
|
||||||
age: DataTypes.INTEGER,
|
|
||||||
phone: DataTypes.BIGINT,
|
|
||||||
address: DataTypes.STRING,
|
|
||||||
city: DataTypes.STRING,
|
|
||||||
state: DataTypes.STRING,
|
|
||||||
country: DataTypes.STRING
|
|
||||||
},
|
},
|
||||||
{
|
first_name: {
|
||||||
freezeTableName: true
|
type: DataTypes.STRING,
|
||||||
}
|
allowNull: false
|
||||||
);
|
},
|
||||||
|
middle_name: DataTypes.STRING,
|
||||||
|
last_name: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
isEmail: true,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
age: DataTypes.INTEGER,
|
||||||
|
phone: DataTypes.BIGINT,
|
||||||
|
address: DataTypes.STRING,
|
||||||
|
city: DataTypes.STRING,
|
||||||
|
state: DataTypes.STRING,
|
||||||
|
country: DataTypes.STRING
|
||||||
|
});
|
||||||
return Donors;
|
return Donors;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Campaigns = sequelize.define('campaigns', {
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true
|
||||||
|
},
|
||||||
|
// user_id: {
|
||||||
|
// type: DataTypes.INTEGER,
|
||||||
|
// references: {
|
||||||
|
// // This is a reference to another model
|
||||||
|
// model: Donors,
|
||||||
|
// // This is the column name of the referenced model
|
||||||
|
// key: 'id'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
name: DataTypes.STRING,
|
||||||
|
amount: DataTypes.INTEGER
|
||||||
|
});
|
||||||
|
return Campaigns;
|
||||||
|
};
|
||||||
@@ -4,7 +4,7 @@ const express = require('express'),
|
|||||||
|
|
||||||
const donors = require('../controllers/donors.controller.js');
|
const donors = require('../controllers/donors.controller.js');
|
||||||
|
|
||||||
// Create a new Donor
|
// Signup route
|
||||||
router.post('/', donors.create);
|
router.post('/', donors.create);
|
||||||
|
|
||||||
// Retrieve all Donors
|
// Retrieve all Donors
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
require('dotenv/config');
|
||||||
|
require('../server');
|
||||||
Generated
+6
@@ -117,6 +117,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||||
},
|
},
|
||||||
|
"dotenv": {
|
||||||
|
"version": "6.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
|
||||||
|
"integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"dottie": {
|
"dottie": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.1.tgz",
|
||||||
|
|||||||
+4
-1
@@ -6,7 +6,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"start": "PORT=4200 & set JWT_KEY=secretkey & node server.js",
|
"start": "PORT=4200 & set JWT_KEY=secretkey & node server.js",
|
||||||
"dev": "set NODE_ENV=test & set PORT=4205 & set JWT_KEY=secretkey & nodemon server.js"
|
"dev": "nodemon bin/dev.js"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -25,5 +25,8 @@
|
|||||||
"jsonwebtoken": "^8.4.0",
|
"jsonwebtoken": "^8.4.0",
|
||||||
"mysql2": "^1.6.4",
|
"mysql2": "^1.6.4",
|
||||||
"sequelize": "^4.42.0"
|
"sequelize": "^4.42.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"dotenv": "^6.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
//require dependencies
|
//require dependencies
|
||||||
const express = require('express'),
|
const express = require('express'),
|
||||||
app = express(),
|
app = express(),
|
||||||
router = express.Router(),
|
|
||||||
bodyParser = require('body-parser'),
|
bodyParser = require('body-parser'),
|
||||||
port = process.env.PORT || 4200,
|
port = process.env.PORT,
|
||||||
db = require('./app/config/db.config.js');
|
db = require('./app/config/db.config.js');
|
||||||
|
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
@@ -34,13 +33,13 @@ db.sequelize
|
|||||||
console.error('Unable to connect to the database:', err);
|
console.error('Unable to connect to the database:', err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// force: true will drop the table if it already exists
|
//force: true will drop the table if it already exists
|
||||||
const drop_tables = false;
|
const drop_tables = false;
|
||||||
db.sequelize.sync({ force: drop_tables }).then(() => {
|
db.sequelize.sync({ force: drop_tables }).then(() => {
|
||||||
console.log(`Drop and Resync with { force: ${drop_tables} }`);
|
console.log(`Drop and Resync with { force: ${drop_tables} }`);
|
||||||
});
|
});
|
||||||
|
|
||||||
//define a route, usually this would be a bunch of routes imported from another file
|
//main route for api; perhaps for api docs frontend
|
||||||
app.get('/', function(req, res, next) {
|
app.get('/', function(req, res, next) {
|
||||||
res.send('Welcome to the Ucharify API');
|
res.send('Welcome to the Ucharify API');
|
||||||
});
|
});
|
||||||
@@ -49,18 +48,26 @@ app.get('/', function(req, res, next) {
|
|||||||
app.use('/api/donors', require('./app/routes/donors.route.js'));
|
app.use('/api/donors', require('./app/routes/donors.route.js'));
|
||||||
app.use('/api/auth', require('./app/routes/auth.route.js'));
|
app.use('/api/auth', require('./app/routes/auth.route.js'));
|
||||||
|
|
||||||
|
//404 not found error handling on any other routes
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
const error = new Error('Not found');
|
const error = new Error('Not found');
|
||||||
error.status = 404;
|
error.status = 404;
|
||||||
next(error);
|
next(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//General error handler for anything
|
||||||
app.use((error, req, res, next) => {
|
app.use((error, req, res, next) => {
|
||||||
|
//can log the error internally
|
||||||
|
// console.log(error);
|
||||||
|
|
||||||
|
if (req.app.get('env') !== 'development' && req.app.get('env') !== 'test') {
|
||||||
|
delete error.stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
//status is set from other logic depending on the error itself
|
||||||
res.status(error.status || 500);
|
res.status(error.status || 500);
|
||||||
res.json({
|
res.json({
|
||||||
error: {
|
error: error.message
|
||||||
message: error.message
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user