Vulcan/packages/vulcan-users/lib/modules/mutations.js
2018-09-04 21:47:16 +09:00

225 lines
6.7 KiB
JavaScript

import { createMutator, updateMutator, deleteMutator, Utils, Connectors, registerCallback } from 'meteor/vulcan:lib';
import Users from './collection'; // TODO: circular dependency?
const performCheck = (mutation, user, document) => {
if (!mutation.check(user, document))
throw new Error(
Utils.encodeIntlError({ id: `app.mutation_not_allowed`, value: `"${mutation.name}" on _id "${document._id}"` })
);
};
const createMutation = {
name: 'createUser',
check(user, document) {
if (!user) return false;
// OpenCRUD backwards compatibility
return Users.canDo(user, ['user.create', 'users.new']);
},
mutation(root, { data }, context) {
const { Users, currentUser } = context;
performCheck(this, currentUser, data);
return createMutator({
collection: Users,
data,
currentUser,
validate: true,
context,
});
},
};
const updateMutation = {
name: 'updateUser',
check(user, document) {
if (!user || !document) return false;
// OpenCRUD backwards compatibility
return Users.owns(user, document) ? Users.canDo(user, ['user.update.own', 'users.edit.own']) : Users.canDo(user, [`user.update.all`, `users.edit.all`]);
},
async mutation(root, { selector, data }, context) {
const { Users, currentUser } = context;
const document = await Connectors.get(Users, selector);
if (!document) {
throw new Error(`Could not find document to update for selector: ${JSON.stringify(selector)}`);
}
performCheck(this, currentUser, document);
return updateMutator({
collection: Users,
selector,
data,
currentUser,
validate: true,
context,
});
},
};
const deleteMutation = {
name: 'deleteUser',
check(user, document) {
if (!user || !document) return false;
// OpenCRUD backwards compatibility
return Users.owns(user, document) ? Users.canDo(user, ['user.delete.own', 'users.remove.own']) : Users.canDo(user, [`user.delete.all`, `users.remove.all`]);
},
async mutation(root, { selector }, context) {
const { Users, currentUser } = context;
const document = await Connectors.get(Users, selector);
if (!document) {
throw new Error(`Could not find document to delete for selector: ${JSON.stringify(selector)}`);
}
performCheck(this, currentUser, document);
return deleteMutator({
collection: Users,
selector,
currentUser,
validate: true,
context,
});
},
};
const mutations = {
create: createMutation,
update: updateMutation,
delete: deleteMutation,
// OpenCRUD backwards compatibility
new: createMutation,
edit: updateMutation,
remove: deleteMutation,
};
export default mutations;
registerCallback({
name:'user.create.validate',
iterator: {document:'the document being inserted'},
properties: [
{ document: 'The document being inserted' },
{ currentUser: 'The current user' },
{ validationErrors: 'An object that can be used to accumulate validation errors' },
],
runs: 'sync',
returns: 'document',
description: `Validate a document before insertion (can be skipped when inserting directly on server).`,
});
registerCallback({
name:'user.create.before',
iterator: {document:'the document being inserted'},
properties: [
{ document: 'The document being inserted' },
{ currentUser: 'The current user' },
{ validationErrors: 'An object that can be used to accumulate validation errors' },
],
runs: 'sync',
returns: 'document',
description: `Perform operations on a new document before it's inserted in the database.`,
});
registerCallback({
name:'user.create.after',
iterator: {document:'the document after being inserted in the database'},
properties: [
{ currentUser: 'The current user' },
],
runs: 'sync',
returns: 'document',
description: `Perform operations on a new document after it's inserted in the database but *before* the mutation returns it.`,
});
registerCallback({
name:'user.create.async',
iterator: {data:'the document after being inserted in the database'},
properties: [
{insertedDocument: 'The document that was inserted to the collection'},
{ currentUser: 'The current user' },
{collection: 'The Users collection'}
],
runs: 'async',
returns: 'document',
description: `Perform operations on a new document after it's inserted in the database asynchronously.`,
});
registerCallback({
name: 'user.update.validate',
iterator: {data: 'The client data'},
properties: [
{document: 'The document being updated'},
{currentUser: 'The current user.'},
{validationErrors: 'an object that can be used to accumulate validation errors.'},
],
runs: 'sync',
description: 'Validate a document before update (can be skipped when updating directly on server).'
});
registerCallback({
name: 'user.update.before',
iterator: {data:'The client data'},
properties: [
{document: 'The document being edited'},
{currentUser: 'The current user'},
{newDocument: 'A preview of the future document'},
],
runs: 'sync',
description: `Perform operations on a document before it's updated on the database.`,
});
registerCallback({
name: 'user.update.after',
iterator: {newdocument: 'The document after the update'},
properties: [
{document: 'The document before the update'},
{currentUser: 'The current user'},
],
runs: 'sync',
description: `Perform operations on a document after it's updated in the database but *before* the mutation returns it.`
});
registerCallback({
name: 'user.update.async',
properties: [
{newDocument: 'The document after the update'},
{document: 'The document before the update'},
{currentUser: 'The current user'},
{collection: 'The Users collection'},
],
runs: 'async',
description: `Perform operations on a document after it's updated in the database asynchronously.`
});
registerCallback({
name: 'user.delete.validate',
iterator: {document: 'The document being deleted'},
properties: [
{currentUser: 'The current user'},
],
runs: 'sync',
description: `Validate a document before deletion (can be skipped when deleting directly on the server)`
});
registerCallback({
name: 'user.delete.before',
iterator: {document: 'The document being deleted'},
properties: [
{currentUser: 'The current user'},
],
runs: 'sync',
description: `Perform operations on a document before it's deleted from the database`,
});
registerCallback({
name: 'user.delete.async',
properties:[
{document: 'The document being deleted'},
{currentUser: 'The current user'},
{collection: 'The Users collection'},
],
runs: 'async',
description: `Perform operations on a document after it's deleted from the database asynchronously.`
});