How to temporarily login a new user on register

Hi,
I’m trying to provide a register form where the user only needs to insert its email and then is initially logged in temporarily.

So far I have following flow
On the client, call a register method with the email, the method returns the temp password that is then used to login the user initially

var email = "foo@example.org"
Meteor.call("createUser", email, function(tempPassword){
  Accounts.loginWithPassword(email, tempPassword);
})

On the Server:

  1. Create a random password
  2. Create the user with the email and the password
  3. send the enrollment email
  4. return the temp password
Meteor.methods({
 createUser: function(email){
  var tempPassword = Random.secret(15)
  var userId =   Accounts.createUser({username : email, password: tempPassword, temp: true})
  Accounts.sendEnrollmentEmail(userId);
  return tempPassword;
}
})

And on the login of a temp user remove the initial password

Accounts.onLogin(function(option){

 Meteor.users.update(
   { _id: option.user._id, temp: true}, 
   {$unset : {temp: "", "services.password.bcrypt":""}})
})

A problem in this flow is that I send the password in plaintext back, I could do this with Accounts.createUser from the frontend but do you think it is a valid approach in general?

Thanks in advance
Max

1 Like

I thought Accounts.createUser automatically logs you in, why do you need the extra login call?

Yes this would work, I just would have to create the temp password on the client side, but do you think the delete the bcrypt password via update.({...}) is a valid approach to ensure that the user must access the application via the enrollment email the next time?

You don’t need a temporary password. You can just log in the user when you need it. And next time he/she will have to go through the link in the enrollment email, otherwise they have no password to log in with, of course.

Is that clear? Can you see if that works for you? So just create the user (let them automatically be logged in), send the enrollment email and that’s it. User is logged in for now, next time to log in they will need to go through the enrollment email as there is literally no other way for them, having never gotten another “temporary” password.
Notice that this approach is also common on other sites. The one with the temporary password is not. That means better or at least more familiar user experience, which is always a plus.

I am not sure I understand why they need to be temporarily logged in. You can use the services.password.reset.token on the enrolled user record to find that user.

Meteor.publish('enrolledUser', function (token) {
  var user = Meteor.users.find({ "services.password.reset.token": token });
  if (user.count() === 0) {
    this.error(404, "No patient with token");
  }
  return user;
});

EDIT:
I notice there’s also a setUserId in publications. You can probably make use of that.

Meteor.publish('enrolledUser', function (token) {
  var user = Meteor.users.find({ "services.password.reset.token": token });
  if (user.count() === 0) {
    this.error(404, "No patient with token");
    return;
  }
  this.setUserId(user._id);
  return user;
});
1 Like

@seeekr I’m not sure if I get you, since the Accounts.createUser on the client requires a password, hence I would need to create a temporary one.

@corvid the this.setUserId would work inside my createUser method in the combination with Meteor.connection.setUserId on the client side if my createUser call returns the new userId, I would not need the reset token for that.
See https://dweldon.silvrback.com/impersonating-a-user but as soon the user refreshes the page it’s gone

Is there any particular reason why you can’t just call a Meteor method and execute the Accounts.createUser on the server? Because that’s what I meant you could do, that’s what I was thinking of.

@seeker but createUser on the server side does not login the user, does it?

i tried this code.
But it gave me error mentioning that loginWithPassword is not a function.
What could be the reason ?

does Account.createUser automatically logs in a user?
For me After the call, I am using user._id on server which returns undefined
and on client , Meteor.userId() returns null.

can someone explain the flow from client to server and back with access to userId?