Skip to content

Commit f056198

Browse files
committed
initialize api boilerplate project
1 parent ad2e52e commit f056198

File tree

17 files changed

+8134
-0
lines changed

17 files changed

+8134
-0
lines changed

.gitignore

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
9+
# Diagnostic reports (https://nodejs.org/api/report.html)
10+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
*.lcov
24+
25+
# nyc test coverage
26+
.nyc_output
27+
28+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29+
.grunt
30+
31+
# Bower dependency directory (https://bower.io/)
32+
bower_components
33+
34+
# node-waf configuration
35+
.lock-wscript
36+
37+
# Compiled binary addons (https://nodejs.org/api/addons.html)
38+
build/Release
39+
40+
# Dependency directories
41+
node_modules/
42+
jspm_packages/
43+
44+
# TypeScript v1 declaration files
45+
typings/
46+
47+
# TypeScript cache
48+
*.tsbuildinfo
49+
50+
# Optional npm cache directory
51+
.npm
52+
53+
# Optional eslint cache
54+
.eslintcache
55+
56+
# Microbundle cache
57+
.rpt2_cache/
58+
.rts2_cache_cjs/
59+
.rts2_cache_es/
60+
.rts2_cache_umd/
61+
62+
# Optional REPL history
63+
.node_repl_history
64+
65+
# Output of 'npm pack'
66+
*.tgz
67+
68+
# Yarn Integrity file
69+
.yarn-integrity
70+
71+
# dotenv environment variables file
72+
#.env
73+
.env.test
74+
75+
# parcel-bundler cache (https://parceljs.org/)
76+
.cache
77+
78+
# Next.js build output
79+
.next
80+
81+
# Nuxt.js build / generate output
82+
.nuxt
83+
dist
84+
85+
# Gatsby files
86+
.cache/
87+
# Comment in the public line in if your project uses Gatsby and *not* Next.js
88+
# https://nextjs.org/blog/next-9-1#public-directory-support
89+
# public
90+
91+
# vuepress build output
92+
.vuepress/dist
93+
94+
# Serverless directories
95+
.serverless/
96+
97+
# FuseBox cache
98+
.fusebox/
99+
100+
# DynamoDB Local files
101+
.dynamodb/
102+
103+
# TernJS port file
104+
.tern-port
105+
106+
107+
.DS_Store
108+
.env.example
109+
.idea/
110+
111+
.env

app.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
const dotenv = require('dotenv')
2+
dotenv.config()
3+
const express = require('express')
4+
const app = express()
5+
const routeManager = require('./route/route.manager.js')
6+
const db = require("./models/index");
7+
const cors = require('cors')
8+
const bodyParser = require('body-parser')
9+
10+
app.use(bodyParser.json())
11+
app.use(bodyParser.urlencoded({extended: false}));
12+
app.use(cors());
13+
14+
db.sequelize.sync()
15+
.then(() => {
16+
console.log("sync db.");
17+
})
18+
.catch((err) => {
19+
console.log("Failed to sync db: " + err.message);
20+
});
21+
22+
routeManager(app)
23+
24+
// error handler
25+
app.use(function (err, req, res, next) {
26+
console.error(err.stack)
27+
res.status(500).json({
28+
status: 'fail',
29+
code : 500,
30+
error : `Can't find ${err.stack}`
31+
});
32+
});
33+
34+
// 404 handler
35+
app.use(function (req, res, next) {
36+
res.status(404).json({
37+
status: 'fail',
38+
code : 404,
39+
error : `Can't find ${req.originalUrl}`
40+
});
41+
});
42+
43+
44+
app.listen(process.env.PORT, () => {
45+
console.log(`Server is running on port ${process.env.PORT}.`);
46+
});

config/config.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"development": {
3+
"username": "root",
4+
"password": "",
5+
"database": "api_db_development",
6+
"host": "127.0.0.1",
7+
"dialect": "mysql"
8+
},
9+
"test": {
10+
"username": "root",
11+
"password": "",
12+
"database": "api_db_test",
13+
"host": "127.0.0.1",
14+
"dialect": "mysql"
15+
},
16+
"production": {
17+
"username": "root",
18+
"password": "",
19+
"database": "api_db_production",
20+
"host": "127.0.0.1",
21+
"dialect": "mysql"
22+
}
23+
}

config/logger.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const winston = require('winston');
2+
3+
const logConfiguration = {
4+
5+
format: winston.format.combine(
6+
winston.format.timestamp({
7+
format: 'MMM-DD-YYYY HH:mm:ss'
8+
}),
9+
winston.format.printf(info => `${info.level}: ${[info.timestamp]}: ${info.message}`),
10+
),
11+
transports: [
12+
new winston.transports.Console(),
13+
new winston.transports.File({filename: 'logs/error/error.log', level: 'error'}),
14+
new winston.transports.File({filename: 'logs/activity/activity.log', level:'info'})
15+
],
16+
};
17+
18+
const logger = winston.createLogger(logConfiguration);
19+
20+
21+
22+
module.exports = logger;

controller/hello.controller.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
const hello = (req, res) => {
3+
res.send('Hello World!')
4+
}
5+
6+
7+
module.exports = {
8+
hello
9+
}

controller/user.controller.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
const db = require("../models");
2+
const User = db.user;
3+
const bcrypt = require('bcrypt');
4+
const jwt = require('jsonwebtoken');
5+
const logger = require('../config/logger');
6+
7+
8+
const signUp = async (req, res) => {
9+
// user signup using email and password bcrypt
10+
const {firstname, lastname, username, email, password} = req.body;
11+
const salt = bcrypt.genSaltSync(10);
12+
const hash = bcrypt.hashSync(password, salt);
13+
const user = {
14+
firstname,
15+
lastname,
16+
username,
17+
email,
18+
password: hash
19+
}
20+
21+
const [row, created] = await User.findOrCreate({
22+
where : {email: user.email},
23+
defaults: user,
24+
});
25+
if (created) {
26+
res.send({
27+
"status" : "success",
28+
"message": "User created successfully",
29+
data : row
30+
})
31+
return;
32+
}
33+
res.send({
34+
"status" : "error",
35+
"message": "User already exists",
36+
"email" : row.email,
37+
})
38+
}
39+
40+
const signIn = async (req, res) => {
41+
// user signin using email and password bcrypt
42+
const {email, password} = req.body;
43+
const user = await User.findOne({where: {email}});
44+
if (user) {
45+
const validPassword = bcrypt.compareSync(password, user.password);
46+
if (validPassword) {
47+
// generate jwt token for user
48+
const token = jwt.sign({
49+
id : user.id,
50+
username: user.username,
51+
email : user.email,
52+
}, process.env.TOKEN_SECRET, {
53+
expiresIn: '1h'
54+
});
55+
logger.info(`User ${user.username} logged in successfully`);
56+
res.send({
57+
"status" : "success",
58+
"message": "User logged in successfully",
59+
"token" : token,
60+
"data" : user
61+
})
62+
return;
63+
}
64+
}
65+
res.send({
66+
"status" : "error",
67+
"message": "Invalid email or password",
68+
})
69+
}
70+
71+
72+
const getAllUsers = async (req, res) => {
73+
const users = await User.findAll();
74+
res.send({
75+
"status" : "success",
76+
"message": "Users fetched successfully",
77+
"data" : users
78+
});
79+
}
80+
81+
82+
module.exports = {
83+
signUp,
84+
signIn,
85+
getAllUsers
86+
}

ecosystem.config.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module.exports = {
2+
apps: [{
3+
script : 'app.js',
4+
watch : '.',
5+
env_dev : {
6+
name : 'api-boilerplate-development',
7+
NODE_ENV : 'development',
8+
PORT : 4444,
9+
TOKEN_SECRET: "Malatya44",
10+
11+
},
12+
env_test: {
13+
name : "api-boilerplate-test",
14+
PORT : 4445,
15+
NODE_ENV : "test",
16+
TOKEN_SECRET: "Malatya44"
17+
},
18+
env_prod: {
19+
name : "api-boilerplate-prod",
20+
PORT : 4446,
21+
NODE_ENV : "production",
22+
TOKEN_SECRET: "Malatya44"
23+
},
24+
}],
25+
};

middleware/auth.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const jwt = require('jsonwebtoken')
2+
3+
4+
module.exports.checkAuth= (req, res, next) => {
5+
try {
6+
const token = req.headers.authorization.split(" ")[1]
7+
const decodedToken = jwt.verify(token, process.env.TOKEN_SECRET)
8+
next();
9+
} catch (error) {
10+
if (error.name === "TokenExpiredError") {
11+
return res.status(401).send({
12+
message: 'Expired token',
13+
status: -1
14+
})
15+
} else if (error.name === "JsonWebTokenError") {
16+
return res.status(401).send({
17+
message: 'Invalid token',
18+
status: -1
19+
})
20+
} else {
21+
return res.status(401).send({
22+
message: 'Unauthorized access',
23+
status: -1
24+
})
25+
}
26+
27+
}
28+
}

0 commit comments

Comments
 (0)