jxp 2.10.1 → 2.11.1
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 +8 -4
- package/libs/jxp.js +32 -50
- package/libs/login.js +20 -22
- package/libs/security.js +5 -10
- package/libs/setup.js +1 -3
- package/package.json +19 -18
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,9 +80,16 @@ const outputCSV = (req, res) => {
|
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
// Actions (verbs)
|
|
81
|
-
const actionGet = async (req, res
|
|
83
|
+
const actionGet = async (req, res) => {
|
|
82
84
|
const opname = `get ${req.modelname} ${ops++}`;
|
|
83
85
|
console.time(opname);
|
|
86
|
+
try {
|
|
87
|
+
if (res.user) {
|
|
88
|
+
req.Model.__user = res.user;
|
|
89
|
+
}
|
|
90
|
+
} catch(err) {
|
|
91
|
+
console.error(err);
|
|
92
|
+
}
|
|
84
93
|
const parseSearch = function(search) {
|
|
85
94
|
let result = {};
|
|
86
95
|
for (let i in search) {
|
|
@@ -177,7 +186,6 @@ const actionGet = async (req, res, next) => {
|
|
|
177
186
|
result.data = await q.exec();
|
|
178
187
|
res.result = result;
|
|
179
188
|
if (debug) console.timeEnd(opname);
|
|
180
|
-
next();
|
|
181
189
|
} catch(err) {
|
|
182
190
|
console.error(new Date(), err);
|
|
183
191
|
if (debug) console.timeEnd(opname);
|
|
@@ -189,6 +197,9 @@ const actionGetOne = async (req, res) => {
|
|
|
189
197
|
const opname = `getOne ${req.modelname}/${req.params.item_id} ${ops++}`;
|
|
190
198
|
console.time(opname);
|
|
191
199
|
try {
|
|
200
|
+
if (res.user) {
|
|
201
|
+
req.Model.__user = res.user;
|
|
202
|
+
}
|
|
192
203
|
const data = await getOne(req.Model, req.params.item_id, req.query);
|
|
193
204
|
res.send({ data });
|
|
194
205
|
if (debug) console.timeEnd(opname);
|
|
@@ -203,7 +214,7 @@ const actionGetOne = async (req, res) => {
|
|
|
203
214
|
}
|
|
204
215
|
};
|
|
205
216
|
|
|
206
|
-
const actionPost = async (req, res
|
|
217
|
+
const actionPost = async (req, res) => {
|
|
207
218
|
const opname = `post ${req.modelname} ${ops++}`;
|
|
208
219
|
console.time(opname);
|
|
209
220
|
try {
|
|
@@ -226,7 +237,6 @@ const actionPost = async (req, res, next) => {
|
|
|
226
237
|
data: item
|
|
227
238
|
});
|
|
228
239
|
if (debug) console.timeEnd(opname);
|
|
229
|
-
next();
|
|
230
240
|
} catch (err) {
|
|
231
241
|
console.error(new Date(), err);
|
|
232
242
|
if (debug) console.timeEnd(opname);
|
|
@@ -234,7 +244,7 @@ const actionPost = async (req, res, next) => {
|
|
|
234
244
|
}
|
|
235
245
|
};
|
|
236
246
|
|
|
237
|
-
const actionPut = async (req, res
|
|
247
|
+
const actionPut = async (req, res) => {
|
|
238
248
|
const opname = `put ${req.modelname}/${req.params.item_id} ${ops++}`;
|
|
239
249
|
console.time(opname);
|
|
240
250
|
try {
|
|
@@ -263,7 +273,6 @@ const actionPut = async (req, res, next) => {
|
|
|
263
273
|
data: data
|
|
264
274
|
});
|
|
265
275
|
if (debug) console.timeEnd(opname);
|
|
266
|
-
next();
|
|
267
276
|
} catch (err) {
|
|
268
277
|
console.error(new Date(), err);
|
|
269
278
|
if (debug) console.timeEnd(opname);
|
|
@@ -272,24 +281,10 @@ const actionPut = async (req, res, next) => {
|
|
|
272
281
|
}
|
|
273
282
|
};
|
|
274
283
|
|
|
275
|
-
const actionUpdate = async (req, res
|
|
284
|
+
const actionUpdate = async (req, res) => {
|
|
276
285
|
const opname = `update ${req.modelname}/${req.params.item_id} ${ops++}`;
|
|
277
286
|
console.time(opname);
|
|
278
287
|
try {
|
|
279
|
-
// let item = await req.Model.findById(req.params.item_id);
|
|
280
|
-
// if (!item) {
|
|
281
|
-
// console.error(new Date(), "Document not found");
|
|
282
|
-
// res.send(404, { status: "error", message: "Document not found" });
|
|
283
|
-
// return;
|
|
284
|
-
// }
|
|
285
|
-
// _populateItem(item, datamunging.deserialize(req.body));
|
|
286
|
-
// _versionItem(item);
|
|
287
|
-
// if (res.user) {
|
|
288
|
-
// item.__user = res.user;
|
|
289
|
-
// item._updated_by_id = res.user._id;
|
|
290
|
-
// }
|
|
291
|
-
// const data = await item.save();
|
|
292
|
-
console.log({ body: req.body });
|
|
293
288
|
let body_data = datamunging.deserialize(req.body);
|
|
294
289
|
const data = await req.Model.update({ _id: req.params.item_id }, body_data);
|
|
295
290
|
let silence = req.params._silence;
|
|
@@ -304,7 +299,6 @@ const actionUpdate = async (req, res, next) => {
|
|
|
304
299
|
data
|
|
305
300
|
});
|
|
306
301
|
if (debug) console.timeEnd(opname);
|
|
307
|
-
next();
|
|
308
302
|
} catch (err) {
|
|
309
303
|
console.error(new Date(), err);
|
|
310
304
|
if (debug) console.timeEnd(opname);
|
|
@@ -313,7 +307,7 @@ const actionUpdate = async (req, res, next) => {
|
|
|
313
307
|
}
|
|
314
308
|
};
|
|
315
309
|
|
|
316
|
-
const actionDelete = async (req, res
|
|
310
|
+
const actionDelete = async (req, res) => {
|
|
317
311
|
const permaDelete = req.query._permaDelete;
|
|
318
312
|
const cascade = req.query._cascade;
|
|
319
313
|
let silence = req.query._silence || (req.body && req.body._silence);
|
|
@@ -384,7 +378,6 @@ const actionDelete = async (req, res, next) => {
|
|
|
384
378
|
message: `${req.modelname}/${ req.params.item_id } deleted`
|
|
385
379
|
});
|
|
386
380
|
if (debug) console.timeEnd(opname);
|
|
387
|
-
next();
|
|
388
381
|
} catch(err) {
|
|
389
382
|
console.error(new Date(), err);
|
|
390
383
|
if (debug) console.timeEnd(opname);
|
|
@@ -393,7 +386,7 @@ const actionDelete = async (req, res, next) => {
|
|
|
393
386
|
}
|
|
394
387
|
};
|
|
395
388
|
|
|
396
|
-
const actionCount = async (req, res
|
|
389
|
+
const actionCount = async (req, res) => {
|
|
397
390
|
const opname = `count ${req.modelname} ${ops++}`;
|
|
398
391
|
console.time(opname);
|
|
399
392
|
const parseSearch = function(search) {
|
|
@@ -422,7 +415,6 @@ const actionCount = async (req, res, next) => {
|
|
|
422
415
|
const count = await req.Model.countDocuments(filters).exec();
|
|
423
416
|
res.result = { count };
|
|
424
417
|
if (debug) console.timeEnd(opname);
|
|
425
|
-
next();
|
|
426
418
|
} catch(err) {
|
|
427
419
|
console.error(new Date(), err);
|
|
428
420
|
if (debug) console.timeEnd(opname);
|
|
@@ -443,29 +435,21 @@ const actionCall = async (req, res) => {
|
|
|
443
435
|
}
|
|
444
436
|
};
|
|
445
437
|
|
|
446
|
-
const actionCallItem = (req, res) => {
|
|
447
|
-
|
|
438
|
+
const actionCallItem = async (req, res) => {
|
|
439
|
+
try {
|
|
440
|
+
const item = req.Model.findById(req.params.item_id);
|
|
448
441
|
if (!item) {
|
|
449
442
|
res.send(404, "Document not found for " + req.params.method_name);
|
|
450
443
|
return;
|
|
451
444
|
}
|
|
452
|
-
if (err) {
|
|
453
|
-
console.trace(err);
|
|
454
|
-
res.send(500, { status: "error", message: err.toString() });
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
445
|
req.params.__user = res.user || null;
|
|
458
|
-
req.Model[req.params.method_name](item)
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
res.send(500, { status: "error", message: err.toString() });
|
|
466
|
-
}
|
|
467
|
-
);
|
|
468
|
-
});
|
|
446
|
+
const result = await req.Model[req.params.method_name](item);
|
|
447
|
+
res.json(result);
|
|
448
|
+
|
|
449
|
+
} catch(err) {
|
|
450
|
+
console.trace(err);
|
|
451
|
+
res.send(500, { status: "error", message: err.toString() });
|
|
452
|
+
}
|
|
469
453
|
};
|
|
470
454
|
|
|
471
455
|
// Actions (verbs)
|
|
@@ -573,7 +557,7 @@ const actionAggregate = async (req, res) => {
|
|
|
573
557
|
};
|
|
574
558
|
|
|
575
559
|
// Actions (verbs)
|
|
576
|
-
const actionBulkWrite = async (req, res
|
|
560
|
+
const actionBulkWrite = async (req, res) => {
|
|
577
561
|
if (!req.body || !Array.isArray(req.body)) {
|
|
578
562
|
console.error("query missing or not of type array")
|
|
579
563
|
return res.send(500, { status: "error", message: "query missing or not of type array" });
|
|
@@ -588,7 +572,6 @@ const actionBulkWrite = async (req, res, next) => {
|
|
|
588
572
|
res.result = result;
|
|
589
573
|
if (debug) console.timeEnd(opname);
|
|
590
574
|
res.json(result);
|
|
591
|
-
next();
|
|
592
575
|
} catch (err) {
|
|
593
576
|
console.error(new Date(), err);
|
|
594
577
|
if (debug) console.timeEnd(opname);
|
|
@@ -828,8 +811,7 @@ const JXP = function(options) {
|
|
|
828
811
|
}
|
|
829
812
|
},
|
|
830
813
|
post_hooks: {
|
|
831
|
-
login: async (
|
|
832
|
-
next();
|
|
814
|
+
login: async () => {
|
|
833
815
|
},
|
|
834
816
|
},
|
|
835
817
|
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
|
|
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}
|
|
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}
|
|
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}
|
|
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
|
|
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
|
-
|
|
193
|
-
|
|
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
|
-
|
|
203
|
-
.
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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.
|
|
4
|
+
"version": "2.11.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "libs/jxp.js",
|
|
7
7
|
"scripts": {
|
|
@@ -27,38 +27,39 @@
|
|
|
27
27
|
"url": "https://github.com/j-norwood-young/jexpress-2/issues"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"axios": "^
|
|
30
|
+
"axios": "^1.2.0",
|
|
31
31
|
"bcryptjs": "^2.4.3",
|
|
32
|
-
"commander": "^
|
|
33
|
-
"config": "^3.3.
|
|
34
|
-
"dotenv": "^
|
|
35
|
-
"glob": "
|
|
32
|
+
"commander": "^9.4.1",
|
|
33
|
+
"config": "^3.3.8",
|
|
34
|
+
"dotenv": "^16.0.3",
|
|
35
|
+
"glob": "8.0.3",
|
|
36
36
|
"js-yaml": "4.1.0",
|
|
37
|
-
"json2csv": "^5.0.
|
|
37
|
+
"json2csv": "^5.0.7",
|
|
38
38
|
"jsonwebtoken": "^8.5.1",
|
|
39
|
-
"jstransformer-markdown-it": "^
|
|
40
|
-
"jxp-helper": "^1.
|
|
39
|
+
"jstransformer-markdown-it": "^3.0.0",
|
|
40
|
+
"jxp-helper": "^1.4.0",
|
|
41
41
|
"mkdirp": "^1.0.4",
|
|
42
|
-
"mongoose": "6.
|
|
42
|
+
"mongoose": "6.7.3",
|
|
43
43
|
"mongoose-friendly": "^0.1.4",
|
|
44
44
|
"morgan": "^1.10.0",
|
|
45
|
-
"nodemailer": "^6.
|
|
45
|
+
"nodemailer": "^6.8.0",
|
|
46
46
|
"nodemailer-smtp-transport": "^2.7.4",
|
|
47
47
|
"path": "^0.12.7",
|
|
48
48
|
"pug": "^3.0.2",
|
|
49
49
|
"querystring": "^0.2.1",
|
|
50
50
|
"rand-token": "^1.0.1",
|
|
51
51
|
"readline-sync": "^1.4.10",
|
|
52
|
-
"restify": "^
|
|
52
|
+
"restify": "^9.0.0",
|
|
53
53
|
"restify-cors-middleware": "^1.1.1",
|
|
54
|
-
"traverse": "^0.6.
|
|
55
|
-
"underscore": "^1.13.
|
|
56
|
-
"ws": "^8.
|
|
54
|
+
"traverse": "^0.6.7",
|
|
55
|
+
"underscore": "^1.13.6",
|
|
56
|
+
"ws": "^8.11.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"chai": "^4.3.
|
|
59
|
+
"chai": "^4.3.7",
|
|
60
60
|
"chai-http": "^4.3.0",
|
|
61
|
-
"mocha": "^
|
|
62
|
-
"should": "^13.2.3"
|
|
61
|
+
"mocha": "^10.1.0",
|
|
62
|
+
"should": "^13.2.3",
|
|
63
|
+
"moment": "^2.29.4"
|
|
63
64
|
}
|
|
64
65
|
}
|