-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathserver.js
More file actions
199 lines (175 loc) · 7.67 KB
/
server.js
File metadata and controls
199 lines (175 loc) · 7.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
const express = require('express');
const app = express();
const port = 3000;
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
//The bcryptjs module is used to hash/encrypt passwords so that we don't include the actual password in our database
const bcrypt = require('bcryptjs');
// Require the config file
const config = require('./config.json');
// Get the Model for our Product
const Product = require('./models/products');
// Get the Model for our Users
const User = require('./models/users');
// Connect to Mongoose
// To get the url to connect with you need to first have a cluster on mongodb, as well as a username and password for a user that has read and write permissions.
// In our config.json we have a MONGO_USER, MONGO_PASSWORD AND MONGO_CLUSTER_NAME. You can find all of these through mongodb
// you also need to tell it what database are you wanting to connect to. In the example bellow we are connecting to the shop database.
// You will need to replace that with the name of the database you are wanting to connect to.
// You do NOT need to create the database and tables on mongoDB itself, mongoose will do it for you. If it can't find the database or tables you are wanting to connect to, then it will create them for you.
mongoose.connect(`mongodb+srv://${config.MONGO_USER}:${config.MONGO_PASSWORD}@${config.MONGO_CLUSTER_NAME}.mongodb.net/shop?retryWrites=true&w=majority`, {useNewUrlParser: true});
// Test the connection to mongoose
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('we are connected to mongo db');
});
// Convert our json data which gets sent into JS so we can process it
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
// Allow Cross Origin requests, ie http to https requests
app.use(cors());
// Create a console message showing us what request we are asking for
app.use(function(req, res, next){
console.log(`${req.method} request for ${req.url}`);
next();
});
//Home Route
app.get('/', function(req, res){
res.send('Welcome to our Products API. Use endpoints to filter out the data');
});
//Add a new Product
app.post('/product', function(req, res){
const product = new Product({
_id: new mongoose.Types.ObjectId(),
name: req.body.name,
price: req.body.price,
user_id: req.body.userId
});
product.save().then(result => {
res.send(result);
}).catch(err => res.send(err));
});
// Get all Products
app.get('/allProducts', function(req, res){
Product.find().then(result => {
res.send(result);
})
})
app.get('/product/:id', function(req, res) {
const id = req.params.id;
Product.findById(id, function(err, product) {
if (err) {
res.send(err);
} else {
res.send(product);
}
});
})
//Get single Product based on ID
app.post('/product/:id', function(req, res){
const id = req.params.id;
// we need to check to see if the product which we are asking for actually belongs to the
// user who is requesting it. If they aren't then we will send them back a 401 error
// The same thing is being done with the edit and delete functions
Product.findById(id, function (err, product) {
if(product['user_id'] == req.body.userId){
res.send(product);
} else {
res.send('401');
}
});
});
// Update a product based on id
app.patch('/product/:id', function(req, res){
const id = req.params.id;
Product.findById(id, function(err, product){
if(product['user_id'] == req.body.userId){
const newProduct = {
name: req.body.name,
price: req.body.price
};
Product.updateOne({ _id : id }, newProduct).then(result => {
res.send(result);
}).catch(err => res.send(err));
} else {
res.send('401');
}
}).catch(err => res.send('cannot find product with that id'));
})
// Delete a product based on id
app.delete('/product/:id', function(req, res){
const id = req.params.id;
Product.findById(id, function(err, product){
if(product['user_id'] == req.body.userId){
Product.deleteOne({ _id: id }, function (err) {
res.send('deleted');
});
} else {
res.send('401');
}
}).catch(err => res.send('cannot find product with that id'));
});
// Register Route
app.post('/users', function(req, res){
// We first want to check the database to see if there is already a user with the username we are registering
// The findOne function requires you to specify what column you are searching in and then with what value.
// In this example we are searching the User table, for the row which for the column username, mathces the value we type in the front end (req.body.username)
User.findOne({ username: req.body.username }, function (err, checkUser) {
// checkUser is the result of the findOne() function.
// if we find one then checkUser is an object with all the information about the user, but if we don't then checkUser is nothihng/null/empty
if(checkUser){
// the username you are asking for already exists
res.send('user already exists');
} else {
// the username you are asking for is available
//hash the password
const hash = bcrypt.hashSync(req.body.password);
// Create a user based on the User Model and fill it with the values from the front end
// Make sure to save your hashed password and not the regular one
const user = new User({
_id: new mongoose.Types.ObjectId(),
username: req.body.username,
email: req.body.email,
password: hash
});
// Save the user in the database
user.save().then(result => {
// send the result back to the front end.
res.send(result);
}).catch(err => res.send(err));
}
});
})
// Login Route
app.post('/getUser', function(req, res){
// Just like the register route, we need to check to see if the username already exists (each username needs to be unique)
User.findOne({ username: req.body.username }, function (err, checkUser) {;
// If it already exists then we want to tell the user to choose another username
if(checkUser){
// A user exists
// Now that we have checked to see if a username exists in the database, we need to check to see if the password matches
// we need to check to see if the password the user is inputting matches the hashed password which is saved in the database
// bcrypt.compareSync() checks to if they match
if(bcrypt.compareSync(req.body.password, checkUser.password)){
// password matches the hased password and sends back the information about the user
res.send(checkUser);
} else {
// We found a user with the username you are asking for, but the password doesn't match
res.send('invalid password');
}
} else {
// A user doesnt exist
// The front end user needs to register before logging in
res.send('invalid user');
}
});
})
// Listen to the port number
// This NEEDS to be at the end of your file, other wise you won't see any of the errors which come up
app.listen(port, () => {
// This will clear the console
console.clear();
console.log(`application is running on port ${port}`)
});