jxp 2.11.0 → 2.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/libs/docs.js CHANGED
@@ -46,29 +46,32 @@ class Docs {
46
46
  }
47
47
  }
48
48
 
49
- metaModel(req, res) {
49
+ metaModel(req, res, next) {
50
50
  try {
51
51
  if (!req.Model) {
52
52
  return res.send(404, { status: "error", error: "Model not found" })
53
53
  }
54
54
  res.send(req.Model.schema.paths);
55
+ next();
55
56
  } catch (err) {
56
57
  console.error(err);
57
58
  return res.send(500, { status: "error", error: err, message: err.toString() });
58
59
  }
59
60
  }
60
61
 
61
- dbDiagram(req, res) {
62
+ dbDiagram(req, res, next) {
62
63
  try {
63
64
  res.send(this.models);
65
+ next();
64
66
  } catch(err) {
65
67
  res.send(500, { status: "error", error: err, message: err.toString() });
66
68
  }
67
69
  }
68
70
 
69
- frontPage(req, res) {
71
+ frontPage(req, res, next) {
70
72
  try {
71
73
  this.renderTemplate(res, "index", {});
74
+ next();
72
75
  } catch(err) {
73
76
  res.send(500, { status: "error", error: err, message: err.toString() });
74
77
  }
@@ -84,7 +87,7 @@ class Docs {
84
87
  }
85
88
  }
86
89
 
87
- model(req, res) {
90
+ model(req, res, next) {
88
91
  try {
89
92
  const model = this.models[req.params.modelname];
90
93
  console.dir(model.schema.opts);
@@ -92,6 +95,7 @@ class Docs {
92
95
  fields.sort();
93
96
  const perms = model.schema.opts.perms;
94
97
  this.renderTemplate(res, "model", { model, fields, perms });
98
+ next();
95
99
  } catch(err) {
96
100
  res.send(500, { status: "error", error: err, message: err.toString() });
97
101
  }
package/libs/jxp.js CHANGED
@@ -49,12 +49,13 @@ const middlewareCheckAdmin = (req, res, next) => {
49
49
  };
50
50
 
51
51
  // Outputs whatever is in res.result as JSON
52
- const outputJSON = (req, res) => {
52
+ const outputJSON = (req, res, next) => {
53
53
  res.send(res.result);
54
+ next();
54
55
  }
55
56
 
56
57
  // Outputs whatever is in res.result as CSV
57
- const outputCSV = (req, res) => {
58
+ const outputCSV = (req, res, next) => {
58
59
  const json2csv = require('json2csv').parse;
59
60
  const opts = { "flatten": true };
60
61
  if (!res.result.data) {
@@ -71,6 +72,7 @@ const outputCSV = (req, res) => {
71
72
  });
72
73
  const csv = json2csv(data, opts);
73
74
  res.end(csv);
75
+ next();
74
76
  } catch (err) {
75
77
  console.error(err);
76
78
  res.send(500, { status: "error", error: err, message: err.toString() });
@@ -78,16 +80,9 @@ const outputCSV = (req, res) => {
78
80
  }
79
81
 
80
82
  // Actions (verbs)
81
- const actionGet = async (req, res, next) => {
83
+ const actionGet = async (req, res) => {
82
84
  const opname = `get ${req.modelname} ${ops++}`;
83
85
  console.time(opname);
84
- try {
85
- if (res.user) {
86
- req.Model.__user = res.user;
87
- }
88
- } catch(err) {
89
- console.error(err);
90
- }
91
86
  const parseSearch = function(search) {
92
87
  let result = {};
93
88
  for (let i in search) {
@@ -122,6 +117,9 @@ const actionGet = async (req, res, next) => {
122
117
  countquery = Object.assign({ $text: { $search: req.query.search }}, countquery);
123
118
  qcount = req.Model.find({ $text: { $search: req.query.search }});
124
119
  }
120
+ if (res.user) {
121
+ q.options({ user: res.user });
122
+ }
125
123
  try {
126
124
  let count = await req.Model.estimatedDocumentCount();
127
125
  if (count < 100000 && Object.keys(countquery).length !== 0) {
@@ -184,7 +182,6 @@ const actionGet = async (req, res, next) => {
184
182
  result.data = await q.exec();
185
183
  res.result = result;
186
184
  if (debug) console.timeEnd(opname);
187
- next();
188
185
  } catch(err) {
189
186
  console.error(new Date(), err);
190
187
  if (debug) console.timeEnd(opname);
@@ -196,10 +193,7 @@ const actionGetOne = async (req, res) => {
196
193
  const opname = `getOne ${req.modelname}/${req.params.item_id} ${ops++}`;
197
194
  console.time(opname);
198
195
  try {
199
- if (res.user) {
200
- req.Model.__user = res.user;
201
- }
202
- const data = await getOne(req.Model, req.params.item_id, req.query);
196
+ const data = await getOne(req.Model, req.params.item_id, req.query, { user: res.user });
203
197
  res.send({ data });
204
198
  if (debug) console.timeEnd(opname);
205
199
  } catch(err) {
@@ -213,7 +207,7 @@ const actionGetOne = async (req, res) => {
213
207
  }
214
208
  };
215
209
 
216
- const actionPost = async (req, res, next) => {
210
+ const actionPost = async (req, res) => {
217
211
  const opname = `post ${req.modelname} ${ops++}`;
218
212
  console.time(opname);
219
213
  try {
@@ -236,7 +230,6 @@ const actionPost = async (req, res, next) => {
236
230
  data: item
237
231
  });
238
232
  if (debug) console.timeEnd(opname);
239
- next();
240
233
  } catch (err) {
241
234
  console.error(new Date(), err);
242
235
  if (debug) console.timeEnd(opname);
@@ -244,7 +237,7 @@ const actionPost = async (req, res, next) => {
244
237
  }
245
238
  };
246
239
 
247
- const actionPut = async (req, res, next) => {
240
+ const actionPut = async (req, res) => {
248
241
  const opname = `put ${req.modelname}/${req.params.item_id} ${ops++}`;
249
242
  console.time(opname);
250
243
  try {
@@ -273,7 +266,6 @@ const actionPut = async (req, res, next) => {
273
266
  data: data
274
267
  });
275
268
  if (debug) console.timeEnd(opname);
276
- next();
277
269
  } catch (err) {
278
270
  console.error(new Date(), err);
279
271
  if (debug) console.timeEnd(opname);
@@ -282,24 +274,10 @@ const actionPut = async (req, res, next) => {
282
274
  }
283
275
  };
284
276
 
285
- const actionUpdate = async (req, res, next) => {
277
+ const actionUpdate = async (req, res) => {
286
278
  const opname = `update ${req.modelname}/${req.params.item_id} ${ops++}`;
287
279
  console.time(opname);
288
280
  try {
289
- // let item = await req.Model.findById(req.params.item_id);
290
- // if (!item) {
291
- // console.error(new Date(), "Document not found");
292
- // res.send(404, { status: "error", message: "Document not found" });
293
- // return;
294
- // }
295
- // _populateItem(item, datamunging.deserialize(req.body));
296
- // _versionItem(item);
297
- // if (res.user) {
298
- // item.__user = res.user;
299
- // item._updated_by_id = res.user._id;
300
- // }
301
- // const data = await item.save();
302
- console.log({ body: req.body });
303
281
  let body_data = datamunging.deserialize(req.body);
304
282
  const data = await req.Model.update({ _id: req.params.item_id }, body_data);
305
283
  let silence = req.params._silence;
@@ -314,7 +292,6 @@ const actionUpdate = async (req, res, next) => {
314
292
  data
315
293
  });
316
294
  if (debug) console.timeEnd(opname);
317
- next();
318
295
  } catch (err) {
319
296
  console.error(new Date(), err);
320
297
  if (debug) console.timeEnd(opname);
@@ -323,7 +300,7 @@ const actionUpdate = async (req, res, next) => {
323
300
  }
324
301
  };
325
302
 
326
- const actionDelete = async (req, res, next) => {
303
+ const actionDelete = async (req, res) => {
327
304
  const permaDelete = req.query._permaDelete;
328
305
  const cascade = req.query._cascade;
329
306
  let silence = req.query._silence || (req.body && req.body._silence);
@@ -394,7 +371,6 @@ const actionDelete = async (req, res, next) => {
394
371
  message: `${req.modelname}/${ req.params.item_id } deleted`
395
372
  });
396
373
  if (debug) console.timeEnd(opname);
397
- next();
398
374
  } catch(err) {
399
375
  console.error(new Date(), err);
400
376
  if (debug) console.timeEnd(opname);
@@ -403,7 +379,7 @@ const actionDelete = async (req, res, next) => {
403
379
  }
404
380
  };
405
381
 
406
- const actionCount = async (req, res, next) => {
382
+ const actionCount = async (req, res) => {
407
383
  const opname = `count ${req.modelname} ${ops++}`;
408
384
  console.time(opname);
409
385
  const parseSearch = function(search) {
@@ -432,7 +408,6 @@ const actionCount = async (req, res, next) => {
432
408
  const count = await req.Model.countDocuments(filters).exec();
433
409
  res.result = { count };
434
410
  if (debug) console.timeEnd(opname);
435
- next();
436
411
  } catch(err) {
437
412
  console.error(new Date(), err);
438
413
  if (debug) console.timeEnd(opname);
@@ -453,29 +428,21 @@ const actionCall = async (req, res) => {
453
428
  }
454
429
  };
455
430
 
456
- const actionCallItem = (req, res) => {
457
- req.Model.findById(req.params.item_id, function(err, item) {
431
+ const actionCallItem = async (req, res) => {
432
+ try {
433
+ const item = req.Model.findById(req.params.item_id);
458
434
  if (!item) {
459
435
  res.send(404, "Document not found for " + req.params.method_name);
460
436
  return;
461
437
  }
462
- if (err) {
463
- console.trace(err);
464
- res.send(500, { status: "error", message: err.toString() });
465
- return;
466
- }
467
438
  req.params.__user = res.user || null;
468
- req.Model[req.params.method_name](item).then(
469
- function(item) {
470
- // console.log({ action_id: 7, action: "Method called", type: req.modelname, id: item._id, method: req.params.method_name, user: filterLogUser(res.user) });
471
- res.json(item);
472
- },
473
- function(err) {
474
- console.trace(err);
475
- res.send(500, { status: "error", message: err.toString() });
476
- }
477
- );
478
- });
439
+ const result = await req.Model[req.params.method_name](item);
440
+ res.json(result);
441
+
442
+ } catch(err) {
443
+ console.trace(err);
444
+ res.send(500, { status: "error", message: err.toString() });
445
+ }
479
446
  };
480
447
 
481
448
  // Actions (verbs)
@@ -583,7 +550,7 @@ const actionAggregate = async (req, res) => {
583
550
  };
584
551
 
585
552
  // Actions (verbs)
586
- const actionBulkWrite = async (req, res, next) => {
553
+ const actionBulkWrite = async (req, res) => {
587
554
  if (!req.body || !Array.isArray(req.body)) {
588
555
  console.error("query missing or not of type array")
589
556
  return res.send(500, { status: "error", message: "query missing or not of type array" });
@@ -598,7 +565,6 @@ const actionBulkWrite = async (req, res, next) => {
598
565
  res.result = result;
599
566
  if (debug) console.timeEnd(opname);
600
567
  res.json(result);
601
- next();
602
568
  } catch (err) {
603
569
  console.error(new Date(), err);
604
570
  if (debug) console.timeEnd(opname);
@@ -640,8 +606,8 @@ const actionBulkWrite = async (req, res, next) => {
640
606
 
641
607
  // Utitlities
642
608
 
643
- const getOne = async (Model, item_id, params) => {
644
- const query = Model.findById(item_id);
609
+ const getOne = async (Model, item_id, params, options) => {
610
+ const query = Model.findById(item_id, {}, options);
645
611
  if (params.populate) {
646
612
  if ((typeof params.populate === "object") && !Array.isArray(params.populate)) {
647
613
  for (let i in params.populate) {
@@ -838,8 +804,7 @@ const JXP = function(options) {
838
804
  }
839
805
  },
840
806
  post_hooks: {
841
- login: async (req, res, next) => {
842
- next();
807
+ login: async () => {
843
808
  },
844
809
  },
845
810
  cache_timeout: "5 minutes",
package/libs/login.js CHANGED
@@ -83,7 +83,7 @@ const oauth = (req, res, next) => { // Log in through an OAuth2 provider, define
83
83
  res.redirect(uri, next);
84
84
  }
85
85
 
86
- const oauth_callback = async (req, res, next) => {
86
+ const oauth_callback = async (req, res) => {
87
87
  const provider = req.params.provider;
88
88
  const provider_config = req.config.oauth[provider];
89
89
  const code = req.query.code;
@@ -126,19 +126,19 @@ const oauth_callback = async (req, res, next) => {
126
126
  var jwt_token = jwt.sign({ apikey: apikey.apikey, user: user }, req.config.shared_secret, {
127
127
  expiresIn: "1m"
128
128
  });
129
- res.redirect(`${req.config.oauth.success_uri}?token=${jwt_token}`, next);
129
+ res.redirect(`${req.config.oauth.success_uri}?token=${jwt_token}`);
130
130
  } catch (err) {
131
131
  console.error(err);
132
132
  if (typeof err === 'string' || err instanceof String) {
133
- res.redirect(`${req.config.oauth.fail_uri}?error=${err}&provider=${provider}`, next);
133
+ res.redirect(`${req.config.oauth.fail_uri}?error=${err}&provider=${provider}`);
134
134
  } else {
135
- res.redirect(`${req.config.oauth.fail_uri}?error=unknown&provider=${provider}`, next);
135
+ res.redirect(`${req.config.oauth.fail_uri}?error=unknown&provider=${provider}`);
136
136
  }
137
137
  return;
138
138
  }
139
139
  }
140
140
 
141
- const login = async (req, res, next) => {
141
+ const login = async (req, res) => {
142
142
  const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
143
143
  let email = req.params.email || req.body.email;
144
144
  let password = req.params.password || req.body.password;
@@ -170,7 +170,6 @@ const login = async (req, res, next) => {
170
170
  refresh_token_expires: security.tokenExpires(refreshtoken),
171
171
  provider: token.provider,
172
172
  });
173
- next();
174
173
  } catch (err) {
175
174
  res.send(401, { status: "fail", message: "Authentication failed", err });
176
175
  console.error(new Date(), `Authentication failed`, ip, err);
@@ -178,7 +177,7 @@ const login = async (req, res, next) => {
178
177
  }
179
178
  }
180
179
 
181
- const getJWT = (req, res) => {
180
+ const getJWT = async (req, res) => {
182
181
  var user = null;
183
182
  if (!res.user.admin) {
184
183
  res.send(403, { status: "fail", message: "Unauthorized" });
@@ -189,27 +188,26 @@ const getJWT = (req, res) => {
189
188
  res.send(400, { status: "fail", message: "Email required" });
190
189
  return;
191
190
  }
192
- User.findOne({ email: email }, function (err, result) {
193
- if (err) {
194
- res.send(500, { status: "error", error: err });
195
- return;
196
- }
191
+ try {
192
+ const result = await User.findOne({ email: email });
197
193
  if (!result || !result._id) {
198
194
  res.send(404, { status: "fail", message: "User not found" });
199
195
  return;
200
196
  }
201
197
  user = result;
202
- security.generateApiKey(user._id)
203
- .then(function (result) {
204
- var token = jwt.sign({ apikey: result.apikey, email: user.email, id: user._id }, req.config.shared_secret, {
205
- expiresIn: "2d"
206
- });
207
- res.send({ email: user.email, token: token });
208
- }, function () {
209
- res.send(403, { status: "fail", message: "Unauthorized" });
198
+ try {
199
+ const apikey = await security.generateApiKey(user._id)
200
+ var token = jwt.sign({ apikey: apikey.apikey, email: user.email, id: user._id }, req.config.shared_secret, {
201
+ expiresIn: "2d"
210
202
  });
211
- });
212
- return;
203
+ res.send({ email: user.email, token: token });
204
+ } catch (err) {
205
+ res.send(403, { status: "fail", message: "Unauthorized" });
206
+ return;
207
+ }
208
+ } catch (err) {
209
+ res.send(500, { status: "error", error: err });
210
+ }
213
211
  }
214
212
 
215
213
  const Login = {
package/libs/security.js CHANGED
@@ -204,7 +204,7 @@ const revokeRefreshToken = async user_id => {
204
204
  return true;
205
205
  }
206
206
 
207
- const refresh = async (req, res, next) => {
207
+ const refresh = async (req, res) => {
208
208
  try {
209
209
  if(req.headers.authorization && req.headers.authorization.trim().toLowerCase().indexOf("bearer") === 0) {
210
210
  const refresh_token = await RefreshToken.findOne({ refresh_token: bearerAuthData(req) }).exec();
@@ -221,27 +221,24 @@ const refresh = async (req, res, next) => {
221
221
  refresh_token: new_refresh_token.refresh_token,
222
222
  refresh_token_expires: tokenExpires(new_refresh_token)
223
223
  });
224
- next();
225
224
  } else {
226
225
  throw("Missing refresh token")
227
226
  }
228
- next();
229
227
  } catch (err) {
230
228
  console.error(err);
231
229
  return fail(res, 403, err);
232
230
  }
233
231
  }
234
232
 
235
- const login = async (req, res, next) => {
233
+ const login = async (req, res) => {
236
234
  try {
237
235
  const authenticate_result = await authenticate(req);
238
236
  if (!authenticate_result) {
239
237
  res.user = null;
240
238
  res.groups = [];
241
- return next();
239
+ return;
242
240
  }
243
241
  res = Object.assign(res, authenticate_result);
244
- next();
245
242
  } catch(err) {
246
243
  console.error(err);
247
244
  return fail(res, 403, err);
@@ -282,7 +279,7 @@ const authenticate = async req => {
282
279
  }
283
280
  }
284
281
 
285
- const auth = async (req, res, next) => {
282
+ const auth = async (req, res) => {
286
283
  // Check against model as to whether we're allowed to edit this model
287
284
  if (!req.Model) {
288
285
  console.error("Model missing");
@@ -304,7 +301,6 @@ const auth = async (req, res, next) => {
304
301
  return fail(res, 500, "Unsupported operation: " + req.method);
305
302
  }
306
303
  await check_perms(res.user, res.groups, req.Model, method, req.params.item_id);
307
- next();
308
304
  } catch(err) {
309
305
  console.error(err);
310
306
  return fail(res, 403, { status: "Unauthorized", error: err });
@@ -312,13 +308,12 @@ const auth = async (req, res, next) => {
312
308
  };
313
309
 
314
310
  // Bulk auth requires all CRUD permissions
315
- const bulkAuth = async (req, res, next) => {
311
+ const bulkAuth = async (req, res,) => {
316
312
  try {
317
313
  await check_perms(res.user, res.groups, req.Model, "c");
318
314
  await check_perms(res.user, res.groups, req.Model, "r");
319
315
  await check_perms(res.user, res.groups, req.Model, "u");
320
316
  await check_perms(res.user, res.groups, req.Model, "d");
321
- next();
322
317
  } catch (err) {
323
318
  console.error(err);
324
319
  return fail(res, 403, { status: "Unauthorized", error: err });
package/libs/setup.js CHANGED
@@ -9,14 +9,12 @@ const init = config => {
9
9
  User = require(path.join(config.model_dir, "user_model"));
10
10
  }
11
11
 
12
- const checkUserDoesNotExist = async (req, res, next) => {
12
+ const checkUserDoesNotExist = async (req, res) => {
13
13
  try {
14
14
  const count = await User.countDocuments();
15
15
  if (count) {
16
- const users = await User.find();
17
16
  return res.send(403, { status: "failed", error: "Cannot setup if user exists" });
18
17
  }
19
- return next();
20
18
  } catch(err) {
21
19
  console.error(err);
22
20
  res.send(500, { status: "error", error: err.message });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jxp",
3
3
  "description:": "An opinionated RESTful API library based on Mongoose and Restify. Make an API by just writing Mongoose models.",
4
- "version": "2.11.0",
4
+ "version": "2.11.2",
5
5
  "private": false,
6
6
  "main": "libs/jxp.js",
7
7
  "scripts": {
@@ -59,6 +59,7 @@
59
59
  "chai": "^4.3.7",
60
60
  "chai-http": "^4.3.0",
61
61
  "mocha": "^10.1.0",
62
- "should": "^13.2.3"
62
+ "should": "^13.2.3",
63
+ "moment": "^2.29.4"
63
64
  }
64
65
  }