How to add extra attributes to users collection? - meteor

I am using Accounts.createUser to add new users to the database, but the problem is that, not all the attributes are added.
Here is my code to add new user:
import {Accounts} from 'meteor/accounts-base';
Template.addingUser.events({
'submit #addUser': function (e, t) {
e.preventDefault();
Session.set('name', t.find('#name').value);
Session.set('email', t.find('#email').value);
Session.set('telephoneOffice', t.find('#telephoneOffice').value);
Session.set('telephoneHouse', t.find('#telephoneHouse').value);
Session.set('salary', t.find('#salary').value);
let userId = Accounts.createUser({
username: Session.get('name'),
password: "123456",
email: Session.get('email'),
telephoneOffice: Session.get('telephoneOffice'),
telephoneHouse: Session.get('telephoneHouse'),
employeeSalary: Session.get('salary'),
annualLeave: 14
}, function (err) {
if (err)
console.log(err);
else
console.log('It worked...');
});
Accounts.sendEnrollmentEmail(userId);
}
});
only the name, email, and password are added.
How do I include the other information as well such as telephoneOffice?

You need to pass the extra data inside the profile object.
Accounts.createUser({
username: Session.get('name'),
password: "123456",
email: Session.get('email'),
profile: {
telephoneOffice: Session.get('telephoneOffice'),
telephoneHouse: Session.get('telephoneHouse'),
employeeSalary: Session.get('salary'),
annualLeave: 14
}
...

Accounts.createUser does not accept custom arguments beyond username, email, password, and profile. The default functionality for passing custom user info is to pass those fields such as telephoneOffice as part of the profile object, which is copied to user.profile in the document inserted to the user collection.
For example:
let userId = Accounts.createUser({
username: Session.get('name'),
password: "123456",
email: Session.get('email'),
profile: {
telephoneOffice: Session.get('telephoneOffice'),
telephoneHouse: Session.get('telephoneHouse'),
employeeSalary: Session.get('salary'),
annualLeave: 14
}
});
Note that the user.profile fields are by default modifiable by users. So it's there by legacy, but Meteor actually recommends avoiding using it for storage.
If you want those fields to be on user instead of user.profile, What you can do is to pass your custom params on the profile object as above, and then override the default behavior using Accounts.onCreateUser. Something like this:
Accounts.onCreateUser(function(options, user) {
if (options.profile)
_.extend(user, options.profile);
return user;
});
See more info here: https://guide.meteor.com/accounts.html#custom-user-data

Related

how to allow the same username but different company registration?

in Meteor, how to allow the same username but different company registration?
i want to set username with unique: false
how to custom Accounts package?
accounts_server.js
users._ensureIndex('username', { unique: true, sparse: true });
Having a unique username across your system has strong reasons, especially integrity and validation. Circumventing this functionality can lead to potential risks and may undermine the stability of the accounts packages as they are built around the assumption, that users are unique by username or email.
You can see that in the source, where Accounts.createUser is checking for unique usernames and emails, independently from the raw Mongo collection.
If you still insist to override this behavior (which I highly suggest to not to), you need to do everything manually (validation not included here):
import { Meteor } from 'meteor/meteor'
const createUser = ({ username, password, company }) => {
if (Meteor.users.find({ username, company }).count() > 0) {
throw new Error(`Account already exists for ${username}#${company}`)
}
const userId = Meteor.users.insert({ username, company })
Accounts.setPassword(userId, password)
return userId
}
Meteor.startup(() => {
Meteor.users.rawCollection().dropIndex('username_1')
Meteor.setTimeout(() => {
createUser({ username: 'johndoe', password: 'password', company: 'Software Inc.' })
createUser({ username: 'johndoe', password: 'password', company: 'Pro Software' })
}, 1000)
})
by doing so you need to override all Accounts methods (especially authentication and login) with your own implementation. However, as I said - better don't do it.
Better solution: Use Email instead
The combination of username and company name is already incorporated in the email pattern.
The easiest solution would therefore be to implement accounts based on email, rather than on the username:
const createUser = (email, password, company) => {
const userId = Accounts.createUser({ email, password })
Meteor.users.update(userId, { $set: { company }})
return userId
}

How can I add new field to Meteor.users()?

I have a button that inserts new user to Meteor.users().
In the server I have this method:
Meteor.methods({
'addUser': function(user) {
return Accounts.createUser(user)
}
})
And in the client (After button is clicked):
var newUser = {
email: t.find('#email').value,
password: t.find('#pwd').value,
profile: { name: t.find('#name').value, group: t.find('#userType').value },
roles: checkedRoles // I can successfully console.log(checkedRoles) which is an array of strings.
}
Meteor.call('addUser', newUser, function(error){
if(error){
sweetAlert(error)
} else {
sweetAlert('User Successfully Added')
}
})
Using the above code, the user is added but without the roles field.
My question is, how can I add the roles field to the newly added user?
Use alanning:roles package:
meteor add alanning:roles
then (in your server side method):
const userId = Accounts.createUser(user);
Roles.addUsersToRoles(userId, user.roles);

How to get user ID during user creation in Meteor?

I am creating default users on the server with a Meteor startup function. I want to create a user and also verify his/her email on startup (I'm assuming you can only do this after creating the account).
Here's what I have:
Meteor.startup(function() {
// Creates default accounts if there no user accounts
if(!Meteor.users.find().count()) {
// Set default account details here
var barry = {
username: 'barrydoyle18',
password: '123456',
email: 'myemail#gmail.com',
profile: {
firstName: 'Barry',
lastName: 'Doyle'
},
roles: ['webmaster', 'admin']
};
// Create default account details here
Accounts.createUser(barry);
Meteor.users.update(<user Id goes here>, {$set: {"emails.0.verified": true}});
}
});
As I said, I assume the user has to be created first before setting the the verified flag as true (if this statement is false please show a solution to making the flag true in the creation of the user).
In order to set the email verified flag to be true I know I can update the user after creation using Meteor.users.update(userId, {$set: {"emails.0.verified": true}});.
My problem is, I don't know how to get the userID of my newly created user, how do I do that?
You should be able to access the user id that is returned from the Accounts.createUser() function:
var userId = Accounts.createUser(barry);
Meteor.users.update(userId, {
$set: { "emails.0.verified": true}
});
Alternatively you can access newly created users via the Accounts.onCreateUser() function:
var barry = {
username: 'barrydoyle18',
password: '123456',
email: 'myemail#gmail.com',
profile: {
firstName: 'Barry',
lastName: 'Doyle'
},
isDefault: true, //Add this field to notify the onCreateUser callback that this is default
roles: ['webmaster', 'admin']
};
Accounts.onCreateUser(function(options, user) {
if (user.isDefault) {
Meteor.users.update(user._id, {
$set: { "emails.0.verified": true}
});
}
});

No response from Jquery validation when creating Meteor account

Basically, I'm using Jquery validation package as a way to alert errors to users when creating and registering accounts on Meteor, since the boilerplate interface doesn't work in my case.
Anyway, when a user tries to sign up for an account, I get no response at all on client. The user is just created with no message or redirection like it's supposed to have.
Here is the particular code:
Template.createAccount.onRendered(function(){
var validator = $('.register').validate({
submitHandler: function(){
user = {
email: document.getElementById("email").value,
password: document.getElementById("password").value
};
Accounts.createUser({
email: user.email,
password: user.password,
function(error){
if(error){
if(error.reason == "Email already exists."){
validator.showErrors({
email: "The email belongs to a registered user."
});
}
} else{
console.log("Account successfully created.");
Router.go("starter");
}
}
});
}
});
})
I'm using the same code logic for account logins with the only exception being a different meteor accounts function (Meteor.loginWithPassword() for login and Accounts.createUser() for account creation).
No response at all, so it probably has to do something with the callback function, since the user account is created, but no message displayed on client.
You're including your callback as part of your options object when it should be a separate argument. It should look more like this:
Accounts.createUser({
email: user.email,
password: user.password
}, function(error){
if(error){
if(error.reason == "Email already exists."){
validator.showErrors({
email: "The email belongs to a registered user."
});
}
} else{
console.log("Account successfully created.");
Router.go("starter");
}
});

How would I use Accounts.createUser in Meteor once, at first load, and then persist

I have thought of somehow using session, but that doesn't make much sense to me with a user that I always want to exist, and not be created over and over.
My issue is after a page refresh I get an error saying user already exists, I would like to know how to create a permanent user once.
This is in my server code.
Accounts.createUser({
username: "admin",
password: "password"
});
Try this.
Meteor.startup(function () {
if (Meteor.users.find().count() === 0) {
Accounts.createUser({
username: 'admin',
email: 'admin#admin.com',
password: 'password'
});
console.log('created user');
}
});

Resources