mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
ie, they can use arbitrary selectors on the server and in client stubs, but not in other client contexts. This is to prevent clients from executing arbitrary selectors against the DB. Because of this, the update and remove allow/deny callbacks can only ever get one doc, so switch them from getting an array to just getting the doc (like insert).
116 lines
3.5 KiB
JavaScript
116 lines
3.5 KiB
JavaScript
|
|
|
|
(function () {
|
|
|
|
|
|
LocalCollection._looksLikeObjectID = function (str) {
|
|
return str.length === 24 && str.match(/^[0-9a-f]*$/);
|
|
};
|
|
|
|
LocalCollection._ObjectID = function (hexString) {
|
|
//random-based impl of Mongo ObjectID
|
|
var self = this;
|
|
if (hexString) {
|
|
hexString = hexString.toLowerCase();
|
|
if (!LocalCollection._looksLikeObjectID(hexString)) {
|
|
throw new Error("Invalid hexadecimal string for creating an ObjectID");
|
|
}
|
|
// meant to work with _.isEqual(), which relies on structural equality
|
|
self._str = hexString;
|
|
} else {
|
|
self._str = Random.hexString(24);
|
|
}
|
|
};
|
|
|
|
LocalCollection._ObjectID.prototype.toString = function () {
|
|
var self = this;
|
|
return "ObjectID(\"" + self._str + "\")";
|
|
};
|
|
|
|
LocalCollection._ObjectID.prototype.equals = function (other) {
|
|
var self = this;
|
|
return other instanceof LocalCollection._ObjectID &&
|
|
self.valueOf() === other.valueOf();
|
|
};
|
|
|
|
LocalCollection._ObjectID.prototype.clone = function () {
|
|
var self = this;
|
|
return new LocalCollection._ObjectID(self._str);
|
|
};
|
|
|
|
LocalCollection._ObjectID.prototype.typeName = function() {
|
|
return "oid";
|
|
};
|
|
|
|
LocalCollection._ObjectID.prototype.getTimestamp = function() {
|
|
var self = this;
|
|
return parseInt(self._str.substr(0, 8), 16);
|
|
};
|
|
|
|
LocalCollection._ObjectID.prototype.valueOf =
|
|
LocalCollection._ObjectID.prototype.toJSONValue =
|
|
LocalCollection._ObjectID.prototype.toHexString =
|
|
function () { return this._str; };
|
|
|
|
// Is this selector just shorthand for lookup by _id?
|
|
LocalCollection._selectorIsId = function (selector) {
|
|
return (typeof selector === "string") ||
|
|
(typeof selector === "number") ||
|
|
selector instanceof LocalCollection._ObjectID;
|
|
};
|
|
|
|
// Is the selector just lookup by _id (shorthand or not)?
|
|
LocalCollection._selectorIsIdPerhapsAsObject = function (selector) {
|
|
return LocalCollection._selectorIsId(selector) ||
|
|
(selector && typeof selector === "object" &&
|
|
selector._id && LocalCollection._selectorIsId(selector._id) &&
|
|
_.size(selector) === 1);
|
|
};
|
|
|
|
// If this is a selector which explicitly constrains the match by ID to a finite
|
|
// number of documents, returns a list of their IDs. Otherwise returns
|
|
// null. Note that the selector may have other restrictions so it may not even
|
|
// match those document! We care about $in and $and since those are generated
|
|
// access-controlled update and remove.
|
|
LocalCollection._idsMatchedBySelector = function (selector) {
|
|
// Is the selector just an ID?
|
|
if (LocalCollection._selectorIsId(selector))
|
|
return [selector];
|
|
if (!selector)
|
|
return null;
|
|
|
|
// Do we have an _id clause?
|
|
if (_.has(selector, '_id')) {
|
|
// Is the _id clause just an ID?
|
|
if (LocalCollection._selectorIsId(selector._id))
|
|
return [selector._id];
|
|
// Is the _id clause {_id: {$in: ["x", "y", "z"]}}?
|
|
if (selector._id && selector._id.$in
|
|
&& _.isArray(selector._id.$in)
|
|
&& !_.isEmpty(selector._id.$in)
|
|
&& _.all(selector._id.$in, LocalCollection._selectorIsId)) {
|
|
return selector._id.$in;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// If this is a top-level $and, and any of the clauses constrain their
|
|
// documents, then the whole selector is constrained by any one clause's
|
|
// constraint. (Well, by their intersection, but that seems unlikely.)
|
|
if (selector.$and && _.isArray(selector.$and)) {
|
|
for (var i = 0; i < selector.$and.length; ++i) {
|
|
var subIds = LocalCollection._idsMatchedBySelector(selector.$and[i]);
|
|
if (subIds)
|
|
return subIds;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
EJSON.addType("oid", function (str) {
|
|
return new LocalCollection._ObjectID(str);
|
|
});
|
|
|
|
})();
|