This is what we use:
import { Meteor } from 'meteor/meteor';
import SimpleSchema from 'simpl-schema';
Meteor.users.allow({
insert: () => false,
update: () => false,
remove: () => false,
});
Meteor.users.deny({
insert: () => true,
update: () => true,
remove: () => true,
});
export const UserUpdate = new SimpleSchema({
userId: { type: String },
userAction: { type: String },
userInformation: { type: Object, blackbox: true },
});
const UserSchema = new SimpleSchema({
emails: { type: Array, optional: true },
'emails.$': { type: Object, optional: true },
'emails.$.address': { type: String, regEx: SimpleSchema.RegEx.Email, optional: true },
'emails.$.verified': { type: Boolean, optional: true },
'emails.$.primary': { type: Boolean, optional: true },
createdAt: { type: Date, optional: true },
profile: { type: Object },
'profile.name': { type: Object },
'profile.name.first': { type: String },
'profile.name.last': { type: String },
services: { type: Object, optional: true, blackbox: true },
roles: { type: Object, optional: true, blackbox: true },
// your other stuff can go here
'status': { type: Object, optional: true, blackbox: true } // to track user, so if away, can logout
});
Meteor.users.attachSchema(UserSchema);
And a method could look like so:
export const insertUser = new ValidatedMethod({
name: 'user.insert',
validate: new SimpleSchema({
email: { type: String },
password: { type: String },
profile: { type: Object },
'profile.name': { type: Object },
'profile.name.first': { type: String },
'profile.name.last': { type: String },
roles: { type: Object, blackbox: true, optional: true },
userEntitySettings: { type: Object, optional: true, blackbox: true },
userPersonalSettings: { type: Object, optional: true, blackbox: true },
'status': { type:Object, optional: true, blackbox: true },
}).validator(),
async run({ email, password, profile, roles, userEntitySettings, userPersonalSettings }) {
if (Meteor.isServer) {
const userId = await Accounts.createUser({ email, password, profile });
if (userId) {
// NOTE: set primary email so emails work properly
Meteor.users.update({ _id: userId }, { $set: { 'emails.0.primary': true } });
if (roles) {
Roles.addUsersToRoles({ _id: userId }, roles.type, roles.group);
}
if (userEntitySettings) {
Meteor.users.update({ _id: userId }, { $set: { userEntitySettings: userEntitySettings } });
}
if (userPersonalSettings) {
Meteor.users.update({ _id: userId }, { $set: { userPersonalSettings: userPersonalSettings } });
}
}
return userId;
}
},
});
In below method, i’m using the update to validate.
export const updateUserGeneralSettings = new ValidatedMethod({
name: 'userGeneralSettings.update',
validate: UserUpdate.validator(),
async run ({ userId, userAction, userInformation }) {
if (Meteor.isServer) {
switch (userAction) {
case ('setUGSprofile'): {
let setModifier = { $set: {} };
setModifier.$set[
'profile.name.' + userInformation.option
] = userInformation.value;
return await Meteor.users.update(userId, setModifier);
}
case ('updatePassword'): {
return await Accounts.setPassword(userId, userInformation.password, { logout: false });
}
case ('addRole'): {
return await Roles.addUsersToRoles(userId, userInformation.role, userInformation.group);
}
case ('subRole'): {
return await Roles.removeUsersFromRoles(userId, userInformation.role, userInformation.group);
}
default:{
throw new Meteor.Error(
'userGeneralSettings.update.failure',
`Method ${userAction} was not recognized...`,
);
}
}
}
}
});
Hopefully this helps. Was super annoying for me to work it out originally too.