1
|
|
|
'use strict';
|
2
|
|
|
const config = require('./config/config');
|
|
|
|
|
3
|
|
|
const _ = require('lodash');
|
4
|
|
|
const app = require('express')();
|
5
|
|
|
const bodyParser = require('body-parser');
|
6
|
|
|
const cors = require('cors');
|
7
|
|
|
const favicon = require('serve-favicon');
|
8
|
|
|
|
9
|
|
|
|
10
|
|
|
const {ObjectID} = require('mongodb');
|
11
|
|
|
const {mongoose} = require('./db/mongoose');
|
12
|
|
|
const {Todo} = require('./models/todo');
|
13
|
|
|
const {User} = require('./models/user');
|
14
|
|
|
const {authenticate} = require('./middlewares/authenticate');
|
15
|
|
|
|
16
|
|
|
|
17
|
|
|
// the body-parser middleware
|
18
|
|
|
app.use(bodyParser.json());
|
19
|
|
|
//app.use(bodyParser.urlencoded({extended : false}));
|
20
|
|
|
|
21
|
|
|
app.use(cors());
|
22
|
|
|
app.use(function(req, res, next){
|
23
|
|
|
// Expose the custom headers so that browser can allow to use it
|
24
|
|
|
res.setHeader('Access-Control-Expose-Headers','X-Powered-By, X-Auth');
|
25
|
|
|
next();
|
26
|
|
|
});
|
27
|
|
|
|
28
|
|
|
// use the favicon
|
29
|
|
|
app.use(favicon(__dirname + '/_public/img/favicon.png'));
|
|
|
|
|
30
|
|
|
|
31
|
|
|
|
32
|
|
|
app.get('/', (req, res) => {
|
33
|
|
|
return res.sendFile(__dirname + '/_public/index.html');
|
|
|
|
|
34
|
|
|
});
|
35
|
|
|
|
36
|
|
|
// create a GET /todos route
|
37
|
|
|
app.get('/todos', authenticate, (req, res) => {
|
38
|
|
|
|
39
|
|
|
Todo.find({
|
40
|
|
|
_creator : req.user._id
|
41
|
|
|
}).then((data) => {
|
42
|
|
|
return res.status(200).json({data});
|
43
|
|
|
}, (err) => {
|
|
|
|
|
44
|
|
|
return res.status(500).json({
|
45
|
|
|
message : 'something broke'
|
46
|
|
|
});
|
47
|
|
|
});
|
48
|
|
|
});
|
49
|
|
|
|
50
|
|
|
// create a POST /todos route
|
51
|
|
|
app.post('/todos', authenticate, (req, res) => {
|
52
|
|
|
// log req body
|
53
|
|
|
//console.log('**Req Body => ', req.body);
|
54
|
|
|
// make a todo and save it into the database
|
55
|
|
|
let todo = new Todo({
|
56
|
|
|
text : req.body.text,
|
57
|
|
|
_creator : req.user._id
|
58
|
|
|
});
|
59
|
|
|
|
60
|
|
|
//console.log('**Todo =>', todo)
|
61
|
|
|
|
62
|
|
|
todo.save().then((data) => {
|
63
|
|
|
// send the todo as a response
|
64
|
|
|
return res.status(201).send(data);
|
65
|
|
|
}, (err) => {
|
66
|
|
|
console.log('Error : ', err._message);
|
|
|
|
|
67
|
|
|
// send the error as a response
|
68
|
|
|
return res.status(500).json({
|
69
|
|
|
message : 'something broke'
|
70
|
|
|
});
|
71
|
|
|
});
|
72
|
|
|
});
|
73
|
|
|
|
74
|
|
|
// get todos by id GET /todos/id
|
75
|
|
|
app.get('/todos/:id', authenticate, (req, res) => {
|
76
|
|
|
//get the todo id in todoID
|
77
|
|
|
let todoID = req.params.id;
|
78
|
|
|
|
79
|
|
|
// if the ID is valid not valid, send a message
|
80
|
|
|
if (!ObjectID.isValid(todoID)) {
|
81
|
|
|
//console.log('Invalid todo ID');
|
82
|
|
|
//console.log('Error : 422 : Invalid Todo ID');
|
83
|
|
|
return res.status(422).json({
|
84
|
|
|
message : 'invalid id'
|
85
|
|
|
});
|
86
|
|
|
}
|
87
|
|
|
// search for todo with the todo id and the creator
|
88
|
|
|
// do not displa todo if the creator id is different
|
89
|
|
|
Todo.findOne({
|
90
|
|
|
_id : todoID,
|
91
|
|
|
_creator : req.user._id
|
92
|
|
|
}).then((data) => {
|
93
|
|
|
if (!data) {
|
94
|
|
|
//console.log('Error : 404 : Todo ID Not Found');
|
95
|
|
|
return res.status(404).json({
|
96
|
|
|
message : 'todo not found'
|
97
|
|
|
});
|
98
|
|
|
}
|
99
|
|
|
|
100
|
|
|
return res.status(200).json({
|
101
|
|
|
todo : data
|
102
|
|
|
});
|
103
|
|
|
|
104
|
|
|
}).catch((err) => {
|
105
|
|
|
console.log(err);
|
|
|
|
|
106
|
|
|
//console.log('Error : 500 : Something broke');
|
107
|
|
|
return res.status(500).json({
|
108
|
|
|
message : 'todo not found'
|
109
|
|
|
});
|
110
|
|
|
//console.log('todoId not found');
|
111
|
|
|
});
|
|
|
|
|
112
|
|
|
});
|
113
|
|
|
|
114
|
|
|
// create the delete todo by id route
|
115
|
|
|
app.delete('/todos/:id', authenticate, (req, res) => {
|
116
|
|
|
let todoID = req.params.id;
|
117
|
|
|
|
118
|
|
|
if (!ObjectID.isValid(todoID)) {
|
119
|
|
|
return res.status(400).send({
|
120
|
|
|
message : 'InvalidID',
|
121
|
|
|
status : 400
|
122
|
|
|
});
|
123
|
|
|
}
|
124
|
|
|
|
125
|
|
|
Todo.findOneAndRemove({
|
126
|
|
|
_id : todoID,
|
127
|
|
|
_creator : req.user._id
|
128
|
|
|
}).then((data) => {
|
129
|
|
|
if(!data) {
|
130
|
|
|
return res.status(404).send({
|
131
|
|
|
message : 'Todo not found',
|
132
|
|
|
status : 404
|
133
|
|
|
});
|
134
|
|
|
}
|
135
|
|
|
|
136
|
|
|
res.status(200).send({
|
137
|
|
|
todo : data,
|
138
|
|
|
status : 200
|
139
|
|
|
});
|
|
|
|
|
140
|
|
|
}).catch((err)=> res.status(400).send({
|
|
|
|
|
141
|
|
|
message : 'Error',
|
142
|
|
|
status : 400
|
143
|
|
|
}));
|
|
|
|
|
144
|
|
|
});
|
145
|
|
|
|
146
|
|
|
app.patch('/todos/:id', authenticate, (req, res) => {
|
147
|
|
|
let todoID = req.params.id;
|
148
|
|
|
let body = _.pick(req.body, ['text', 'completed']);
|
149
|
|
|
|
150
|
|
|
if (!ObjectID.isValid(todoID)) {
|
151
|
|
|
console.log('id rejected by isValid()');
|
|
|
|
|
152
|
|
|
return res.status(400).send({
|
153
|
|
|
message : 'InvalidID',
|
154
|
|
|
status : 400
|
155
|
|
|
});
|
156
|
|
|
}
|
157
|
|
|
// check if the completed field is boolena or not
|
158
|
|
|
// and it's value is true
|
159
|
|
|
|
160
|
|
|
if(_.isBoolean(body.completed) && body.completed) {
|
161
|
|
|
// set the completed as true and the timestamp
|
162
|
|
|
body.completed = true;
|
163
|
|
|
body.completedAt = new Date().getTime();
|
164
|
|
|
} else {
|
165
|
|
|
body.completed = false;
|
166
|
|
|
body.completedAt = null;
|
167
|
|
|
}
|
168
|
|
|
|
169
|
|
|
// update the database
|
170
|
|
|
Todo.findOneAndUpdate({
|
171
|
|
|
_id : todoID,
|
172
|
|
|
_creator : req.user._id
|
173
|
|
|
}, { $set : body}, {new : true}).then((data) => {
|
174
|
|
|
if (!data) {
|
175
|
|
|
return res.status(404).send({
|
176
|
|
|
message : 'Todo not found',
|
177
|
|
|
status : 404
|
178
|
|
|
});
|
179
|
|
|
}
|
180
|
|
|
|
181
|
|
|
res.status(200).send({todo : data, status : 200});
|
|
|
|
|
182
|
|
|
|
183
|
|
|
}).catch((e) => {
|
|
|
|
|
184
|
|
|
res.status(400).send({
|
185
|
|
|
message : 'Failed to Update',
|
186
|
|
|
status : 400
|
187
|
|
|
});
|
188
|
|
|
});
|
|
|
|
|
189
|
|
|
});
|
190
|
|
|
|
191
|
|
|
// user routes here
|
192
|
|
|
// POST /users route
|
193
|
|
|
|
194
|
|
|
app.post('/users', (req, res) => {
|
195
|
|
|
// pick the email name and password using lodash pick method
|
196
|
|
|
let userData = _.pick(req.body, ['name', 'email', 'password']);
|
197
|
|
|
|
198
|
|
|
// create new instance of the User model
|
199
|
|
|
let user = new User(userData);
|
200
|
|
|
// save the user data inside the DB
|
201
|
|
|
user.save().then(() => {
|
202
|
|
|
///generate token
|
203
|
|
|
return user.generateAuthToken();
|
204
|
|
|
|
205
|
|
|
}).then((token) => {
|
206
|
|
|
return res.header('x-auth', token).status(201).json({user});
|
207
|
|
|
//console.log('User signup successful');
|
208
|
|
|
|
209
|
|
|
}).catch((err) => {
|
210
|
|
|
//console.log('error : ', err);
|
211
|
|
|
// send the error
|
212
|
|
|
res.status(400).send({
|
213
|
|
|
error : 'error occured'
|
214
|
|
|
});
|
215
|
|
|
return console.log(err._message);
|
|
|
|
|
216
|
|
|
});
|
217
|
|
|
});
|
218
|
|
|
|
219
|
|
|
// GET users/me route, using the token header
|
220
|
|
|
app.get('/users/me', authenticate, (req, res) => {
|
221
|
|
|
res.status(200).json({
|
222
|
|
|
user : req.user
|
223
|
|
|
});
|
224
|
|
|
return console.log(err);
|
|
|
|
|
225
|
|
|
});
|
226
|
|
|
|
227
|
|
|
// login route
|
228
|
|
|
|
229
|
|
|
app.post('/users/login', (req, res) => {
|
230
|
|
|
let userData = _.pick(req.body, ['email', 'password']);
|
231
|
|
|
// search for the user in using the email
|
232
|
|
|
User.findByCredentials(userData.email, userData.password).then((user) => {
|
233
|
|
|
return user.generateAuthToken().then((token) => {
|
234
|
|
|
return res.header('x-auth', token).status(200).json({user});
|
235
|
|
|
});
|
236
|
|
|
}).catch((err) => {
|
237
|
|
|
res.status(500).json({err});
|
238
|
|
|
return console.log(err);
|
|
|
|
|
239
|
|
|
});
|
240
|
|
|
});
|
241
|
|
|
|
242
|
|
|
//logout route
|
243
|
|
|
|
244
|
|
|
app.delete('/users/logout', authenticate, (req, res) => {
|
245
|
|
|
req.user.removeToken(req.token).then(() => {
|
246
|
|
|
return res.status(204).json({message : 'logout successsful'});
|
247
|
|
|
}, (err) => {
|
248
|
|
|
res.status(500).json({message : 'something broke'});
|
249
|
|
|
return console.log(err);
|
|
|
|
|
250
|
|
|
});
|
251
|
|
|
});
|
252
|
|
|
|
253
|
|
|
|
254
|
|
|
|
255
|
|
|
module.exports = {app};
|
256
|
|
|
|