mongoose 7.8.2 → 7.8.4

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.
@@ -250,7 +250,7 @@ function numDocs(v) {
250
250
 
251
251
  function valueFilter(val, assignmentOpts, populateOptions, allIds) {
252
252
  const userSpecifiedTransform = typeof populateOptions.transform === 'function';
253
- const transform = userSpecifiedTransform ? populateOptions.transform : noop;
253
+ const transform = userSpecifiedTransform ? populateOptions.transform : v => v;
254
254
  if (Array.isArray(val)) {
255
255
  // find logic
256
256
  const ret = [];
@@ -342,7 +342,3 @@ function isPopulatedObject(obj) {
342
342
  obj.$__ != null ||
343
343
  leanPopulateMap.has(obj);
344
344
  }
345
-
346
- function noop(v) {
347
- return v;
348
- }
@@ -184,6 +184,7 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
184
184
  if (hasMatchFunction) {
185
185
  match = match.call(doc, doc);
186
186
  }
187
+ throwOn$where(match);
187
188
  data.match = match;
188
189
  data.hasMatchFunction = hasMatchFunction;
189
190
  data.isRefPath = isRefPath;
@@ -461,6 +462,8 @@ function _virtualPopulate(model, docs, options, _virtualRes) {
461
462
  data.match = match;
462
463
  data.hasMatchFunction = hasMatchFunction;
463
464
 
465
+ throwOn$where(match);
466
+
464
467
  // Get local fields
465
468
  const ret = _getLocalFieldValues(doc, localField, model, options, virtual);
466
469
 
@@ -732,3 +735,24 @@ function _findRefPathForDiscriminators(doc, modelSchema, data, options, normaliz
732
735
 
733
736
  return modelNames;
734
737
  }
738
+
739
+ /**
740
+ * Throw an error if there are any $where keys
741
+ */
742
+
743
+ function throwOn$where(match) {
744
+ if (match == null) {
745
+ return;
746
+ }
747
+ if (typeof match !== 'object') {
748
+ return;
749
+ }
750
+ for (const key of Object.keys(match)) {
751
+ if (key === '$where') {
752
+ throw new MongooseError('Cannot use $where filter with populate() match');
753
+ }
754
+ if (match[key] != null && typeof match[key] === 'object') {
755
+ throwOn$where(match[key]);
756
+ }
757
+ }
758
+ }
package/lib/query.js CHANGED
@@ -4431,10 +4431,10 @@ Query.prototype.exec = async function exec(op) {
4431
4431
  str = str.slice(0, 60) + '...';
4432
4432
  }
4433
4433
  const err = new MongooseError('Query was already executed: ' + str);
4434
- err.originalStack = this._executionStack.stack;
4434
+ err.originalStack = this._executionStack;
4435
4435
  throw err;
4436
4436
  } else {
4437
- this._executionStack = new Error();
4437
+ this._executionStack = new Error().stack;
4438
4438
  }
4439
4439
 
4440
4440
  await _executePreExecHooks(this);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "7.8.2",
4
+ "version": "7.8.4",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -58,7 +58,7 @@
58
58
  "mkdirp": "^3.0.1",
59
59
  "mocha": "10.2.0",
60
60
  "moment": "2.x",
61
- "mongodb-memory-server": "9.2.0",
61
+ "mongodb-memory-server": "9.5.0",
62
62
  "ncp": "^2.0.0",
63
63
  "nyc": "15.1.0",
64
64
  "pug": "3.0.2",
package/valnotes.md ADDED
@@ -0,0 +1,85 @@
1
+ ## sift where
2
+
3
+ ```
4
+ it('match prevents using $where', async function() {
5
+ const ParentSchema = new Schema({
6
+ name: String,
7
+ child: {
8
+ type: mongoose.Schema.Types.ObjectId,
9
+ ref: 'Child'
10
+ },
11
+ children: [{
12
+ type: mongoose.Schema.Types.ObjectId,
13
+ ref: 'Child'
14
+ }]
15
+ });
16
+
17
+ const ChildSchema = new Schema({
18
+ name: String
19
+ });
20
+ ChildSchema.virtual('parent', {
21
+ ref: 'Parent',
22
+ localField: '_id',
23
+ foreignField: 'parent'
24
+ });
25
+
26
+ const Parent = db.model('Parent', ParentSchema);
27
+ const Child = db.model('Child', ChildSchema);
28
+
29
+ const child = await Child.create({ name: 'Luke' });
30
+ const parent = await Parent.create({ name: 'Anakin', child: child._id });
31
+
32
+ await assert.rejects(
33
+ () => Parent.findOne().populate({ path: 'child', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
34
+ /Cannot use \$where filter with populate\(\) match/
35
+ );
36
+ await assert.rejects(
37
+ () => Parent.find().populate({ path: 'child', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
38
+ /Cannot use \$where filter with populate\(\) match/
39
+ );
40
+ await assert.rejects(
41
+ () => parent.populate({ path: 'child', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
42
+ /Cannot use \$where filter with populate\(\) match/
43
+ );
44
+ await assert.rejects(
45
+ () => Child.find().populate({ path: 'parent', match: () => ({ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }) }),
46
+ /Cannot use \$where filter with populate\(\) match/
47
+ );
48
+ await assert.rejects(
49
+ () => Child.find().populate({ path: 'parent', match: () => ({ $or: [{ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }] }) }),
50
+ /Cannot use \$where filter with populate\(\) match/
51
+ );
52
+ await assert.rejects(
53
+ () => Child.find().populate({ path: 'parent', match: () => ({ $and: [{ $where: 'typeof console !== "undefined" ? doesNotExist("foo") : true;' }] }) }),
54
+ /Cannot use \$where filter with populate\(\) match/
55
+ );
56
+
57
+ class MyClass {}
58
+ MyClass.prototype.$where = 'typeof console !== "undefined" ? doesNotExist("foo") : true;';
59
+ // OK because sift only looks through own properties
60
+ await Child.find().populate({ path: 'parent', match: () => new MyClass() });
61
+ });
62
+ ```
63
+
64
+ ```
65
+ /**
66
+ * Throw an error if there are any $where keys
67
+ */
68
+
69
+ function throwOn$where(match) {
70
+ if (match == null) {
71
+ return;
72
+ }
73
+ if (typeof match !== 'object') {
74
+ return;
75
+ }
76
+ for (const key of Object.keys(match)) {
77
+ if (key === '$where') {
78
+ throw new MongooseError('Cannot use $where filter with populate() match');
79
+ }
80
+ if (match[key] != null && typeof match[key] === 'object') {
81
+ throwOn$where(match[key]);
82
+ }
83
+ }
84
+ }
85
+ ```