Get rid of collection2; do validations at mutation level

This commit is contained in:
SachaG 2017-04-03 16:24:19 +09:00
parent 27da5d0de9
commit e5837a6c0e
5 changed files with 52 additions and 17 deletions

View file

@ -1,6 +1,5 @@
accounts-base@1.2.15
accounts-password@1.3.4
aldeed:collection2-core@2.0.0
allow-deny@1.0.5
autoupdate@1.3.12
babel-compiler@6.14.1
@ -53,7 +52,6 @@ observe-sequence@1.0.16
ordered-dict@1.0.9
percolatestudio:synced-cron@1.1.0
promise@0.8.8
raix:eventemitter@0.1.3
random@1.0.10
rate-limit@1.0.7
reactive-dict@1.1.8
@ -71,7 +69,6 @@ srp@1.0.10
standard-minifier-css@1.3.4
standard-minifier-js@1.2.3
standard-minifiers@1.0.6
tmeasday:check-npm-versions@0.3.1
tracker@1.1.2
ui@1.0.12
underscore@1.0.10

View file

@ -10,10 +10,12 @@ const schema = {
_id: {
type: String,
optional: true,
viewableBy: ['guests'],
},
createdAt: {
type: Date,
optional: true,
viewableBy: ['guests'],
autoValue: (documentOrModifier) => {
if (documentOrModifier && !documentOrModifier.$set) return new Date() // if this is an insert, set createdAt to current timestamp
@ -21,6 +23,7 @@ const schema = {
},
userId: {
type: String,
optional: true,
viewableBy: ['guests'],
resolveAs: 'user: User',
},

View file

@ -14,13 +14,13 @@ SimpleSchema.extendOptions([
* @summary replacement for Collection2's attachSchema
* @class Mongo.Collection
*/
// Mongo.Collection.prototype.attachSchema = function (schemaOrFields) {
// if (schemaOrFields instanceof SimpleSchema) {
// this.simpleSchema = () => schemaOrFields;
// } else {
// this.simpleSchema().extend(schemaOrFields)
// }
// }
Mongo.Collection.prototype.attachSchema = function (schemaOrFields) {
if (schemaOrFields instanceof SimpleSchema) {
this.simpleSchema = () => schemaOrFields;
} else {
this.simpleSchema().extend(schemaOrFields)
}
}
/**
* @summary Add an additional field (or an array of fields) to a schema.

View file

@ -37,17 +37,20 @@ export const newMutation = ({ collection, document, currentUser, validate, conte
// we don't want to modify the original document
let newDocument = Object.assign({}, document);
const collectionName = collection._name;
const schema = collection.simpleSchema()._schema;
// if document is not trusted, run validation steps
if (validate) {
// validate document
collection.simpleSchema().validate(document);
// check that the current user has permission to insert each field
_.keys(newDocument).forEach(function (fieldName) {
_.keys(newDocument).forEach(fieldName => {
var field = schema[fieldName];
if (!context.Users.canInsertField (currentUser, field)) {
if (!field || !context.Users.canInsertField (currentUser, field)) {
throw new Error(Utils.encodeIntlError({id: 'app.disallowed_property_detected', value: fieldName}));
}
});
@ -55,11 +58,21 @@ export const newMutation = ({ collection, document, currentUser, validate, conte
// run validation callbacks
newDocument = runCallbacks(`${collectionName}.new.validate`, newDocument, currentUser);
}
// check if userId field is in the schema and add it to document if needed
const userIdInSchema = Object.keys(schema).find(key => key === 'userId');
if (!!userIdInSchema && !newDocument.userId) newDocument.userId = currentUser._id;
// run autoValue step
_.keys(schema).forEach(fieldName => {
if (!newDocument[fieldName] && schema[fieldName].autoValue) {
const autoValue = schema[fieldName].autoValue(newDocument);
if (autoValue && typeof autoValue.$setOnInsert === 'undefined') {
newDocument[fieldName] = autoValue;
}
}
});
// TODO: find that info in GraphQL mutations
// if (Meteor.isServer && this.connection) {
// post.userIP = this.connection.clientAddress;
@ -105,11 +118,14 @@ export const editMutation = ({ collection, documentId, set, unset, currentUser,
// if document is not trusted, run validation steps
if (validate) {
// validate modifiers
collection.simpleSchema().newContext().validate({$set: set, $unset: unset}, { modifier: true });
// check that the current user has permission to edit each field
const modifiedProperties = _.keys(set).concat(_.keys(unset));
modifiedProperties.forEach(function (fieldName) {
var field = schema[fieldName];
if (!context.Users.canEditField(currentUser, field, document)) {
if (!field || !context.Users.canEditField(currentUser, field, document)) {
throw new Error(Utils.encodeIntlError({id: 'app.disallowed_property_detected', value: fieldName}));
}
});
@ -118,11 +134,29 @@ export const editMutation = ({ collection, documentId, set, unset, currentUser,
modifier = runCallbacks(`${collectionName}.edit.validate`, modifier, document, currentUser);
}
// run autoValue step
_.keys(schema).forEach(fieldName => {
if (!modifier.$set[fieldName] && schema[fieldName].autoValue) {
const autoValue = schema[fieldName].autoValue(modifier);
if (autoValue && typeof autoValue.$setOnInsert === 'undefined') {
modifier.$set[fieldName] = autoValue;
}
}
});
// run sync callbacks (on mongo modifier)
modifier = runCallbacks(`${collectionName}.edit.sync`, modifier, document, currentUser);
// remove empty modifiers
if (_.isEmpty(modifier.$set)) {
delete modifier.$set;
}
if (_.isEmpty(modifier.$unset)) {
delete modifier.$unset;
}
// update document
collection.update(documentId, modifier);
collection.update(documentId, modifier, {removeEmptyStrings: false});
// get fresh copy of document from db
const newDocument = collection.findOne(documentId);
@ -131,6 +165,7 @@ export const editMutation = ({ collection, documentId, set, unset, currentUser,
runCallbacksAsync(`${collectionName}.edit.async`, newDocument, document, currentUser, collection);
// console.log("// edit mutation finished")
// console.log(modifier)
// console.log(newDocument)
return newDocument;

View file

@ -29,7 +29,7 @@ Package.onUse(function (api) {
// Third-party packages
'aldeed:collection2-core@2.0.0',
// 'aldeed:collection2-core@2.0.0',
'meteorhacks:picker@1.0.3',
'percolatestudio:synced-cron@1.1.0',
'meteorhacks:inject-initial@1.0.4',