Skip to content

Commit f671d62

Browse files
author
bastienwcs
committed
init
0 parents  commit f671d62

File tree

7 files changed

+197
-0
lines changed

7 files changed

+197
-0
lines changed

Diff for: .env.sample

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
SERVER_PORT=8080
2+
CLIENT_URL=http://localhost:3000
3+
4+
DB_HOST=localhost
5+
DB_PORT=3306
6+
DB_USER=username for database
7+
DB_PASS=password for user
8+
DB_NAME=database name
9+
10+
JWT_SECRET=secret to use to generate token

Diff for: .eslintrc.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"commonjs": true,
5+
"es2021": true,
6+
"jest/globals": true
7+
},
8+
"extends": ["airbnb-base", "prettier"],
9+
"parserOptions": {
10+
"ecmaVersion": 12
11+
},
12+
"plugins": ["jest"],
13+
"ignorePatterns": ["migrations/**"],
14+
"rules": {
15+
"no-console": "off",
16+
"camelcase": "off",
17+
"no-await-in-loop": "off"
18+
}
19+
}

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
package-lock.json
3+
.env

Diff for: .prettierrc.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"singleQuote": true,
3+
"semi": true
4+
}

Diff for: database.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require("dotenv").config();
2+
const mysql = require("mysql");
3+
4+
const config = {
5+
host: process.env.DB_HOST,
6+
port: process.env.DB_PORT,
7+
user: process.env.DB_USER,
8+
password: process.env.DB_PASS,
9+
database: process.env.DB_NAME
10+
};
11+
12+
const connection = mysql.createPool(config);
13+
14+
module.exports = connection;

Diff for: index.js

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
const express = require('express');
2+
const jwt = require('jsonwebtoken');
3+
const cors = require('cors');
4+
const bcrypt = require('bcrypt');
5+
require('dotenv').config();
6+
const connection = require('./database');
7+
8+
const { SERVER_PORT, CLIENT_URL, JWT_SECRET } = process.env;
9+
10+
const app = express();
11+
12+
app.use(
13+
cors({
14+
origin: CLIENT_URL,
15+
})
16+
);
17+
app.use(express.json());
18+
app.use(express.urlencoded({ extended: true }));
19+
20+
// 1. Register route
21+
app.post('/register', (req, res) => {
22+
const { email, password } = req.body;
23+
if (!email || !password) {
24+
res
25+
.status(400)
26+
.json({ errorMessage: 'Please specify both email and password' });
27+
} else {
28+
const hash = bcrypt.hashSync(password, 10);
29+
connection.query(
30+
`INSERT INTO user(email, password) VALUES (?, ?)`,
31+
[email, hash],
32+
(error, result) => {
33+
if (error) {
34+
res.status(500).json({ errorMessage: error.message });
35+
} else {
36+
res.status(201).json({
37+
id: result.insertId,
38+
email,
39+
});
40+
}
41+
}
42+
);
43+
}
44+
});
45+
46+
// 2. Login route
47+
app.post('/login', (req, res) => {
48+
const { email, password } = req.body;
49+
if (!email || !password) {
50+
res
51+
.status(400)
52+
.json({ errorMessage: 'Please specify both email and password' });
53+
} else {
54+
connection.query(
55+
`SELECT * FROM user WHERE email=?`,
56+
[email],
57+
(error, result) => {
58+
if (error) {
59+
res.status(500).json({ errorMessage: error.message });
60+
} else if (result.length === 0) {
61+
res.status(403).json({ errorMessage: 'Invalid email' });
62+
} else if (bcrypt.compareSync(password, result[0].password)) {
63+
// Passwords match
64+
const user = {
65+
id: result[0].id,
66+
email,
67+
password: 'hidden',
68+
};
69+
const token = jwt.sign({ id: user.id }, JWT_SECRET, {
70+
expiresIn: '1 day',
71+
});
72+
res.status(200).json({ user, token });
73+
} else {
74+
// Passwords don't match
75+
res.status(403).json({ errorMessage: 'Invalid password' });
76+
}
77+
}
78+
);
79+
}
80+
});
81+
82+
// 3. Token middleware
83+
const authenticateWithJsonWebToken = (req, res, next) => {
84+
if (req.headers.authorization !== undefined) {
85+
const token = req.headers.authorization.split(' ')[1];
86+
jwt.verify(token, JWT_SECRET, (err) => {
87+
if (err) {
88+
res
89+
.status(401)
90+
.json({ errorMessage: "you're not allowed to access these data" });
91+
} else {
92+
next();
93+
}
94+
});
95+
} else {
96+
res
97+
.status(401)
98+
.json({ errorMessage: "you're not allowed to access these data" });
99+
}
100+
};
101+
102+
// 4. Authenticated route
103+
app.get('/users', authenticateWithJsonWebToken, (req, res) => {
104+
connection.query(`SELECT * FROM user`, (error, result) => {
105+
if (error) {
106+
res.status(500).json({ errorMessage: error.message });
107+
} else {
108+
res.status(200).json(
109+
result.map((user) => {
110+
return { ...user, password: 'hidden' };
111+
})
112+
);
113+
}
114+
});
115+
});
116+
117+
// Don't write anything below this line
118+
app.listen(SERVER_PORT, () => {
119+
console.log(`Server is running on port ${SERVER_PORT}.`);
120+
});

Diff for: package.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "back-app",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "nodemon index.js"
8+
},
9+
"author": "",
10+
"license": "ISC",
11+
"dependencies": {
12+
"bcrypt": "^5.0.0",
13+
"cors": "^2.8.5",
14+
"dotenv": "^8.2.0",
15+
"express": "^4.17.1",
16+
"jsonwebtoken": "^8.5.1",
17+
"mysql": "^2.18.1"
18+
},
19+
"devDependencies": {
20+
"eslint": "^7.14.0",
21+
"eslint-config-airbnb-base": "^14.2.1",
22+
"eslint-config-prettier": "^6.15.0",
23+
"eslint-plugin-import": "^2.22.1",
24+
"eslint-plugin-jest": "^24.1.3",
25+
"nodemon": "^2.0.6"
26+
}
27+
}

0 commit comments

Comments
 (0)