I have created a user profile using simple schema and collection2. If the name or email address is updated I want to update the meteor user profile. When I try to set the email address in the meteor user profile it won't update. This is the offending line:
Meteor.users.update(Meteor.userId(), {$set: {emails[0].address: pDetails.contactDetails.email}});
Can anyone show me how to update the meteor user profile?
Thank you.
You need to select the array element based on the previous email address value in your selector.
Meteor.users.update({ _id: Meteor.userId(), 'emails.address': oldAddress },
{ $set: { 'emails.0.address': newAddress }});
You may have to set the verified field to false at the same time if the new email address is not verified. Then send the email verification email.
This also worked:
Meteor.users.update(Meteor.userId(), {$set: {'emails.0.address': pDetails.contactDetails.email, 'profile.name': pDetails.contactDetails.firstName}});
Related
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'}})
The only way I have found to delete user accounts in meteor (other than emptying the database with mrt reset), is by actually logging into that specific user account, and deleting the account from the console, using:
Meteor.users.remove('the user id');
But like I said, I need to be logged in as that specific user, and have not been able to find a solution which enables me to delete any user from the db. I'm sure it has something to do with permissions or roles, but I am not sure how to proceed / what is the best solution / how to set an administrative role for a particular user, so that I can delete different user accounts.
You could do
meteor mongo
or
meteor mongo myapp.meteor.com for a deployed app
Then
db.users.remove({_id:<user id>});
I wouldn't recommend it but if you want to delete any user without being logged in from meteor you would need to modify the allow rules. But deleting a user is a very unlikely event hence the above might be the best way to do it.
Anyway if you do want, modify the Meteor.users.allow({remove:function() { return true }); property. See http://docs.meteor.com/#allow. You could add in some custom logic there so it'll only let you do so if you're the admin
I was having trouble doing this on nitrous.io because I couldn't open both Meteor and Mongo. I put:
Meteor.users.remove(' the _id of the user ');
in the isServer section to remove the user.
If anyone is still looking for an answer to this question, I have outlined my solution below.
When I create a new user, I add a field called role in my user document. If I want a user to be able to remove other users from the Meteor.users collection, I give him a role of administrator. If not, I give him a role of member. So, my user document looks something like this -
{
"_id" : ...,
"createdAt" : ...,
"services" : {...},
"username" : "test",
"profile" : {
"name" : "Test Name",
"role" : "administrator"
}
}
On the client, I have a list of users (added using a #each template tag) with a remove button next to each user. A user has to login to see this list. I defined an event handler for the remove button -
'click #remove-user-btn': function () {
Meteor.users.remove({ _id: this._id }, function (error, result) {
if (error) {
console.log("Error removing user: ", error);
} else {
console.log("Number of users removed: " + result);
}
})
}
However, Meteor.users does not allow remove operations from the client by default. So, you have to edit the Meteor.users.allow callback in the server as shown below to allow the users to be removed from the client side. But we need to make sure that only a user with an administrator role is allowed this privilege.
Meteor.users.allow({
remove: function (userId, doc) {
var currentUser, userRole;
currentUser = Meteor.users.findOne({ _id: userId }, { fields: { 'profile.role': 1 } });
userRole = currentUser.profile && currentUser.profile.role;
if (userRole === "administrator" && userId !== doc._id) {
console.log("Access granted. You are an administrator and you are not trying to delete your own document.");
return true;
} else {
console.log("Access denied. You are not an administrator or you are trying to delete your own document.");
return false;
}
},
fetch: []
});
This is the general idea. You can build upon this to suit your needs.
Here are the steps to delete user from mongo through console:
step 1: open new console
step 2: change diretory to your app such as (cd myapp)
step 3 : enter command meteor mongo
step 4: make sure there exists a table called users, db.users.find({});
step 5: find the userid of the user you wish to delete and type :
db.users.remove({_id:"nRXJCC9wTx5x6wSP2"}); // id should be within quotes
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.
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)
}
});