Skip to content

Commit

Permalink
Create basic Node/Express server with MongoDB
Browse files Browse the repository at this point in the history
  • Loading branch information
jurkian committed Nov 4, 2019
1 parent 999fdb7 commit 3b0fff3
Show file tree
Hide file tree
Showing 19 changed files with 4,298 additions and 0 deletions.
10 changes: 10 additions & 0 deletions api/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
PORT=3001

MONGODB_URI=mongodb://127.0.0.1:27017/react-bank-api

JWT_SECRET_KEY=key
JWT_EXPIRATION=10000

MAILGUN_API_KEY=apikey
MAILGUN_DOMAIN=domain.com
MAILGUN_HOST=apihost.com
3 changes: 3 additions & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/node_modules
/config
.env
67 changes: 67 additions & 0 deletions api/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require('module-alias/register');
const CONFIG = require('@config/config');

// Mongoose
require('./db/mongoose');

// Routes
const userRouter = require('@routes/users');
const cardRouter = require('@routes/cards');
const messageRouter = require('@routes/messages');
const transactionRouter = require('@routes/transactions');

// Others
const express = require('express');
const bodyParser = require('body-parser');
const helmet = require('helmet');
const compression = require('compression');
const cors = require('cors');
const chalk = require('chalk');

// Middlewares
const auth = require('@middleware/auth');
const errorHandler = require('@middleware/error-handler');
// const maintenance = require('@middleware/maintenance');

// App
const app = express();

// Maintenance mode
// app.use(maintenance());

app.use(bodyParser.json({ limit: '5mb' }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(helmet());
app.use(compression());

// CORS
app.use(cors());

// Routes
app.use(userRouter);
app.use(cardRouter);
app.use(messageRouter);
app.use(transactionRouter);

// Handle errors only in development
if (process.env.NODE_ENV === 'development') {
app.use(errorHandler());
} else {
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send('Server Error');
});
}

// Start the app
app.listen(CONFIG.port, () => {
console.log(
'%s App is running at http://localhost:%d in %s mode',
chalk.green('✓'),
process.env.PORT,
process.env.NODE_ENV
);
console.log(' Press CTRL-C to stop\n');
});

module.exports = app;
15 changes: 15 additions & 0 deletions api/db/mongoose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const CONFIG = require('@config/config');
const mongoose = require('mongoose');
const chalk = require('chalk');

mongoose.connect(`${CONFIG.mongodb_uri}`, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false
});

mongoose.connection.on('error', err => {
console.error(err);
console.log('%s MongoDB connection error. Please make sure MongoDB is running.', chalk.red('✗'));
process.exit();
});
15 changes: 15 additions & 0 deletions api/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@config/*": ["config/*"],
"@controllers/*": ["controllers/*"],
"@middleware/*": ["middleware/*"],
"@models/*": ["models/*"],
"@routes/*": ["routes/*"],
"@util/*": ["util/*"],
"@validations/*": ["validations/*"]
}
},
"exclude": ["node_modules"]
}
35 changes: 35 additions & 0 deletions api/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const CONFIG = require('@config/config');
let jwt = require('jsonwebtoken');

const User = require('@models/user');

// Utilities
const { throwError, passError, handleValidationErrors } = require('@util/errors');

// Verify JWT and add user to next requests
const auth = async (req, res, next) => {
try {
let token = req.header('Authorization');

if (!token) {
throwError('Auth token not available or incorrect', 422);
}

token = token.replace('Bearer ', '');

const decoded = jwt.verify(token, CONFIG.jwt_secret_key);
const user = await User.findByPk(decoded.id);

if (!user) {
throwError('No user found or token is incorrect', 422);
}

req.token = token;
req.user = user;
next();
} catch (err) {
passError(err, next);
}
};

module.exports = auth;
5 changes: 5 additions & 0 deletions api/middleware/error-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = (error, req, res, next) => {
const { statusCode = 500, message, data } = error;

res.status(statusCode).json({ message, data });
};
21 changes: 21 additions & 0 deletions api/middleware/maintenance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Block GET requests
// app.use((req, res, next) => {
// if (req.method === 'GET') {
// res.send('GET requests are disabled')
// } else {
// next()
// }
// })

// Utilities
const { throwError, passError, handleValidationErrors } = require('@util/errors');

const maintenance = async (req, res, next) => {
try {
res.status(503).json({ message: 'Site is currently down. Check back soon!' });
} catch (err) {
passError(err, next);
}
};

module.exports = maintenance;
15 changes: 15 additions & 0 deletions api/models/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const mongoose = require('mongoose');
const validator = require('validator');

const Card = mongoose.model('Card', {
number: {
type: Number,
required: true
},
isActive: {
type: Boolean,
default: true
}
});

module.exports = Card;
15 changes: 15 additions & 0 deletions api/models/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const mongoose = require('mongoose');
const validator = require('validator');

const Message = mongoose.model('Message', {
content: {
type: String,
required: true
},
isRead: {
type: Boolean,
default: false
}
});

module.exports = Message;
11 changes: 11 additions & 0 deletions api/models/transaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const mongoose = require('mongoose');
const validator = require('validator');

const Transaction = mongoose.model('Transaction', {
date: {
type: Date,
required: true
}
});

module.exports = Transaction;
38 changes: 38 additions & 0 deletions api/models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// const { throwError, passError, handleValidationErrors } = require('@util/errors');
// const bcrypt = require('bcryptjs');

const mongoose = require('mongoose');
const validator = require('validator');

const User = mongoose.model('User', {
username: {
type: String,
required: true,
trim: true,
lowercase: true
},
email: {
type: String,
required: true,
trim: true,
lowercase: true
},
password: {
type: String,
required: true,
minlength: 7,
trim: true
},
firstName: {
type: String,
required: true,
minlength: 2
},
lastName: {
type: String,
required: true,
minlength: 2
}
});

module.exports = User;
Loading

0 comments on commit 3b0fff3

Please sign in to comment.