copied alanning:roles package to rocketchat:authorization

pull/1828/head
Marcelo Schmidt 10 years ago
parent 6e84e842ec
commit 8f0cbd83bb
  1. 1
      .meteor/versions
  2. 132
      packages/rocketchat-authorization/client/roles.js
  3. 716
      packages/rocketchat-authorization/lib/roles.js
  4. 11
      packages/rocketchat-authorization/package.js
  5. 32
      packages/rocketchat-authorization/server/roles.js
  6. 4
      packages/rocketchat-integrations/package.js
  7. 2
      packages/rocketchat-livechat/package.js

@ -6,7 +6,6 @@ accounts-meteor-developer@1.0.6
accounts-oauth@1.1.8
accounts-password@1.1.4
accounts-twitter@1.0.6
alanning:roles@1.2.14
aldeed:simple-schema@1.5.3
arunoda:streams@0.1.17
autoupdate@1.2.4

@ -0,0 +1,132 @@
"use strict"
////////////////////////////////////////////////////////////
// Debugging helpers
//
// Run this in your browser console to turn on debugging
// for this package:
//
// localstorage.setItem('Roles.debug', true)
//
Roles.debug = false
if (localStorage) {
var temp = localStorage.getItem("Roles.debug")
if ('undefined' !== typeof temp) {
Roles.debug = !!temp
}
}
/**
* Convenience functions for use on client.
*
* NOTE: You must restrict user actions on the server-side; any
* client-side checks are strictly for convenience and must not be
* trusted.
*
* @module UIHelpers
*/
////////////////////////////////////////////////////////////
// UI helpers
//
// Use a semi-private variable rather than declaring UI
// helpers directly so that we can unit test the helpers.
// XXX For some reason, the UI helpers are not registered
// before the tests run.
//
Roles._uiHelpers = {
/**
* UI helper to check if current user is in at least one
* of the target roles. For use in client-side templates.
*
* @example
* {{#if isInRole 'admin'}}
* {{/if}}
*
* {{#if isInRole 'editor,user'}}
* {{/if}}
*
* {{#if isInRole 'editor,user' 'group1'}}
* {{/if}}
*
* @method isInRole
* @param {String} role Name of role or comma-seperated list of roles
* @param {String} [group] Optional, name of group to check
* @return {Boolean} true if current user is in at least one of the target roles
* @static
* @for UIHelpers
*/
isInRole: function (role, group) {
var user = Meteor.user(),
comma = (role || '').indexOf(','),
roles
if (!user) return false
if (!Match.test(role, String)) return false
if (comma !== -1) {
roles = _.reduce(role.split(','), function (memo, r) {
if (!r || !r.trim()) {
return memo
}
memo.push(r.trim())
return memo
}, [])
} else {
roles = [role]
}
if (Match.test(group, String)) {
return Roles.userIsInRole(user, roles, group)
}
return Roles.userIsInRole(user, roles)
}
}
////////////////////////////////////////////////////////////
// Register UI helpers
//
if (Roles.debug && console.log) {
console.log("[roles] Roles.debug =", Roles.debug)
}
if ('undefined' !== typeof Package.blaze &&
'undefined' !== typeof Package.blaze.Blaze &&
'function' === typeof Package.blaze.Blaze.registerHelper) {
_.each(Roles._uiHelpers, function (func, name) {
if (Roles.debug && console.log) {
console.log("[roles] registering Blaze helper '" + name + "'")
}
Package.blaze.Blaze.registerHelper(name, func)
})
}
/**
* Subscription handle for the currently logged in user's permissions.
*
* NOTE: The corresponding publish function, `_roles`, depends on
* `this.userId` so it will automatically re-run when the currently
* logged-in user changes.
*
* @example
*
* `Roles.subscription.ready()` // => `true` if user roles have been loaded
*
* @property subscription
* @type Object
* @for Roles
*/
Tracker.autorun(function () {
Roles.subscription = Meteor.subscribe("_roles")
})

@ -0,0 +1,716 @@
;(function () {
/**
* Provides functions related to user authorization. Compatible with built-in Meteor accounts packages.
*
* @module Roles
*/
/**
* Roles collection documents consist only of an id and a role name.
* ex: { _id:<uuid>, name: "admin" }
*/
if (!Meteor.roles) {
Meteor.roles = new Mongo.Collection("roles")
}
/**
* Authorization package compatible with built-in Meteor accounts system.
*
* Stores user's current roles in a 'roles' field on the user object.
*
* @class Roles
* @constructor
*/
if ('undefined' === typeof Roles) {
Roles = {}
}
"use strict";
var mixingGroupAndNonGroupErrorMsg = "Roles error: Can't mix grouped and non-grouped roles for same user";
_.extend(Roles, {
/**
* Constant used to reference the special 'global' group that
* can be used to apply blanket permissions across all groups.
*
* @example
* Roles.addUsersToRoles(user, 'admin', Roles.GLOBAL_GROUP)
* Roles.userIsInRole(user, 'admin') // => true
*
* Roles.setUserRoles(user, 'support-staff', Roles.GLOBAL_GROUP)
* Roles.userIsInRole(user, 'support-staff') // => true
* Roles.userIsInRole(user, 'admin') // => false
*
* @property GLOBAL_GROUP
* @type String
* @static
* @final
*/
GLOBAL_GROUP: '__global_roles__',
/**
* Create a new role. Whitespace will be trimmed.
*
* @method createRole
* @param {String} role Name of role
* @return {String} id of new role
*/
createRole: function (role) {
var id,
match
if (!role
|| 'string' !== typeof role
|| role.trim().length === 0) {
return
}
try {
id = Meteor.roles.insert({'name': role.trim()})
return id
} catch (e) {
// (from Meteor accounts-base package, insertUserDoc func)
// XXX string parsing sucks, maybe
// https://jira.mongodb.org/browse/SERVER-3069 will get fixed one day
if (e.name !== 'MongoError') throw e
match = e.err.match(/^E11000 duplicate key error index: ([^ ]+)/)
if (!match) throw e
if (match[1].indexOf('$name') !== -1)
throw new Meteor.Error(403, "Role already exists.")
throw e
}
},
/**
* Delete an existing role. Will throw "Role in use" error if any users
* are currently assigned to the target role.
*
* @method deleteRole
* @param {String} role Name of role
*/
deleteRole: function (role) {
if (!role) return
var foundExistingUser = Meteor.users.findOne(
{roles: {$in: [role]}},
{fields: {_id: 1}})
if (foundExistingUser) {
throw new Meteor.Error(403, 'Role in use')
}
var thisRole = Meteor.roles.findOne({name: role})
if (thisRole) {
Meteor.roles.remove({_id: thisRole._id})
}
},
/**
* Add users to roles. Will create roles as needed.
*
* NOTE: Mixing grouped and non-grouped roles for the same user
* is not supported and will throw an error.
*
* Makes 2 calls to database:
* 1. retrieve list of all existing roles
* 2. update users' roles
*
* @example
* Roles.addUsersToRoles(userId, 'admin')
* Roles.addUsersToRoles(userId, ['view-secrets'], 'example.com')
* Roles.addUsersToRoles([user1, user2], ['user','editor'])
* Roles.addUsersToRoles([user1, user2], ['glorious-admin', 'perform-action'], 'example.org')
* Roles.addUsersToRoles(userId, 'admin', Roles.GLOBAL_GROUP)
*
* @method addUsersToRoles
* @param {Array|String} users User id(s) or object(s) with an _id field
* @param {Array|String} roles Name(s) of roles/permissions to add users to
* @param {String} [group] Optional group name. If supplied, roles will be
* specific to that group.
* Group names can not start with a '$' or contain
* null characters. Periods in names '.' are
* automatically converted to underscores.
* The special group Roles.GLOBAL_GROUP provides
* a convenient way to assign blanket roles/permissions
* across all groups. The roles/permissions in the
* Roles.GLOBAL_GROUP group will be automatically
* included in checks for any group.
*/
addUsersToRoles: function (users, roles, group) {
// use Template pattern to update user roles
Roles._updateUserRoles(users, roles, group, Roles._update_$addToSet_fn)
},
/**
* Set a users roles/permissions.
*
* @example
* Roles.setUserRoles(userId, 'admin')
* Roles.setUserRoles(userId, ['view-secrets'], 'example.com')
* Roles.setUserRoles([user1, user2], ['user','editor'])
* Roles.setUserRoles([user1, user2], ['glorious-admin', 'perform-action'], 'example.org')
* Roles.setUserRoles(userId, 'admin', Roles.GLOBAL_GROUP)
*
* @method setUserRoles
* @param {Array|String} users User id(s) or object(s) with an _id field
* @param {Array|String} roles Name(s) of roles/permissions to add users to
* @param {String} [group] Optional group name. If supplied, roles will be
* specific to that group.
* Group names can not start with '$'.
* Periods in names '.' are automatically converted
* to underscores.
* The special group Roles.GLOBAL_GROUP provides
* a convenient way to assign blanket roles/permissions
* across all groups. The roles/permissions in the
* Roles.GLOBAL_GROUP group will be automatically
* included in checks for any group.
*/
setUserRoles: function (users, roles, group) {
// use Template pattern to update user roles
Roles._updateUserRoles(users, roles, group, Roles._update_$set_fn)
},
/**
* Remove users from roles
*
* @example
* Roles.removeUsersFromRoles(users.bob, 'admin')
* Roles.removeUsersFromRoles([users.bob, users.joe], ['editor'])
* Roles.removeUsersFromRoles([users.bob, users.joe], ['editor', 'user'])
* Roles.removeUsersFromRoles(users.eve, ['user'], 'group1')
*
* @method removeUsersFromRoles
* @param {Array|String} users User id(s) or object(s) with an _id field
* @param {Array|String} roles Name(s) of roles to add users to
* @param {String} [group] Optional. Group name. If supplied, only that
* group will have roles removed.
*/
removeUsersFromRoles: function (users, roles, group) {
var update
if (!users) throw new Error ("Missing 'users' param")
if (!roles) throw new Error ("Missing 'roles' param")
if (group) {
if ('string' !== typeof group)
throw new Error ("Roles error: Invalid parameter 'group'. Expected 'string' type")
if ('$' === group[0])
throw new Error ("Roles error: groups can not start with '$'")
// convert any periods to underscores
group = group.replace(/\./g, '_')
}
// ensure arrays
if (!_.isArray(users)) users = [users]
if (!_.isArray(roles)) roles = [roles]
// ensure users is an array of user ids
users = _.reduce(users, function (memo, user) {
var _id
if ('string' === typeof user) {
memo.push(user)
} else if ('object' === typeof user) {
_id = user._id
if ('string' === typeof _id) {
memo.push(_id)
}
}
return memo
}, [])
// update all users, remove from roles set
if (group) {
update = {$pullAll: {}}
update.$pullAll['roles.'+group] = roles
} else {
update = {$pullAll: {roles: roles}}
}
try {
if (Meteor.isClient) {
// Iterate over each user to fulfill Meteor's 'one update per ID' policy
_.each(users, function (user) {
Meteor.users.update({_id:user}, update)
})
} else {
// On the server we can leverage MongoDB's $in operator for performance
Meteor.users.update({_id:{$in:users}}, update, {multi: true})
}
}
catch (ex) {
if (ex.name === 'MongoError' && isMongoMixError(ex.err)) {
throw new Error (mixingGroupAndNonGroupErrorMsg)
}
throw ex
}
},
/**
* Check if user has specified permissions/roles
*
* @example
* // non-group usage
* Roles.userIsInRole(user, 'admin')
* Roles.userIsInRole(user, ['admin','editor'])
* Roles.userIsInRole(userId, 'admin')
* Roles.userIsInRole(userId, ['admin','editor'])
*
* // per-group usage
* Roles.userIsInRole(user, ['admin','editor'], 'group1')
* Roles.userIsInRole(userId, ['admin','editor'], 'group1')
* Roles.userIsInRole(userId, ['admin','editor'], Roles.GLOBAL_GROUP)
*
* // this format can also be used as short-hand for Roles.GLOBAL_GROUP
* Roles.userIsInRole(user, 'admin')
*
* @method userIsInRole
* @param {String|Object} user User Id or actual user object
* @param {String|Array} roles Name of role/permission or Array of
* roles/permissions to check against. If array,
* will return true if user is in _any_ role.
* @param {String} [group] Optional. Name of group. If supplied, limits check
* to just that group.
* The user's Roles.GLOBAL_GROUP will always be checked
* whether group is specified or not.
* @return {Boolean} true if user is in _any_ of the target roles
*/
userIsInRole: function (user, roles, group) {
var id,
userRoles,
query,
groupQuery,
found = false
// ensure array to simplify code
if (!_.isArray(roles)) {
roles = [roles]
}
if (!user) return false
if (group) {
if ('string' !== typeof group) return false
if ('$' === group[0]) return false
// convert any periods to underscores
group = group.replace(/\./g, '_')
}
if ('object' === typeof user) {
userRoles = user.roles
if (_.isArray(userRoles)) {
return _.some(roles, function (role) {
return _.contains(userRoles, role)
})
} else if ('object' === typeof userRoles) {
// roles field is dictionary of groups
found = _.isArray(userRoles[group]) && _.some(roles, function (role) {
return _.contains(userRoles[group], role)
})
if (!found) {
// not found in regular group or group not specified.
// check Roles.GLOBAL_GROUP, if it exists
found = _.isArray(userRoles[Roles.GLOBAL_GROUP]) && _.some(roles, function (role) {
return _.contains(userRoles[Roles.GLOBAL_GROUP], role)
})
}
return found
}
// missing roles field, try going direct via id
id = user._id
} else if ('string' === typeof user) {
id = user
}
if (!id) return false
query = {_id: id, $or: []}
// always check Roles.GLOBAL_GROUP
groupQuery = {}
groupQuery['roles.'+Roles.GLOBAL_GROUP] = {$in: roles}
query.$or.push(groupQuery)
if (group) {
// structure of query, when group specified including Roles.GLOBAL_GROUP
// {_id: id,
// $or: [
// {'roles.group1':{$in: ['admin']}},
// {'roles.__global_roles__':{$in: ['admin']}}
// ]}
groupQuery = {}
groupQuery['roles.'+group] = {$in: roles}
query.$or.push(groupQuery)
} else {
// structure of query, where group not specified. includes
// Roles.GLOBAL_GROUP
// {_id: id,
// $or: [
// {roles: {$in: ['admin']}},
// {'roles.__global_roles__': {$in: ['admin']}}
// ]}
query.$or.push({roles: {$in: roles}})
}
found = Meteor.users.findOne(query, {fields: {_id: 1}})
return found ? true : false
},
/**
* Retrieve users roles
*
* @method getRolesForUser
* @param {String|Object} user User Id or actual user object
* @param {String} [group] Optional name of group to restrict roles to.
* User's Roles.GLOBAL_GROUP will also be included.
* @return {Array} Array of user's roles, unsorted.
*/
getRolesForUser: function (user, group) {
if (!user) return []
if (group) {
if ('string' !== typeof group) return []
if ('$' === group[0]) return []
// convert any periods to underscores
group = group.replace(/\./g, '_')
}
if ('string' === typeof user) {
user = Meteor.users.findOne(
{_id: user},
{fields: {roles: 1}})
} else if ('object' !== typeof user) {
// invalid user object
return []
}
if (!user || !user.roles) return []
if (group) {
return _.union(user.roles[group] || [], user.roles[Roles.GLOBAL_GROUP] || [])
}
if (_.isArray(user.roles))
return user.roles
// using groups but group not specified. return global group, if exists
return user.roles[Roles.GLOBAL_GROUP] || []
},
/**
* Retrieve set of all existing roles
*
* @method getAllRoles
* @return {Cursor} cursor of existing roles
*/
getAllRoles: function () {
return Meteor.roles.find({}, {sort: {name: 1}})
},
/**
* Retrieve all users who are in target role.
*
* NOTE: This is an expensive query; it performs a full collection scan
* on the users collection since there is no index set on the 'roles' field.
* This is by design as most queries will specify an _id so the _id index is
* used automatically.
*
* @method getUsersInRole
* @param {Array|String} role Name of role/permission. If array, users
* returned will have at least one of the roles
* specified but need not have _all_ roles.
* @param {String} [group] Optional name of group to restrict roles to.
* User's Roles.GLOBAL_GROUP will also be checked.
* @param {Object} [options] Optional options which are passed directly
* through to `Meteor.users.find(query, options)`
* @return {Cursor} cursor of users in role
*/
getUsersInRole: function (role, group, options) {
var query,
roles = role,
groupQuery
// ensure array to simplify query logic
if (!_.isArray(roles)) roles = [roles]
if (group) {
if ('string' !== typeof group)
throw new Error ("Roles error: Invalid parameter 'group'. Expected 'string' type")
if ('$' === group[0])
throw new Error ("Roles error: groups can not start with '$'")
// convert any periods to underscores
group = group.replace(/\./g, '_')
}
query = {$or: []}
// always check Roles.GLOBAL_GROUP
groupQuery = {}
groupQuery['roles.'+Roles.GLOBAL_GROUP] = {$in: roles}
query.$or.push(groupQuery)
if (group) {
// structure of query, when group specified including Roles.GLOBAL_GROUP
// {
// $or: [
// {'roles.group1':{$in: ['admin']}},
// {'roles.__global_roles__':{$in: ['admin']}}
// ]}
groupQuery = {}
groupQuery['roles.'+group] = {$in: roles}
query.$or.push(groupQuery)
} else {
// structure of query, where group not specified. includes
// Roles.GLOBAL_GROUP
// {
// $or: [
// {roles: {$in: ['admin']}},
// {'roles.__global_roles__': {$in: ['admin']}}
// ]}
query.$or.push({roles: {$in: roles}})
}
return Meteor.users.find(query, options);
}, // end getUsersInRole
/**
* Retrieve users groups, if any
*
* @method getGroupsForUser
* @param {String|Object} user User Id or actual user object
* @param {String} [role] Optional name of roles to restrict groups to.
*
* @return {Array} Array of user's groups, unsorted. Roles.GLOBAL_GROUP will be omitted
*/
getGroupsForUser: function (user, role) {
var userGroups = [];
if (!user) return []
if (role) {
if ('string' !== typeof role) return []
if ('$' === role[0]) return []
// convert any periods to underscores
role = role.replace('.', '_')
}
if ('string' === typeof user) {
user = Meteor.users.findOne(
{_id: user},
{fields: {roles: 1}})
}else if ('object' !== typeof user) {
// invalid user object
return []
}
//User has no roles or is not using groups
if (!user || !user.roles || _.isArray(user.roles)) return []
if (role) {
_.each(user.roles, function(groupRoles, groupName) {
if (_.contains(groupRoles, role) && groupName !== Roles.GLOBAL_GROUP) {
userGroups.push(groupName);
}
});
return userGroups;
}else {
return _.without(_.keys(user.roles), Roles.GLOBAL_GROUP);
}
}, //End getGroupsForUser
/**
* Private function 'template' that uses $set to construct an update object
* for MongoDB. Passed to _updateUserRoles
*
* @method _update_$set_fn
* @protected
* @param {Array} roles
* @param {String} [group]
* @return {Object} update object for use in MongoDB update command
*/
_update_$set_fn: function (roles, group) {
var update = {}
if (group) {
// roles is a key/value dict object
update.$set = {}
update.$set['roles.' + group] = roles
} else {
// roles is an array of strings
update.$set = {roles: roles}
}
return update
}, // end _update_$set_fn
/**
* Private function 'template' that uses $addToSet to construct an update
* object for MongoDB. Passed to _updateUserRoles
*
* @method _update_$addToSet_fn
* @protected
* @param {Array} roles
* @param {String} [group]
* @return {Object} update object for use in MongoDB update command
*/
_update_$addToSet_fn: function (roles, group) {
var update = {}
if (group) {
// roles is a key/value dict object
update.$addToSet = {}
update.$addToSet['roles.' + group] = {$each: roles}
} else {
// roles is an array of strings
update.$addToSet = {roles: {$each: roles}}
}
return update
}, // end _update_$addToSet_fn
/**
* Internal function that uses the Template pattern to adds or sets roles
* for users.
*
* @method _updateUserRoles
* @protected
* @param {Array|String} users user id(s) or object(s) with an _id field
* @param {Array|String} roles name(s) of roles/permissions to add users to
* @param {String} group Group name. If not null or undefined, roles will be
* specific to that group.
* Group names can not start with '$'.
* Periods in names '.' are automatically converted
* to underscores.
* The special group Roles.GLOBAL_GROUP provides
* a convenient way to assign blanket roles/permissions
* across all groups. The roles/permissions in the
* Roles.GLOBAL_GROUP group will be automatically
* included in checks for any group.
* @param {Function} updateFactory Func which returns an update object that
* will be passed to Mongo.
* @param {Array} roles
* @param {String} [group]
*/
_updateUserRoles: function (users, roles, group, updateFactory) {
if (!users) throw new Error ("Missing 'users' param")
if (!roles) throw new Error ("Missing 'roles' param")
if (group) {
if ('string' !== typeof group)
throw new Error ("Roles error: Invalid parameter 'group'. Expected 'string' type")
if ('$' === group[0])
throw new Error ("Roles error: groups can not start with '$'")
// convert any periods to underscores
group = group.replace(/\./g, '_')
}
var existingRoles,
query,
update
// ensure arrays to simplify code
if (!_.isArray(users)) users = [users]
if (!_.isArray(roles)) roles = [roles]
// remove invalid roles
roles = _.reduce(roles, function (memo, role) {
if (role
&& 'string' === typeof role
&& role.trim().length > 0) {
memo.push(role.trim())
}
return memo
}, [])
// empty roles array is ok, since it might be a $set operation to clear roles
//if (roles.length === 0) return
// ensure all roles exist in 'roles' collection
existingRoles = _.reduce(Meteor.roles.find({}).fetch(), function (memo, role) {
memo[role.name] = true
return memo
}, {})
_.each(roles, function (role) {
if (!existingRoles[role]) {
Roles.createRole(role)
}
})
// ensure users is an array of user ids
users = _.reduce(users, function (memo, user) {
var _id
if ('string' === typeof user) {
memo.push(user)
} else if ('object' === typeof user) {
_id = user._id
if ('string' === typeof _id) {
memo.push(_id)
}
}
return memo
}, [])
// update all users
update = updateFactory(roles, group)
try {
if (Meteor.isClient) {
// On client, iterate over each user to fulfill Meteor's
// 'one update per ID' policy
_.each(users, function (user) {
Meteor.users.update({_id: user}, update)
})
} else {
// On the server we can use MongoDB's $in operator for
// better performance
Meteor.users.update(
{_id: {$in: users}},
update,
{multi: true})
}
}
catch (ex) {
if (ex.name === 'MongoError' && isMongoMixError(ex.err)) {
throw new Error (mixingGroupAndNonGroupErrorMsg)
}
throw ex
}
} // end _updateUserRoles
}) // end _.extend(Roles ...)
function isMongoMixError (errorMsg) {
var expectedMessages = [
'Cannot apply $addToSet modifier to non-array',
'Cannot apply $addToSet to a non-array field',
'Can only apply $pullAll to an array',
'Cannot apply $pull/$pullAll modifier to non-array',
"can't append to array using string field name",
'to traverse the element'
]
return _.some(expectedMessages, function (snippet) {
return strContains(errorMsg, snippet)
})
}
function strContains (haystack, needle) {
return -1 !== haystack.indexOf(needle)
}
}());

@ -11,16 +11,21 @@ Package.onUse(function(api) {
api.use([
'coffeescript',
'underscore',
'rocketchat:lib@0.0.1',
'alanning:roles@1.2.12'
'rocketchat:lib'
]);
api.use('mongo', 'client');
api.use('kadira:flow-router', 'client');
api.use('less@2.5.1', 'client');
api.use('tracker', 'client');
api.use('templating', 'client');
// roles
api.addFiles('server/roles.js', ['server']);
api.addFiles('lib/roles.js', ['client', 'server']);
api.addFiles('client/roles.js', ['client']);
api.addFiles('lib/rocketchat.coffee', ['server','client']);
api.addFiles('client/collection.coffee', ['client']);
api.addFiles('client/startup.coffee', ['client']);
@ -73,4 +78,6 @@ Package.onUse(function(api) {
}));
api.use('tap:i18n');
api.addFiles(tapi18nFiles);
api.export('Roles');
});

@ -0,0 +1,32 @@
"use strict"
/**
* Roles collection documents consist only of an id and a role name.
* ex: { _id: "123", name: "admin" }
*/
if (!Meteor.roles) {
Meteor.roles = new Meteor.Collection("roles")
// Create default indexes for roles collection
Meteor.roles._ensureIndex('name', {unique: 1})
}
/**
* Publish logged-in user's roles so client-side checks can work.
*
* Use a named publish function so clients can check `ready()` state.
*/
Meteor.publish('_roles', function () {
var loggedInUserId = this.userId,
fields = {roles: 1}
if (!loggedInUserId) {
this.ready()
return
}
return Meteor.users.find({_id: loggedInUserId},
{fields: fields})
})

@ -12,8 +12,8 @@ Package.onUse(function(api) {
api.use('coffeescript');
api.use('underscore');
api.use('simple:highlight.js');
api.use('rocketchat:lib@0.0.1');
api.use('alanning:roles@1.2.12');
api.use('rocketchat:lib');
api.use('rocketchat:authorization');
api.use('kadira:flow-router', 'client');
api.use('templating', 'client');

@ -20,8 +20,8 @@ Package.onUse(function(api) {
api.use(['webapp', 'autoupdate'], 'server');
api.use('ecmascript');
api.use('alanning:roles@1.2.12');
api.use('rocketchat:lib');
api.use('rocketchat:authorization');
api.use('kadira:flow-router', 'client');
api.use('templating', 'client');
api.use('mongo');

Loading…
Cancel
Save