In the new Meteor auth branch how can I create users server side?
I see how to create them client side with the call to
[Client] Meteor.createUser(options, extra, callback)
But suppose I want to create a Meteor user collection record on startup?
For example, the Administrator account during startup/bootstrapping for an application?
Thanks
Steeve
On newer versions of meteor use
Accounts.createUser({
username: username,
email : email,
password : password,
profile : {
//publicly visible fields like firstname goes here
}
});
note: the password hash is generated automatically
On older versions of meteor use:
1 - NB: DO YOU HAVE THE REQUIRED PACKAGES INSTALLED ?
mrt add accounts-base
mrt add accounts-password
On some versions of meteor you cannot call SRP password salt generator as Steeve suggested, so try this:
2 - do Meteor.users.insert( )
e.g.
var newUserId =
Meteor.users.insert({
emails: ['peter#jones.com'],
profile : { fullname : 'peter' }
});
note: a user must have EITHER a username or an email address. I used email in this example.
3 - Finally set the password for the newly created account.
Accounts.setPassword(newUserId, 'newPassword');
Probably it's a well known fact now, but for the sake of completing this - there's a new server API for doing this on the auth branch. From the docs on auth:
" [Server] Meteor.createUser(options, extra) - Creates a user and
sends that user an email with a link to choose their initial password
and complete their account enrollment
options a hash containing: email (mandatory), username (optional)
extra: extra fields for the user object (eg name, etc). "
Please note the API is subject to change as it's not on the master branch yet.
For now this has been suggested in the meteor-core google group.
Meteor.users.insert({username: 'foo', emails: ['bar#example.com'], name: 'baz', services: {password: {srp: Meteor._srp.generateVerifier('password')}}});
It works. I tested it in during startup/boot strap.
I would not consider this the permanent or long term answer because I believe the auth branch is still in a great degree of change and I imagine the team behind Meteor will provide some kind of functionality for it.
So, do not depend on this as a long term answer.
Steeve
At the moment, I believe you cannot. Running
Meteor.call('createUser', {username: "foo", password: "bar"});
comes close, but the implementation of createUser in passwords_server.js calls this.setUserId on success, and setUserId cannot be called on the server unless we're in a client-initiated method invocation (search for "Can't call setUserId on a server initiated method call" in livedata_server.js.
This does seem like something worth supporting. Perhaps the last three lines of createUser, which log the user in, should be controlled by a new boolean login option to the method? Then you could use
Meteor.call('createUser', {username: "foo", password: "bar", login: false});
in server bootstrap code.
I've confirmed that the following code in my server/seeds.js file works with the most recent version of Meteor (Release 0.8.1.1)
if (Meteor.users.find().count() === 0) {
seedUserId = Accounts.createUser({
email: 'f#oo.com',
password: '123456'
});
}
Directory (or folder) of server means I'm running the code on the server. The filename seeds.js is completely arbitrary.
The official documentation now describes both the behavior for Accounts.createUser() when run on the client and when run on the server.
Working coffeescript example for Meteor version 1.1.0.2 (server side):
userId = Accounts.createUser
username: 'user'
email: 'user#company.com'
password: 'password'
profile:
name: 'user name'
user = Meteor.users.findOne userId
I struggled for some time with this API getting 'User already exists' exception in working code before adding profiles.name to the options and exception disappeared.
reference: Accounts.createUser(options,[callback])
Create user from server side
// Server method
Meteor.methods({
register: function(data) {
try {
console.log("Register User");
console.log(data);
user = Accounts.createUser({
username: data.email,
email: data.email,
password: data.password,
profile: {
name: data.email,
createdOn: new Date(),
IsInternal: 0
}
});
return {
"userId": user
};
} catch (e) {
// IF ALREADY EXSIST THROW EXPECTION 403
throw e;
}
}
});
// Client call method
Meteor.call('register',{email: "vxxxxx#xxxx.com",password: "123456"}, function(error, result){
if(result){
console.log(result)
}
if(error){
console.log(result)
}
});
Related
I want to publish some limited user information about my users, the idea is that the admin role of my web app can view the emailaddress and username (last one is in the profile data).
Meteor.publish("usersSpecificDataforAdmin", function () {
return Meteor.users.find({}, {fields: {
'profile': 1,
'emails': 1,
'roles': 1
}});
});
I'm then subscribing to this in my router:
adminRoutes.route('/users', {
name: 'adminUsersList',
subscriptions: function (params, queryParams) {
this.register('adminUsersList', Meteor.subscribe('usersSpecificDataforAdmin'));
},
action: function (params, queryParams) {
BlazeLayout.render('layout_frontend', {
top: 'menu',
main: 'adminUsersList',
footer: 'footer'
});
}
});
In the template, I'm using the following to display the email address of the user: '{{emails.address}}', but that doesn't work. I can display all other info.
I have following questions:
how can I display the email address of the user in the template
even when I don't add the password or services fields in the publishing, it is send to the client (doing Meteor.user()) is revealing all the info, including passwords etc, which is a security issue in my opinion. How can I disable the publication of this?
Several things:
You don't need to include _id in the list of fields to be published, it is always included
You're publishing allUserData but your router code is subscribing to usersAllforAdmin which you're not showing code for. I suspect that publication is including services
Passwords are not stored anywhere in Meteor, only the bcrypt hash of the password is stored in services
emails is an array, you can't access it with {{emails.address}} in spacebars, instead use {{emails.[0].address}} (reference)
I have a Meteor project where users need to confirm their email address before they can login.
When the Meteor.user collection is empty I create a default admin user:
Meteor.startup(function () {
if (Meteor.users.find().count() === 0 ) {
Accounts.createUser({
username: 'admin',
email: 'me#domain.com',
password: 'admin',
profile: {
role: 'admin'
}
});
}
});
Even though the user has been created automatically, the user still needs to verify its email address.
How can I automatically set verified to true for this user?
I have fixed it by using:
Meteor.users.update(user._id, { $set:
{
"emails.0.verified": true
}
});
You need to update that user document to set emails[0].verified to true. That account will be verified but the accounts package will still send out an email asking the user to verify their email address.
Dude, you can add something like this which searches for the username and assigns value according to the db schema you follow for verification (Meteor.users.find({username: 'admin'}).fetch(), ['set your verified to true']);
Something similar is used to assign admin property to user in Allaning:Roles. Check that out for better understanding.
I have basic project in Meteor created from Meteor-admin stub: (https://github.com/yogiben/meteor-admin)
I need to display avatars for all users, not only current one.
For displaying user's avatar I need his email address. (I am using utilities:avatar https://atmospherejs.com/utilities/avatar)
Question: what adjustments to project should I make to be able to access other users' data?
It probably has something to do with publishing users.
At the moment I have:
{{> avatar user=getAuthor shape="circle" size="small"}}
getAuthor: ->
console.log 'Owner:'
console.log #owner
user = Meteor.users.findOne(#owner)
console.log user
user
This correctly prints Owner: #owner (id) for all users, but user object is only populated for current user.
I also have this code in server-side:
Meteor.publishComposite 'user', ->
find: ->
Meteor.users.find _id: #userId
children: [
find: (user) ->
_id = user.profile?.picture or null
ProfilePictures.find _id: _id
]
(children / ProfilePicture are irrelevent)
I think account-base library turns publishing off or something? Thanks for help!
Bonus question: I would like to access only some info about an user (email address).
If you remove the package autopublish, you need to specify explicitly what the server sends to the client. You can do this via Meteor.publish and Meteor.subscribe.
For instance, to publish the email addresses of all users you could do:
if (Meteor.isServer) {
Meteor.publish('emailAddresses', function() {
return Meteor.users.find({}, {
fields: {
'email': 1
}
});
});
}
After that, you need to subscribe to the publication on the client:
if (Meteor.isClient) {
Meteor.subscribe("emailAddresses");
}
Read more about Meteor's publish and subscribe functionality.
Having collection: Meteor.users
To access other users data just publish it on the server-side:
Meteor.publish 'userData', ->
Meteor.users.find()
On client side you don't have to use any userData reference. Just access it:
Meteor.users.findOne(someId)
To allow access to only specific information, publish it with fields parameter:
Meteor.publish 'userData', ->
Meteor.users.find({},{fields: {'_id', 'emails', 'username'}})
I'm using accounts-password package - Meteor.
I code interface for admin.
Admin will create accounts for other user.
Accounts.createUser({
email: "abc#gmail.com",
password : "abc123",
profile: { name: register_name }
});
But after this code executed, my application automatic login with account abc#gmail.com, wich i don't want it
Question
How to create accounts without automatic login?
I read accounts-password source but i dont know how to remove automatic login
I also tried to use Meteor.users.insert function but Accounts.setPassword didn't work..
This is a normal behavior using accounts package, to avoid messing with the source code use a Meteor.method/Meteor.call.
This is a simple example,also you can use the default username filed and not a profile:{name:register_name}.
if(Meteor.isServer){
Meteor.methods({
createUserFromAdmin:function(emai,password,username){
Accounts.createUser({email:email,password:password,username:username})
}
})
}else if(Meteor.isClient){
Template.admin.events({
'click #createAccount':function(){
Meteor.call('createUserFromAdmin',email,password,username,function(err,result){
if(!err){
console.log("a new user just got created")
}else{
console.log("something goes wrong with the following error message " +err.reason )
}
})
}
})
}
With this you can create multiple accounts on the admin template, and keep the autologin behavior on the sign-up template (if you have one)
I would like to create a user in my fixture and to be able to sign in as that user. For this reason, I need to somehow set the password of the user (if I try to sign in without a password, I get a 'User has no password set' validation error).
So far I only have:
var joeId = Meteor.users.insert({
username: 'joe'
})
Meteor complains about "Error: Accounts.createUser with callback not supported on the server yet." as of Meteor 0.6.4 if trying to create user on server side fixtures.
Just add the following after creating Joe:
Accounts.setPassword(joeId, 'my great password')
Using http://docs.meteor.com/#accounts_createuser you can do this:
Accounts.createUser({
'username' : 'John Doe',
'email' : 'john#doe.com',
'password' : 'abc123' //encrypted automatically
}, function(err){
if(typeof err === 'undefined'){
//account created successfully you might want to send an email to the user using Account.sendEnrollmentEmail()
}
});
Which will login with that user on successful creation.