Skip to content

Commit 9fc3995

Browse files
authoredFeb 8, 2018
Merge pull request #16 from renanlopescoder/v2.1.0
v2.1.0
·
v5.16.03.2.0
2 parents 957f89d + addcf17 commit 9fc3995

File tree

12 files changed

+134
-221
lines changed

12 files changed

+134
-221
lines changed
 

‎Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: pm2 start server.js && pm2 logs all

‎README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
## Node API
55

6-
Application in Node, Express, MongoDB and PM2 to give support to Front End development, this application serving a bunch of AJAX requests to give and manipulate data from database.
6+
### Description
7+
Node API is production ready and open source project in Node, Express and MongoDB
8+
9+
### Support
10+
This application is hosted on Heroku and serve a bunch of AJAX requests to give and manipulate data from database and give a support to test front end applications
711

812
### Showcase
913

@@ -12,7 +16,6 @@ Application in Node, Express, MongoDB and PM2 to give support to Front End devel
1216
|https://typescript-angular4.herokuapp.com/ | https://github.com/renanlopescoder/typescript-angular4 |
1317
|http://mobx-react.herokuapp.com/ | https://github.com/renanlopescoder/mobx-react |
1418

15-
1619
## Routes
1720

1821
#### Projects
@@ -73,23 +76,27 @@ Application in Node, Express, MongoDB and PM2 to give support to Front End devel
7376
- Routes ```./src/routes```
7477
- Models ```./src/models```
7578
- Actions ```./src/actions```
79+
- Services ```./src/services```
7680
- Configurations of Express ```./config/express.js```
7781
- Database configurations ```./config/database.js```
7882
- Server configurations ```./server.js```
7983

8084
## Configuring the API locally
8185

82-
- Download or clone the project access the project folder with the terminal and execute the CLI <code>npm install</code>.
83-
- Run the server <code>npm start</code> (Nodemon)
84-
- Access in your browser <a href="http://localhost:3000">http://localhost:3000</a>
86+
- Download or clone the project access the project folder with the terminal and execute the CLI <code>npm install</code>
87+
- Config your database in ```./congig/database.js``` change ```mongoose.connect('mongodb://localhost/yourDatabaseName');```
88+
- Run the server in development mode <code>npm run dev</code>
89+
- <code>Ctrl + c</code> to exit of logs and run <code>pm2 kill</code> to kill all process of pm2
90+
- Access in your browser <a href="http://localhost:3000/projects">http://localhost:3000/projects</a>
8591

8692
## API Dependencies
8793

8894
- Dependency express - <a href="https://www.npmjs.com/package/express">https://www.npmjs.com/package/express</a>
8995
- Dependency body-parser - <a href="https://www.npmjs.com/package/body-parser">https://www.npmjs.com/package/body-parser</a>
9096
- Dependency cors - <a href="https://www.npmjs.com/package/cors">https://www.npmjs.com/package/cors</a>
91-
- Dependency express-load - <a href="https://www.npmjs.com/package/express-load">https://www.npmjs.com/package/express-load</a>
97+
- Dependency consign - <a href="https://www.npmjs.com/package/consign">https://www.npmjs.com/package/consign</a>
9298
- Dependency PM2 - <a href="http://pm2.keymetrics.io/">http://pm2.keymetrics.io/</a>
99+
- Dependency mongoose - <a href="https://www.npmjs.com/package/mongoose">https://www.npmjs.com/package/mongoose</a>
93100

94101
By: <a href="http://renanlopes.com">Renan Lopes</a>
95102

‎config/express.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
const express = require('express');
22
const bodyParser = require('body-parser');
3-
const load = require('express-load');
43
const cors = require('cors');
4+
const consign = require('consign');
55
const server = express();
66

77
server.use(bodyParser.json());
88
server.set('secret', 'opensecret');
99
server.use(cors({ origin: '*' }));
1010

11-
load('src/models')
12-
.then('src/actions')
13-
.then('src/routes/auth.js')
14-
.then('src/routes')
15-
.into(server);
11+
consign({cwd: process.cwd() + '/src'})
12+
.include("models")
13+
.then("actions")
14+
.then("routes/auth.js")
15+
.then("routes")
16+
.into(server);
1617

1718
module.exports = server;

‎package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
{
2-
"name": "rest_api_node",
3-
"version": "2.0.0",
4-
"description": "NodeJS REST API is a open code NodeJS Back End API",
2+
"name": "node_api",
3+
"version": "2.1.0",
4+
"description": "Node API is production ready and open source project in Node, Express, MongoDB and PM2",
55
"scripts": {
6-
"dev": "pm2 start server.js --watch",
6+
"preinstall": "npm i -g pm2 && pm2 install pm2-logrotate",
7+
"dev": "pm2 start server.js --watch && pm2 logs",
78
"start": "node ./node_modules/.bin/pm2 start server.js"
89
},
910
"author": "Renan Lopes",
1011
"license": "MIT",
1112
"dependencies": {
1213
"bcrypt": "^1.0.2",
1314
"body-parser": "^1.15.2",
15+
"consign": "^0.1.6",
1416
"cors": "^2.8.3",
1517
"express": "^4.14.0",
16-
"express-load": "^1.1.16",
1718
"jsonwebtoken": "^7.2.1",
1819
"mongoose": "^4.7.1",
1920
"nodemailer": "^4.2.0",
2021
"pm2": "^2.9.3"
2122
},
2223
"engines": {
23-
"node": "7.10.1"
24+
"node": "8.9.4"
2425
}
2526
}

‎server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ require('./config/database');
55
const PORT = process.env.PORT || 3000;
66

77
server.listen(PORT, () => {
8-
console.log('Servidor Iniciado');
8+
console.log(`Server running on port ${PORT}`);
99
});

‎src/actions/auth.js

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,21 @@ const saltRounds = 15;
44
const jwt = require('jsonwebtoken');
55
const model = mongoose.model('User');
66

7-
/**
8-
* Auth API para gerenciamento de autenticação de usuários
9-
*
10-
* Requires: Json Web Token, simple-encryptor, bcrypt e mongoose
11-
* @description simple-encrytor usado para criptografar dados do usuário em localStorage e Json Web Token para autenticação do usuário no sistema.
12-
*
13-
* Modelo: user.js
14-
* Nome: User
15-
* Collection no MongoDB: users
16-
* Atualização: EcmaScript 6
17-
* Conceitos Aplicados: Criptografia unidirecional e bidirecional Arrow Functions e Variáveis com Escopo de Bloco.
18-
*
19-
*/
20-
217
module.exports = (app) => {
22-
238
let actions = {};
9+
const SECRET = app.get('secret');
2410

2511
actions.login = (req, res) => {
2612
model.findOne({ email: req.body.email })
2713
.then(
2814
(user) => {
29-
const password = req.body.password;
30-
const hash = user.password;
31-
bcrypt.compare(password, hash, (error, success) => {
15+
bcrypt.compare(req.body.password, user.password, (error, success) => {
3216
if (error) {
33-
console.log('Error, password mismatch with user ' + user.username);
34-
res.sendStatus(401);
17+
res.status(401).send({ error: error, message: 'Password mismatch'});
3518
} else if (success) {
36-
var token = jwt.sign({ user: user.username }, app.get('secret'),{
37-
expiresIn: 84600
38-
});
19+
const token = jwt.sign({ user_id: user._id }, SECRET, { expiresIn: '3h' });
3920
return res.status(200).json(
4021
{
41-
user_id: user._id,
4222
nickname : user.nickname,
4323
username: user.username,
4424
photo : user.photo,
@@ -48,35 +28,25 @@ module.exports = (app) => {
4828
);
4929
};
5030
});
51-
},
52-
(error) => {
53-
console.log('Error, user does not exists');
54-
res.sendStatus(401);
5531
}
5632
)
33+
.catch(error => res.status(401).send({ error: error, message: 'Error, user does not exists' }))
5734
};
5835

5936
actions.verifyToken = (req, res, next) => {
60-
let token = req.get('Autorization');
61-
if(token) {
62-
console.log('Verificando Token');
63-
jwt.verify(
64-
token,
65-
app.get('secret'),
66-
(error, decoded) => {
67-
if(error) {
68-
console.log('Token Rejeitado');
69-
res.sendStatus(401);
70-
}
71-
req.user = decoded;
72-
console.log('Usuario aprovado');
73-
next();
74-
}
75-
);
76-
} else {
77-
console.log('Token não enviado');
78-
res.sendStatus(401);
79-
}
37+
const TOKEN = req.get('Authorization');
38+
if (TOKEN) {
39+
jwt.verify(TOKEN, SECRET, (error, decoded) => {
40+
if (error) {
41+
res.status(401).send({ error: error, message: 'Invalid Token' });
42+
} else {
43+
req.user = decoded;
44+
next();
45+
}
46+
});
47+
} else {
48+
res.status(401).send('Token is required');
49+
};
8050
};
8151

8252
return actions;

‎src/actions/project.js

Lines changed: 19 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,66 +3,34 @@ const model = mongoose.model('Project');
33

44
let actions = {};
55

6-
actions.list = function (req, res){
7-
model.find({},function(error, list){
8-
if(error){
9-
res.status(500).json(error);
10-
}
11-
res.json(list);
12-
});
13-
6+
actions.list = (req, res) => {
7+
model.find({})
8+
.then(projects => res.status(200).json(projects))
9+
.catch(error => res.status(500).json(error))
1410
};
1511

16-
actions.create = function(req, res){
17-
model
18-
.create(req.body).then(function(dados){
19-
res.json(dados);
20-
}, function(error){
21-
console.log(error);
22-
res.status(404).json(error);
23-
});
24-
12+
actions.create = (req, res) => {
13+
model.create(req.body)
14+
.then(user => res.json(user))
15+
.catch(error => res.status(500).json(error))
2516
};
2617

27-
actions.searchById = function(req,res){
28-
29-
model
30-
.findById(req.params.id)
31-
.then(function(id){
32-
33-
res.json(id);
34-
35-
}, function(error){
36-
console.log(error);
37-
res.status(404).json(error);
38-
});
39-
18+
actions.searchById = (req, res) => {
19+
model.findById(req.params.id)
20+
.then(project => res.status(200).json(project))
21+
.catch(error => res.status(404).json(error))
4022
};
4123

42-
actions.deleteById = function(req,res){
24+
actions.deleteById = (req, res) => {
4325
model.remove({_id: req.params.id})
44-
.then(function(){
45-
res.sendStatus(200);
46-
}, function(error){
47-
console.log(error);
48-
res.status(404).json (error);
49-
});
50-
26+
.then(() => res.status(200))
27+
.catch(() => res.status(404).json(error))
5128
};
5229

53-
actions.update = function(req,res){
54-
console.log(req.body);
55-
model
56-
.findByIdAndUpdate(req.params.id, req.body)
57-
.then(function(dado){
58-
59-
res.json(dado);
60-
61-
}, function(error){
62-
console.log(error);
63-
res.status(404).json(error);
64-
});
65-
30+
actions.update = (req, res) => {
31+
model.findByIdAndUpdate(req.params.id, req.body)
32+
.then(project => res.status(200).json(project))
33+
.catch(error => res.status(404).json(error))
6634
};
6735

6836
module.exports = actions;

‎src/actions/user.js

Lines changed: 23 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,47 @@
11
const mongoose = require('mongoose');
2-
const mail = require('../services/mail.js');
2+
const mailService = require('../services/mail.js');
33
const bcrypt = require('bcrypt');
44
const saltRounds = 15;
5-
const transporter = mail().getMail();
5+
const transporter = mailService.config();
66
const model = mongoose.model('User');
77

88
let actions = {};
99

10-
actions.list = function (req, res){
11-
model.find({},function(error, list){
12-
if(error){
13-
res.status(500).json(error);
14-
}
15-
res.json(list);
16-
});
10+
actions.list = (req, res) => {
11+
model.find({})
12+
.then(users => res.status(200).json(users))
13+
.catch(error => res.status(500).json(error))
1714
};
1815

1916
actions.create = (req,res) => {
2017
bcrypt.hash(req.body.password, saltRounds, (err, hash) => {
2118
req.body.password = hash;
2219
model.create(req.body).then(
2320
(user) => {
24-
let mailOptions = {
25-
from: '"Node API" <rest-api-node@gmail.com>',
26-
to: req.body.email,
27-
subject: 'Welcome to Node API',
28-
html: '<p>Welcome to Node API!</p>'
29-
+'<p>This API is developed to provide Front End developers with a server and database configurations for connection testing and to provide a visualization of the data streamlining for the development process. The API provides HTTP methods via AJAX requests to collect, insert and update the given data.</p>'
30-
+'Github: <a href="https://github.com/renanlopescoder/rest-api-node">rest-api-node</a>'
31-
+'<br><br>Happy Hack!,'
32-
+'<br>Node API Team 🤖'
33-
+'<br><img src="http://pluspng.com/img-png/github-octocat-logo-vector-png--896.jpg" alt="Github Logo" height="82" width="82">'
34-
+'<img src="http://mean.io/wp-content/themes/twentysixteen-child/images/nodejs.png" alt="Node Logo" height="52" width="217">'
35-
};
36-
transporter.sendMail(mailOptions, (error, info) => {
37-
if (error) {
38-
return console.log(error);
39-
}
40-
console.log('Message %s sent: %s', info.messageId, info.response);
41-
});
42-
res.json(user);
43-
},
44-
(error) => {
45-
console.log(error);
46-
res.status(404).json(error);
47-
});
48-
});
21+
const content = mailService.content(req.body.email);
22+
transporter.sendMail(content);
23+
res.status(200).json(user);
24+
})
25+
.catch(error => res.status(404).json(error))
26+
})
4927
};
5028

51-
actions.searchById = function(req,res){
52-
53-
model
54-
.findById(req.params.id)
55-
.then(function(id){
56-
57-
res.json(id);
58-
59-
}, function(error){
60-
console.log(error);
61-
res.status(404).json(error);
62-
});
63-
29+
actions.searchById = (req, res) => {
30+
model.findById(req.params.id)
31+
.then(user => res.status(200).json(user))
32+
.catch(error => res.status(404).json(error))
6433
};
6534

66-
actions.deleteById = function(req,res){
35+
actions.deleteById = (req, res) => {
6736
model.remove({_id: req.params.id})
68-
.then(function(){
69-
res.sendStatus(200);
70-
}, function(error){
71-
console.log(error);
72-
res.status(404).json (error);
73-
});
74-
37+
.then(() => res.status(200))
38+
.catch(() => res.status(404).json(error))
7539
};
7640

77-
actions.update = function(req,res){
78-
console.log(req.body);
79-
model
80-
.findByIdAndUpdate(req.params.id, req.body)
81-
.then(function(dado){
82-
83-
res.json(dado);
84-
85-
}, function(error){
86-
console.log(error);
87-
res.status(404).json(error);
88-
});
89-
41+
actions.update = (req, res) => {
42+
model.findByIdAndUpdate(req.params.id, req.body)
43+
.then(user => res.status(200).json(user))
44+
.catch(error => res.status(404).json(error))
9045
};
9146

9247
module.exports = actions;

‎src/routes/auth.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
module.exports = (app) => {
1+
module.exports = (src) => {
22

3-
const action = app.src.actions.auth;
3+
const action = src.actions.auth;
44

5-
app.post('/login', action.login);
5+
src.post('/login', action.login);
66

77
/**
88
*

‎src/routes/project.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
module.exports = (app) => {
1+
module.exports = (src) => {
22

3-
const action = app.src.actions.project;
3+
const action = src.actions.project;
44

5-
app.get('/projects', action.list);
5+
src.get('/projects', action.list);
66

7-
app.post('/projects/create', action.create);
7+
src.post('/projects/create', action.create);
88

9-
app.put('/projects/update/:id', action.update);
9+
src.put('/projects/update/:id', action.update);
1010

11-
app.get('/projects/select/:id', action.searchById);
11+
src.get('/projects/select/:id', action.searchById);
1212

13-
app.delete('/projects/delete/:id', action.deleteById);
13+
src.delete('/projects/delete/:id', action.deleteById);
1414
};

‎src/routes/user.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
module.exports = (app) => {
1+
module.exports = (src) => {
22

3-
const action = app.src.actions.user;
3+
const action = src.actions.user;
44

5-
app.get('/users', action.list);
5+
src.get('/users', action.list);
66

7-
app.post('/users/create', action.create);
7+
src.post('/users/create', action.create);
88

9-
app.put('/users/edit/:id', action.update);
9+
src.put('/users/edit/:id', action.update);
1010

11-
app.get('/users/show/:id', action.searchById);
11+
src.get('/users/show/:id', action.searchById);
1212

13-
app.delete('/users/remove/:id', action.deleteById);
13+
src.delete('/users/remove/:id', action.deleteById);
1414
};

‎src/services/mail.js

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
const nodemailer = require('nodemailer');
2-
3-
module.exports = (app) => {
4-
5-
let api = {};
6-
7-
api.getMail = () => {
8-
9-
let mailConfig = nodemailer.createTransport({
10-
host: 'smtp.gmail.com',
11-
auth: {
12-
user: 'rest.api.node@gmail.com',
13-
pass: 'pnzkxchwwqddzhve'
14-
}
15-
});
16-
return mailConfig;
2+
3+
let mailService = {};
4+
5+
mailService.config = () => (
6+
nodemailer.createTransport({
7+
host: 'smtp.gmail.com',
8+
auth: {
9+
user: 'rest.api.node@gmail.com',
10+
pass: 'pnzkxchwwqddzhve'
11+
}
12+
})
13+
);
14+
15+
mailService.content = userMail => (
16+
{
17+
from: '"Node API" <rest-api-node@gmail.com>',
18+
to: userMail,
19+
subject: 'Welcome to Node API',
20+
html: '<p>Welcome to Node API!</p>'
21+
+'<p>This API is developed to provide Front End developers with a server and database configurations for connection testing and to provide a visualization of the data streamlining for the development process. The API provides HTTP methods via AJAX requests to collect, insert and update the given data.</p>'
22+
+'Github: <a href="https://github.com/renanlopescoder/rest-api-node">rest-api-node</a>'
23+
+'<br><br>Happy Hack!,'
24+
+'<br>Node API Team 🤖'
25+
+'<br><br><img src="http://pluspng.com/img-png/github-octocat-logo-vector-png--896.jpg" alt="Github Logo" height="82" width="82">'
26+
+'<img src="https://raw.githubusercontent.com/renanlopescoder/rest-api-node/master/logo.png" alt="Node Logo" height="65" width="150">'
1727
}
18-
19-
return api;
20-
};
28+
);
29+
30+
module.exports = mailService

0 commit comments

Comments
 (0)
Please sign in to comment.