@@ -11,12 +11,14 @@ const router = express.Router()
11
11
dotenv . config ( { path : '../../.env' } ) // for environ variables
12
12
13
13
// @route GET /api/problems/
14
- // @desc Get all problems
14
+ // @desc Get all problems, or problems within an ID range
15
15
// @access Public
16
16
router . get ( '/' , async ( req , res ) => {
17
17
try {
18
- start = null
19
- end = null
18
+ // Set defaults for range from 0 to max int
19
+ let start = 0
20
+ let end = Number . MAX_SAFE_INTEGER
21
+ // Adjust range if range was provided
20
22
if ( req . query . start ) {
21
23
start = req . query . start
22
24
}
@@ -25,23 +27,9 @@ router.get('/', async (req, res) => {
25
27
}
26
28
// NOTE: We're finding based on id, NOT _id! _id is the DB id, whereas id is the leetcode
27
29
// problem ID!
28
- let problems = null
29
- // TODO: Figure out if there's a way to pass null into gte/lte w/o causing problems
30
- // such that this logic can be condensed to a single query again
31
- if ( start && end ) {
32
- problems = await Problem . find ( ) . where ( 'id' ) . gte ( start ) . lte ( end )
33
- }
34
- else if ( start ) {
35
- problems = await Problem . find ( ) . where ( 'id' ) . gte ( start )
36
- }
37
- else if ( end ) {
38
- problems = await Problem . find ( ) . where ( 'id' ) . lte ( end )
39
- }
40
- else {
41
- problems = await Problem . find ( )
42
- }
30
+ const problems = await Problem . find ( ) . where ( 'id' ) . gte ( start ) . lte ( end )
43
31
44
- if ( ! problems ) {
32
+ if ( ! problems || problems . length === 0 ) {
45
33
return res . status ( 404 ) . json ( { errors : [ { msg : 'No problems found.' } ] } )
46
34
}
47
35
@@ -63,29 +51,35 @@ router.get('/name/:search', async (req, res) => {
63
51
// TODO: Figure out how/if RegExp objects can be used in mongo searchs
64
52
// re = RegExp('\\b(' + req.params.search + ')\\b', 'i')
65
53
66
- // If we don't pass a search term, don't try to match, just return
67
- if ( ! req . params . search ) {
68
- return res . json ( { } )
54
+ // If we don't pass a search term, don't try to match, just return err
55
+ if ( ! req . params . search || req . params . search === '' ) {
56
+ return res . status ( 404 ) . json ( { errors : [ { msg : 'No problems found.' } ] } )
69
57
}
70
58
const problems = await Problem . find ( { $or :
71
59
[
72
60
{ name : { $regex : req . params . search , $options : 'i' } } ,
73
61
{ problem_text : { $regex : req . params . search , $options : 'i' } } ,
74
62
] }
75
63
) . sort ( { id : 1 } )
64
+
65
+
66
+ if ( ! problems || problems . length === 0 ) {
67
+ return res . status ( 404 ) . json ( { errors : [ { msg : 'No problems found.' } ] } )
68
+ }
69
+
76
70
return res . json ( { problems} )
77
71
} catch ( error ) {
78
72
console . error ( 'Error when getting problems via search ' + error . message )
79
73
return res . status ( 500 ) . json ( { errors : [ { msg : 'Server error.' } ] } )
80
74
}
81
75
} )
82
76
83
- // @route GET /api/problems/:id
77
+ // @route GET /api/problems/id/ :id
84
78
// @desc Get a problem by id
85
79
// @access Public
86
80
router . get ( '/id/:id' , async ( req , res ) => {
87
81
try {
88
- if ( req . params . id === 'undefined' ) {
82
+ if ( ! req . params . id || isNaN ( parseInt ( req . params . id ) ) ) {
89
83
return res . json ( { } )
90
84
}
91
85
// Try to get the problem by ID
@@ -94,10 +88,10 @@ router.get('/id/:id', async (req, res) => {
94
88
// Check that the problem actually exists
95
89
if ( ! problem ) {
96
90
// Doesn't exist, return bad request
97
- return res . status ( 404 ) . json ( { msg : 'Problem not found.' } )
91
+ return res . status ( 404 ) . json ( { errors : [ { msg : 'Problem not found.' } ] } )
98
92
}
99
93
100
- return res . json ( { problem} )
94
+ return res . json ( problem )
101
95
} catch ( error ) {
102
96
console . error ( 'Get problem by id err: ' + error . message )
103
97
return res . status ( 500 ) . json ( { errors : [ { msg : 'Server error.' } ] } )
@@ -113,13 +107,13 @@ router.post('/', [auth, [
113
107
check ( 'id' , 'Problem must have valid id.' ) . not ( ) . isEmpty ( ) ,
114
108
check ( 'name' , 'Problem must have a name' ) . not ( ) . isEmpty ( ) ,
115
109
check ( 'problem_text' , 'Problem must have accompanying text' ) . not ( ) . isEmpty ( ) ,
116
- check ( 'link' , 'Must include link to problem' ) . not ( ) . isEmpty ( ) ,
110
+ check ( 'link' , 'Problem must include link to problem' ) . not ( ) . isEmpty ( ) ,
117
111
check ( 'difficulty' , 'Problem must have a difficulty level' ) . isNumeric ( ) ,
118
112
check ( 'is_premium' , 'Problem must be marked premium or not' ) . isBoolean ( ) ,
119
113
] ] , async ( req , res ) => {
120
114
// Check our request contains required fields
121
115
const validationErrors = validationResult ( req )
122
- if ( ! validationErrors . isEmpty ) {
116
+ if ( ! validationErrors . isEmpty ( ) ) {
123
117
// Something was missing, send an error
124
118
return res . status ( 400 ) . json ( { errors : validationErrors . array ( ) } )
125
119
}
@@ -130,7 +124,7 @@ router.post('/', [auth, [
130
124
const user = await User . findById ( req . user . id )
131
125
const admin_email = process . env . ADMIN_EMAIL
132
126
if ( ! user || user . email != admin_email ) {
133
- return res . status ( 401 ) . json ( { msg : 'Access denied' } )
127
+ return res . status ( 401 ) . json ( { errors : [ { msg : 'Access denied' } ] } )
134
128
}
135
129
136
130
// Valid admin - create the problem and post it.
@@ -176,16 +170,16 @@ router.post('/', [auth, [
176
170
// @access Admin
177
171
router . post ( '/bulk' , [ auth , [
178
172
check ( 'problems' , 'Must submit array of problems.' ) . isArray ( ) ,
179
- check ( 'problems.*.id' , 'Problem must have valid id.' ) . not ( ) . isEmpty ( ) ,
180
- check ( 'problems.*.name' , 'Problem must have a name' ) . not ( ) . isEmpty ( ) ,
181
- check ( 'problems.*.problem_text' , 'Problem must have accompanying text' ) . not ( ) . isEmpty ( ) ,
182
- check ( 'problems.*.link' , 'Must include link to problem' ) . not ( ) . isEmpty ( ) ,
183
- check ( 'problems.*.difficulty' , 'Problem must have a difficulty level' ) . isNumeric ( ) ,
184
- check ( 'problems.*.is_premium' , 'Problem must be marked premium or not' ) . isBoolean ( ) ,
173
+ check ( 'problems.*.id' , 'Problem(s) must have valid id.' ) . not ( ) . isEmpty ( ) ,
174
+ check ( 'problems.*.name' , 'Problem(s) must have a name' ) . not ( ) . isEmpty ( ) ,
175
+ check ( 'problems.*.problem_text' , 'Problem(s) must have accompanying text' ) . not ( ) . isEmpty ( ) ,
176
+ check ( 'problems.*.link' , 'Problems(s) must include link to problem' ) . not ( ) . isEmpty ( ) ,
177
+ check ( 'problems.*.difficulty' , 'Problem(s) must have a difficulty level' ) . isNumeric ( ) ,
178
+ check ( 'problems.*.is_premium' , 'Problem(s) must be marked premium or not' ) . isBoolean ( ) ,
185
179
] ] , async ( req , res ) => {
186
180
// Check our request contains required fields
187
181
const validationErrors = validationResult ( req )
188
- if ( ! validationErrors . isEmpty ) {
182
+ if ( ! validationErrors . isEmpty ( ) ) {
189
183
// Something was missing, send an error
190
184
return res . status ( 400 ) . json ( { errors : validationErrors . array ( ) } )
191
185
}
@@ -196,7 +190,7 @@ router.post('/bulk', [auth, [
196
190
const user = await User . findById ( req . user . id )
197
191
const admin_email = process . env . ADMIN_EMAIL
198
192
if ( ! user || user . email != admin_email ) {
199
- return res . status ( 401 ) . json ( { msg : 'Access denied' } )
193
+ return res . status ( 401 ) . json ( { errors : [ { msg : 'Access denied' } ] } )
200
194
}
201
195
202
196
const {
@@ -249,7 +243,7 @@ router.post('/bulk', [auth, [
249
243
}
250
244
}
251
245
// Return the results of which problems we could add and which we couldn't
252
- return res . json ( { 'NotAdded' : notAdded , 'Added: ' : added } )
246
+ return res . json ( { 'NotAdded' : notAdded , 'Added' : added } )
253
247
} catch ( error ) {
254
248
console . error ( 'Error when posting new LC problems ' + error . message )
255
249
return res . status ( 500 ) . json ( { errors : [ { msg : 'Server error.' } ] } )
@@ -268,7 +262,7 @@ router.put('/bulk', [
268
262
check ( 'problems.*' , 'All problem IDs must be a valid MongoID' ) . isMongoId ( ) ,
269
263
] , async ( req , res ) => {
270
264
const validationErrors = validationResult ( req )
271
- if ( ! validationErrors . isEmpty ) {
265
+ if ( ! validationErrors . isEmpty ( ) ) {
272
266
// Something was missing, send an error
273
267
return res . status ( 400 ) . json ( { errors : validationErrors . array ( ) } )
274
268
}
@@ -279,9 +273,9 @@ router.put('/bulk', [
279
273
const problems = await Problem . find ( { '_id' : { $in : object_ids } } )
280
274
281
275
// Check that the problems actually exist
282
- if ( ! problems ) {
276
+ if ( ! problems || problems . length === 0 ) {
283
277
// Doesn't exist, return bad request
284
- return res . status ( 404 ) . json ( { msg : 'Problems not found.' } )
278
+ return res . status ( 404 ) . json ( { errors : [ { msg : 'Problems not found.' } ] } )
285
279
}
286
280
return res . json ( { problems} )
287
281
} catch ( error ) {
@@ -298,7 +292,7 @@ router.put('/', [auth, [
298
292
] ] , async ( req , res ) => {
299
293
// Check our request contains required fields
300
294
const validationErrors = validationResult ( req )
301
- if ( ! validationErrors . isEmpty ) {
295
+ if ( ! validationErrors . isEmpty ( ) ) {
302
296
// Something was missing, send an error
303
297
return res . status ( 400 ) . json ( { errors : validationErrors . array ( ) } )
304
298
}
@@ -309,7 +303,7 @@ router.put('/', [auth, [
309
303
const user = await User . findById ( req . user . id )
310
304
const admin_email = process . env . ADMIN_EMAIL
311
305
if ( ! user || user . email != admin_email ) {
312
- return res . status ( 401 ) . json ( { msg : 'Access denied' } )
306
+ return res . status ( 401 ) . json ( { errors : [ { msg : 'Access denied' } ] } )
313
307
}
314
308
315
309
// Valid admin - parse out the updated fields
@@ -347,4 +341,28 @@ router.put('/', [auth, [
347
341
}
348
342
} )
349
343
344
+
345
+ // @route DELETE api/problems/:id
346
+ // @desc Delete problem by LeetCode ID
347
+ // @access Admin
348
+ router . delete ( '/:id' , [ auth ] ,
349
+ async ( req , res ) => {
350
+ try {
351
+ // Get the User by the passed auth ID
352
+ const user = await User . findById ( req . user . id ) . select ( [ '-password' , '-__v' ] )
353
+ // Ensure we could find them and that they're admin
354
+ const admin_email = process . env . ADMIN_EMAIL
355
+ if ( ! user || user . email != admin_email ) {
356
+ return res . status ( 401 ) . json ( { errors : [ { msg : 'Access denied' } ] } )
357
+ }
358
+ // Delete the problem
359
+ await Problem . deleteOne ( { id : req . params . id } )
360
+ // Return true as JSON
361
+ return res . json ( true )
362
+ } catch ( error ) {
363
+ console . log ( 'Error when deleting problem by LC id ' + error . message )
364
+ return res . status ( 500 ) . json ( { errors : [ { msg : 'Server error.' } ] } )
365
+ }
366
+ } )
367
+
350
368
module . exports = router
0 commit comments