Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add base event hooks methods and implement a few #720

Merged
merged 3 commits into from
Feb 2, 2016
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
13 changes: 11 additions & 2 deletions packages/reaction-accounts/server/methods/accounts.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ Accounts.onCreateUser(function (options, user) {

// assign default user roles
user.roles = roles;
return user;

// run onCreateUser hooks
// (the user object must be returned by all callbacks)
userDoc = ReactionCore.Hooks.Events.run("onCreateUser", user, options);

return userDoc;
}
});

Expand All @@ -97,7 +102,11 @@ Accounts.onCreateUser(function (options, user) {
* @param {Object} options - user account creation options
* @fires "cart/mergeCart" Method
*/
Accounts.onLogin(function (options) {
Accounts.onLogin(function (opts) {
// run onLogin hooks
// (the options object must be returned by all callbacks)
options = ReactionCore.Hooks.Events.run("onLogin", opts);

// remove anonymous role
// all users are guest, but anonymous user don't have profile access
// or ability to order history, etc. so ensure its removed upon login.
Expand Down
3 changes: 3 additions & 0 deletions packages/reaction-core/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ Package.onUse(function (api) {
api.addFiles("server/methods/hooks/hooks.js");
api.addFiles("server/methods/hooks/cart.js", "server");

// misc hooks
api.addFiles("server/hooks.js", "server");

api.addFiles("server/methods/workflows/orders.js", "server");

// client
Expand Down
80 changes: 80 additions & 0 deletions packages/reaction-core/server/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Callback hooks to alter the behavior of common operations or trigger other things.
* @namespace ReactionCore.Hooks.Events
*/
ReactionCore.Hooks = {};
ReactionCore.Hooks.Events = {};


/**
* Add a callback function to a hook
* @param {String} name - The name of the hook
* @param {Function} callback - The callback function
* @return {Array} array of the currently defined hooks
*/
ReactionCore.Hooks.Events.add = (name, callback) => {
// if callback array doesn't exist yet, initialize it
if (typeof ReactionCore.Hooks.Events[name] === "undefined") {
ReactionCore.Hooks.Events[name] = [];
}
return ReactionCore.Hooks.Events[name].push(callback);
};


/**
* Remove a callback from a hook
* @param {String} name - The name of the hook
* @param {String} callbackName - The name of the function to remove
* @return {Array} array of remaining callbacks
*/
ReactionCore.Hooks.Events.remove = (name, callbackName) => {
ReactionCore.Hooks.Events[name] = _.reject(ReactionCore.Hooks.Events[name], (callback) => {
return callback.name === callbackName;
});

return ReactionCore.Hooks.Events;
};


/**
* Successively run all of a hook's callbacks on an item
* @param {String} name - The name of the hook
* @param {Object} item - The object, modifier, etc. on which to run the callbacks
* @param {Object} [constant] - An optional constant that will be passed along to each callback
* @return {Object} Returns the item after it has been through all callbacks for this hook
*/
ReactionCore.Hooks.Events.run = (name, item, constant) => {
const callbacks = ReactionCore.Hooks.Events[name];

// if the hook exists, and contains callbacks to run
if (typeof callbacks !== "undefined" && !!callbacks.length) {
return callbacks.reduce((result, callback) => {
return callback(result, constant);
}, item);
}
return item;
};


/**
* Successively run all of a hook's callbacks on an item, in async mode (only works on server)
* @param {String} name - The name of the hook
* @param {Object} item - The object, modifier, etc. on which to run the callbacks
* @param {Object} [constant] - An optional constant that will be passed along to each callback
* @return {Object} Returns the item after it has been through all callbacks for this hook
*/
ReactionCore.Hooks.Events.runAsync = (name, item, constant) => {
const callbacks = ReactionCore.Hooks.Events[name];

if (Meteor.isServer && typeof callbacks !== "undefined" && !!callbacks.length) {
// use defer to avoid holding up client
Meteor.defer(() => {
// run all async server callbacks successively on object
callbacks.forEach((callback) => {
callback(item, constant);
});
});
} else {
return item;
}
};
26 changes: 10 additions & 16 deletions packages/reaction-core/server/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ ReactionRegistry.loadSettings = function (json) {
* @returns {String} return userId
*/
ReactionRegistry.createDefaultAdminUser = function () {
const options = {};
let options = {};
const domain = getDomain();
const defaultAdminRoles = ["owner", "admin", "guest"];
const shopId = ReactionCore.getShopId();
Expand All @@ -131,6 +131,10 @@ ReactionRegistry.createDefaultAdminUser = function () {
}
}

// run hooks on options object before creating user
// (the options object must be returned from all callbacks)
options = ReactionCore.Hooks.Events.run("beforeCreateDefaultAdminUser", options);

// set the default shop email to the default admin email
ReactionCore.Collections.Shops.update(shopId, {
$addToSet: {
Expand Down Expand Up @@ -175,21 +179,7 @@ ReactionRegistry.createDefaultAdminUser = function () {
"Unable to send admin account verification email.", error);
}
}
// launchdock is the Reaction PaaS solution
// if we have launchdock credentials, we'll configure them
if (process.env.LAUNCHDOCK_USERID) {
Meteor.users.update({
_id: accountId
}, {
$set: {
"services.launchdock.userId": process.env.LAUNCHDOCK_USERID,
"services.launchdock.username": process.env.LAUNCHDOCK_USERNAME,
"services.launchdock.auth": process.env.LAUNCHDOCK_AUTH,
"services.launchdock.url": process.env.LAUNCHDOCK_URL,
"services.launchdock.stackId": process.env.LAUNCHDOCK_STACK_ID
}
});
}

// populate roles with all the packages and their permissions
// this way the default user has all permissions
const packages = ReactionCore.Collections.Packages.find().fetch();
Expand Down Expand Up @@ -217,6 +207,10 @@ ReactionRegistry.createDefaultAdminUser = function () {
\n PASSWORD: ${options.password}
\n ********************************* \n\n`
);

// run hooks on new user object
const user = Meteor.users.findOne(accountId);
ReactionCore.Hooks.Events.run("afterCreateDefaultAdminUser", user);
};

/**
Expand Down