Move isAdmin init code to callback, fix #1917

This commit is contained in:
SachaG 2018-03-03 15:04:33 +09:00
parent e63c412198
commit 20185cfda3
6 changed files with 93 additions and 82 deletions

View file

@ -1,71 +0,0 @@
import Users from './collection.js';
import marked from 'marked';
import { addCallback, Utils, runCallbacksAsync } from 'meteor/vulcan:lib'; // import from vulcan:lib because vulcan:core isn't loaded yet
//////////////////////////////////////////////////////
// Callbacks //
//////////////////////////////////////////////////////
function hasCompletedProfile (user) {
return Users.hasCompletedProfile(user);
}
addCallback("users.profileCompleted.sync", hasCompletedProfile);
// remove this to get rid of dependency on vulcan:email
// function usersNewAdminUserCreationNotification (user) {
// // send notifications to admins
// const admins = Users.adminUsers();
// admins.forEach(function(admin) {
// if (Users.getSetting(admin, "notifications_users", false)) {
// const emailProperties = Users.getNotificationProperties(user);
// const html = VulcanEmail.getTemplate('newUser')(emailProperties);
// VulcanEmail.send(Users.getEmail(admin), `New user account: ${emailProperties.displayName}`, VulcanEmail.buildTemplate(html));
// }
// });
// return user;
// }
// addCallback("users.new.sync", usersNewAdminUserCreationNotification);
function usersEditGenerateHtmlBio (modifier) {
if (modifier.$set && modifier.$set.bio) {
modifier.$set.htmlBio = Utils.sanitize(marked(modifier.$set.bio));
}
return modifier;
}
addCallback("users.edit.sync", usersEditGenerateHtmlBio);
function usersEditCheckEmail (modifier, user) {
// if email is being modified, update user.emails too
if (modifier.$set && modifier.$set.email) {
const newEmail = modifier.$set.email;
// check for existing emails and throw error if necessary
const userWithSameEmail = Users.findByEmail(newEmail);
if (userWithSameEmail && userWithSameEmail._id !== user._id) {
throw new Error(Utils.encodeIntlError({id:"users.email_already_taken", value: newEmail}));
}
// if user.emails exists, change it too
if (!!user.emails) {
user.emails[0].address = newEmail;
modifier.$set.emails = user.emails;
}
// update email hash
modifier.$set.emailHash = Users.avatar.hash(newEmail);
}
return modifier;
}
addCallback("users.edit.sync", usersEditCheckEmail);
// when a user is edited, check if their profile is now complete
function usersCheckCompletion (newUser, oldUser) {
if (!Users.hasCompletedProfile(oldUser) && Users.hasCompletedProfile(newUser)) {
runCallbacksAsync("users.profileCompleted.async", newUser);
}
}
addCallback("users.edit.async", usersCheckCompletion);

View file

@ -1,7 +1,6 @@
import Users from './collection.js';
import './avatar.js';
import './callbacks.js';
import './fragments.js';
import './helpers.js';
import './permissions.js';

View file

@ -81,11 +81,6 @@ const schema = {
editableBy: ['admins'],
viewableBy: ['guests'],
group: adminGroup,
onInsert: async user => {
// if this is not a dummy account, and is the first user ever, make them an admin
const realUsersCount = await Connectors.count(getCollection('Users'), {'isDummy': {$ne: true}});
return (!user.isDummy && realUsersCount === 0) ? true : false;
}
},
profile: {
type: Object,
@ -203,6 +198,9 @@ const schema = {
fieldName: 'avatarUrl',
type: 'String',
resolver: async (user, args, { Users }) => {
if (_.isEmpty(user)) return null;
if (user.avatarUrl) {
return user.avatarUrl;
} else {
@ -211,6 +209,7 @@ const schema = {
const fullUser = await Users.loader.load(user._id);
return Users.avatar.getUrl(fullUser);
}
}
}
},

View file

@ -0,0 +1,80 @@
import Users from '../modules/collection.js';
import marked from 'marked';
import { addCallback, Utils, runCallbacksAsync } from 'meteor/vulcan:lib'; // import from vulcan:lib because vulcan:core isn't loaded yet
//////////////////////////////////////////////////////
// Callbacks //
//////////////////////////////////////////////////////
function hasCompletedProfile (user) {
return Users.hasCompletedProfile(user);
}
addCallback("users.profileCompleted.sync", hasCompletedProfile);
// remove this to get rid of dependency on vulcan:email
// function usersNewAdminUserCreationNotification (user) {
// // send notifications to admins
// const admins = Users.adminUsers();
// admins.forEach(function(admin) {
// if (Users.getSetting(admin, "notifications_users", false)) {
// const emailProperties = Users.getNotificationProperties(user);
// const html = VulcanEmail.getTemplate('newUser')(emailProperties);
// VulcanEmail.send(Users.getEmail(admin), `New user account: ${emailProperties.displayName}`, VulcanEmail.buildTemplate(html));
// }
// });
// return user;
// }
// addCallback("users.new.sync", usersNewAdminUserCreationNotification);
function usersMakeAdmin (user) {
// if this is not a dummy account, and is the first user ever, make them an admin
// TODO: should use await Connectors.count() instead, but cannot await inside Accounts.onCreateUser. Fix later.
const realUsersCount = Users.find({'isDummy': {$ne: true}}).count();
user.isAdmin = !user.isDummy && realUsersCount === 0;
return user;
}
addCallback("users.new.sync", usersMakeAdmin);
function usersEditGenerateHtmlBio (modifier) {
if (modifier.$set && modifier.$set.bio) {
modifier.$set.htmlBio = Utils.sanitize(marked(modifier.$set.bio));
}
return modifier;
}
addCallback("users.edit.sync", usersEditGenerateHtmlBio);
function usersEditCheckEmail (modifier, user) {
// if email is being modified, update user.emails too
if (modifier.$set && modifier.$set.email) {
const newEmail = modifier.$set.email;
// check for existing emails and throw error if necessary
const userWithSameEmail = Users.findByEmail(newEmail);
if (userWithSameEmail && userWithSameEmail._id !== user._id) {
throw new Error(Utils.encodeIntlError({id:"users.email_already_taken", value: newEmail}));
}
// if user.emails exists, change it too
if (!!user.emails) {
user.emails[0].address = newEmail;
modifier.$set.emails = user.emails;
}
// update email hash
modifier.$set.emailHash = Users.avatar.hash(newEmail);
}
return modifier;
}
addCallback("users.edit.sync", usersEditCheckEmail);
// when a user is edited, check if their profile is now complete
function usersCheckCompletion (newUser, oldUser) {
if (!Users.hasCompletedProfile(oldUser) && Users.hasCompletedProfile(newUser)) {
runCallbacksAsync("users.profileCompleted.async", newUser);
}
}
addCallback("users.edit.async", usersCheckCompletion);

View file

@ -1,6 +1,7 @@
import './on_create_user.js';
import './urls.js';
import './graphql_context.js';
import './callbacks.js';
export {default as createUser} from './create_user.js';
export * from '../modules/index.js';

View file

@ -1,6 +1,7 @@
import Users from '../modules/index.js';
import { runCallbacks, runCallbacksAsync, Utils } from 'meteor/vulcan:lib'; // import from vulcan:lib because vulcan:core isn't loaded yet
// TODO: the following should use async/await, but async/await doesn't seem to work with Accounts.onCreateUser
function onCreateUserCallback (options, user) {
const schema = Users.simpleSchema()._schema;
@ -28,15 +29,18 @@ function onCreateUserCallback (options, user) {
user = runCallbacks(`users.new.validate`, user);
// run onInsert step
_.keys(schema).forEach(fieldName => {
// note: cannot use forEach with async/await.
// note 2: don't use async/await here for now. TODO: fix this.
// See https://stackoverflow.com/a/37576787/649299
for(let fieldName of _.keys(schema)) {
if (!user[fieldName] && schema[fieldName].onInsert) {
const autoValue = schema[fieldName].onInsert(user, options);
if (autoValue) {
if (typeof autoValue !== 'undefined') {
user[fieldName] = autoValue;
}
}
});
}
user = runCallbacks("users.new.sync", user);
runCallbacksAsync("users.new.async", user);
@ -45,7 +49,6 @@ function onCreateUserCallback (options, user) {
if (Users.hasCompletedProfile(user)) {
runCallbacksAsync("users.profileCompleted.async", user);
}
return user;
}