Every newly created Meteor project uses the insecure
package. This is the package that allows us to edit the database from the client. It’s useful when prototyping, but it is not good for production level applications. Following the Meteor todos tutorial security with methods step, we’ve removed the insecure package in meteor-application-template-react-production
. Removing the insecure package removes all client-side database permissions. We had to implement some Meteor methods to allow the client to update the database. We are using meteor/validated-methods.
In app/imports/api/stuff
, we created the StuffCollection.methods.js. This file defines three methods, stuffDefineMethod
, stuffUpdateMethod
and stuffRemoveItMethod
.
import { Meteor } from 'meteor/meteor';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { CallPromiseMixin } from 'meteor/didericis:callpromise-mixin';
import { Stuffs } from './StuffCollection';
/**
* Meteor method used to define new instances of the given collection name.
* @param collectionName the name of the collection.
* @param definitionDate the object used in the collection.define method.
* @memberOf api/base
*/
export const stuffDefineMethod = new ValidatedMethod({
name: 'StuffCollection.define',
mixins: [CallPromiseMixin],
validate: null,
run(definitionData) {
if (Meteor.isServer) {
const docID = Stuffs.define(definitionData);
// console.log(`stuffDefineMethod returning ${docID}. Now have ${Stuffs.count()}`);
return docID;
}
return '';
},
});
export const stuffUpdateMethod = new ValidatedMethod({
name: 'StuffCollection.update',
mixins: [CallPromiseMixin],
validate: null,
run(updateData) {
Stuffs.update(updateData.id, updateData);
return true;
},
});
export const stuffRemoveItMethod = new ValidatedMethod({
name: 'StuffCollection.removeIt',
mixins: [CallPromiseMixin],
validate: null,
run(instance) {
return Stuffs.removeIt(instance);
},
});
Note: Every collection will need three methods
We suggest the names of the methods be ${collectionName}.define
, ${collectionName}.update
, and ${collectionName}.removeIt
. This ensures the names of the ValidatedMethods are unique.
The client calls the method and the method runs on the server giving access to the database.
We updated the AddStuff.jsx’s submit
method to call stuffDefineMethod
.
/** On submit, insert the data. */
submit(data, formRef) {
const { name, quantity, condition } = data;
const owner = Meteor.user().username;
stuffDefineMethod.call({ name, quantity, condition, owner },
(error) => {
if (error) {
swal('Error', error.message, 'error');
} else {
swal('Success', 'Item added successfully', 'success');
formRef.reset();
}
});
}
We extract the information from the form. Then get the currently logged in user’s name. Then we call the stuffDefineMethod
passing in the data and a callback function. If there is an error we display a Sweet Alert indicating the error or we indicate success and reset the form.
Similarly, we updated the EditStuff.jsx’s submit
method to call stuffUpdateMethod
.
/** On successful submit, insert the data. */
submit(data) {
const { name, quantity, condition, _id } = data;
const updateData = {
id: _id,
name,
quantity,
condition,
};
stuffUpdateMethod.call(updateData, (error) => (error ?
swal('Error', error.message, 'error') :
swal('Success', 'Item updated successfully', 'success')));
}
We extract the form values from data, create the updateData object, then call stuffUpdateMethod
with a callback function.