Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,83 +1,36 @@
// TODO: Remove this after meteor fixes the issue
// This override fixes a recent issue introduced after the update to Meteor 3.0
// MinimongoCollection.remove(query) where `query` has `_id: { $in: Array }` removes only the first found record.
LocalCollection.prototype['_eachPossiblyMatchingDocAsync'] = async function (selector, fn) {
const specificIds = LocalCollection._idsMatchedBySelector(selector);
LocalCollection.prototype['_eachPossiblyMatchingDocAsync'] = async function (selector, fn) {
const specificIds = LocalCollection._idsMatchedBySelector(selector);

if (specificIds) {
for (const id of specificIds) {
const doc = this._docs.get(id);
if (specificIds) {
for (const id of specificIds) {
const doc = this._docs.get(id);

if (doc && (await fn(doc, id)) === false) { // Changed from `!fn(doc,id)`
break
}
}
} else {
await this._docs.forEachAsync(fn);
}
}

LocalCollection.prototype['_eachPossiblyMatchingDocSync'] = function (selector, fn) {
const specificIds = LocalCollection._idsMatchedBySelector(selector);

if (specificIds) {
for (const id of specificIds) {
const doc = this._docs.get(id);

if (doc && fn(doc, id) === false) { // Changed from `!fn(doc,id)`
break
}
}
} else {
this._docs.forEach(fn);
}
}

// This file overwrites the default metoer Mongo.Collection modifiers: "insert",
// "update", "remove"
//
// The new methods are checking if Meteor is in "restricted" mode to apply
// allow and deny rules if needed.
//
// This will allow us to run the modifiers inside of a "Meteor.runAsUser" with
// security checks.
_.each(['insert', 'update', 'remove'], function (method) {
var _super = Mongo.Collection.prototype[method];

Mongo.Collection.prototype[method] = function (/* arguments */) {
var self = this;
var args = _.toArray(arguments);

// Check if this method is run in restricted mode and collection is
// restricted.
if (Meteor.isRestricted() && self._restricted) {
var generatedId = null;
if (method === 'insert' && !_.has(args[0], '_id')) {
generatedId = self._makeNewID();
}

// short circuit if there is no way it will pass.
if (self._validators[method].allow.length === 0) {
throw new Meteor.Error(403, 'Access denied. No allow validators set on restricted ' + "collection for method '" + method + "'.");
if (doc && (await fn(doc, id)) === false) {
// Changed from `!fn(doc,id)`
break;
}
}
} else {
await this._docs.forEachAsync(fn);
}
};

var validatedMethodName = '_validated' + method.charAt(0).toUpperCase() + method.slice(1);
args.unshift(Meteor.userId());
LocalCollection.prototype['_eachPossiblyMatchingDocSync'] = function (selector, fn) {
const specificIds = LocalCollection._idsMatchedBySelector(selector);

if (method === 'insert') {
args.push(generatedId);
if (specificIds) {
for (const id of specificIds) {
const doc = this._docs.get(id);

self[validatedMethodName].apply(self, args);
// xxx: for now we return the id since self._validatedInsert doesn't
// yet return the new id
return generatedId || args[0]._id;
if (doc && fn(doc, id) === false) {
// Changed from `!fn(doc,id)`
break;
}

return self[validatedMethodName].apply(self, args);
}

return _super.apply(self, args);
};
});


} else {
this._docs.forEach(fn);
}
};
88 changes: 1 addition & 87 deletions apps/meteor/packages/meteor-run-as-user/lib/common.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,3 @@
// This file adds the actual "Meteor.runAsUser" and "Meteor.isRestricted" api
//
// It's done by using a DDP method invocation, setting a user id and a
// "isRestricted" flag on it.
//
// If run inside of an existing DDP invocation a nested version will be created.

var restrictedMode = new Meteor.EnvironmentVariable();

/**
* Returns true if inside a runAsUser user scope
* @return {Boolean} True if in a runAsUser user scope
*/
Meteor.isRestricted = function () {
return !!restrictedMode.get();
};

/**
* Run code restricted
* @param {Function} f Code to run in restricted mode
* @return {Any} Result of code running
*/
Meteor.runRestricted = function (f) {
if (Meteor.isRestricted()) {
return f();
} else {
return restrictedMode.withValue(true, f);
}
};

/**
* Run code unrestricted
* @param {Function} f Code to run in restricted mode
* @return {Any} Result of code running
*/
Meteor.runUnrestricted = function (f) {
if (Meteor.isRestricted()) {
return restrictedMode.withValue(false, f);
} else {
f();
}
};

/**
* Run as a user
* @param {String} userId The id of user to run as
Expand All @@ -56,7 +13,7 @@ Meteor.runAsUser = function (userId, f) {
? currentInvocation
: {
connection: null,
},
},
);

// Now run as user on this invocation
Expand All @@ -66,46 +23,3 @@ Meteor.runAsUser = function (userId, f) {
return f.apply(invocation, [userId]);
});
};

/**
* Run as restricted user
* @param {Function} f Function to run unrestricted
* @return {Any} Returns function result
*/
Meteor.runAsRestrictedUser = function (userId, f) {
return Meteor.runRestricted(function () {
return Meteor.runAsUser(userId, f);
});
};

var adminMode = new Meteor.EnvironmentVariable();

/**
* Check if code is running isside an invocation / method
*/
Meteor.isAdmin = function () {
return !!adminMode.get();
};

/**
* Make the function run outside invocation
*/
Meteor.runAsAdmin = function (f) {
if (Meteor.isAdmin()) {
return f();
} else {
return adminMode.withValue(false, f);
}
};

/**
* Make sure code runs outside an invocation on the
* server
*/
Meteor.runOutsideInvocation = function (f) {
if (Meteor.isServer && DDP._CurrentInvocation.get()) {
DDP._CurrentInvocation.withValue(null, f);
} else {
f();
}
};
94 changes: 0 additions & 94 deletions apps/meteor/packages/meteor-run-as-user/lib/pre.1.0.3.js

This file was deleted.

10 changes: 1 addition & 9 deletions apps/meteor/packages/meteor-run-as-user/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Package.describe({
});

Package.onUse(function (api) {

api.use([
'meteor',
'check',
Expand All @@ -19,12 +18,5 @@ Package.onUse(function (api) {
// 'ddp-client'
]);

api.addFiles(
[
'lib/pre.1.0.3.js', // Waiting for ddp-common and ddp-client
'lib/common.js',
'lib/collection.overwrites.js',
],
['client', 'server'],
);
api.addFiles(['lib/common.js', 'lib/collection.overwrites.js'], ['client', 'server']);
});
Loading