import SimpleSchema from 'simpl-schema'; import { ValidatedMethod } from 'meteor/mdg:validated-method'; const userSchema = new SimpleSchema({ username: { type: String, optional: true, max: 30, min: 4, }, emails: { type: Array, optional: true, }, 'emails.$': { type: Object, }, 'emails.$.address': { type: String, regEx: SimpleSchema.RegEx.Email, }, 'emails.$.verified': { type: Boolean, }, registered_emails: { type: Array, optional: true, }, 'registered_emails.$': { type: Object, blackbox: true, }, createdAt: { type: Date }, services: { type: Object, optional: true, blackbox: true, }, roles: { type: Array, optional: true, }, 'roles.$': { type: String }, // In order to avoid an 'Exception in setInterval callback' from Meteor heartbeat: { type: Date, optional: true, }, apiKey: { type: String, index: 1, optional: true, }, darkMode: { type: Boolean, optional: true, }, subscribedLibraries: { type: Array, defaultValue: [], max: 100, }, 'subscribedLibraries.$': { type: String, regEx: SimpleSchema.RegEx.Id, }, subscribedCharacters: { type: Array, defaultValue: [], max: 100, }, 'subscribedCharacters.$': { type: String, regEx: SimpleSchema.RegEx.Id, }, profile: { type: Object, blackbox: true, optional: true, }, }); Meteor.users.attachSchema(userSchema); Meteor.users.generateApiKey = new ValidatedMethod({ name: 'Users.methods.generateApiKey', validate: null, run(){ if(Meteor.isClient) return; var user = Meteor.users.findOne(this.userId); if (!user) return; if (user && user.apiKey) return; var apiKey = Random.id(30); Meteor.users.update(this.userId, {$set: {apiKey}}); }, }); Meteor.users.setDarkMode = new ValidatedMethod({ name: 'Users.methods.setDarkMode', validate: new SimpleSchema({ darkMode: { type: Boolean }, }).validator(), run({darkMode}){ if (!this.userId) return; Meteor.users.update(this.userId, {$set: {darkMode}}); }, }); Meteor.users.sendVerificationEmail = new ValidatedMethod({ name: 'Users.methods.sendVerificationEmail', validate: new SimpleSchema({ userId:{ type: String, optional: true, }, address: { type: String, }, }).validator(), run({userId, address}){ userId = this.userId || userId; let user = Meteor.users.findOne(userId); if (!user) { throw new Meteor.Error('User not found', 'Can\'t send a validation email to a user that does not exist'); } if (!_.some(user.emails, email => email.address === address)) { throw new Meteor.Error('Email address not found', 'The specified email address wasn\'t found on this user account'); } Accounts.sendVerificationEmail(userId, address); } }); Meteor.users.isAdmin = function(userId){ userId = this.userId || userId; let user = Meteor.users.findOne(userId); return user && user.roles.includes('admin'); } Meteor.users.canPickUsername = new ValidatedMethod({ name: 'Users.methods.canPickUsername', validate: userSchema.pick('username').validator(), run({username}){ if (Meteor.isClient) return; let user = Accounts.findUserByUsername(username); // You can pick your own username if (user && user._id === this.userId){ return false; } return !!user; } }); Meteor.users.setUsername = new ValidatedMethod({ name: 'Users.methods.setUsername', validate: userSchema.pick('username').validator(), run({username}){ if (!this.userId) throw 'Can only set your username if logged in'; if (Meteor.isClient) return; return Accounts.setUsername(this.userId, username) } }); Meteor.users.subscribeToLibrary = new ValidatedMethod({ name: 'Users.methods.subscribeToLibrary', validate: new SimpleSchema({ libraryId:{ type: String, regEx: SimpleSchema.RegEx.Id, }, subscribe: { type: Boolean, }, }).validator(), run({libraryId, subscribe}){ if (!this.userId) throw 'Can only subscribe if logged in'; if (subscribe){ return Meteor.users.update(this.userId, { $addToSet: {subscribedLibraries: libraryId}, }); } else { return Meteor.users.update(this.userId, { $pullAll: {subscribedLibraries: libraryId}, }); } } }); Meteor.users.findUserByUsernameOrEmail = new ValidatedMethod({ name: 'Users.methods.findUserByUsernameOrEmail', validate: new SimpleSchema({ usernameOrEmail:{ type: String, }, }).validator(), run({usernameOrEmail}){ if (Meteor.isClient) return; let user = Accounts.findUserByUsername(usernameOrEmail) || Accounts.findUserByEmail(usernameOrEmail); return user && user._id; } });