How to use Accounts.onResetPasswordLink with React?

I have this in a client-side JS file:

Accounts.onResetPasswordLink(function (token, done) {
  // 1. ????
  // 2. Accounts.resetPassword(token, 'new pass');
  // 3. profit
});

But it’s not really clear (especially in React) how to render out a password reset form. I can use FlowRouter:

Accounts.onResetPasswordLink(function (token, done) {
  FlowRouter.go(routes.ROUTE_RESET, { token });
});

But the problem is that I can’t pass the done function via FlowRouter. If anyone could point me in the right direction, I’d appreciate it!

A bit hacky, but this is my workaround for now:

Accounts.onResetPasswordLink(function (token, done) {
  global.resetCallback = done;
  Session.set('emailResetRequest', true);
});

And then in my React Meteor container, I’m passing Session.get('emailResetRequest') into my component and if it’s true, it pops up a dialog to allow the user to input their new password.

I think that’s not hacky, at least setting a local state (Session.set(‘emailResetRequest’, true):wink: and then using the layout to show a reset-password screen, when this state is set.

I did the same, but i ignored the done-callback and it seems to work. Not sure, if it is really needed.

Yeah, I’m not really sure what that callback does. IMO the documentation is unclear: (emphasis mine)

done: A function to call when the password reset UI flow is complete. The normal login process is suspended until this function is called, so that the password for user A can be reset even if user B was logged in.

I’m not really sure what user B has to do with user A resetting their password.

@sashko added it here: https://github.com/meteor/meteor/commit/b1f7132454391baf2788581b23a56e2133e45dff#diff-9e94fdc9869e15279642f7d64ce426dcR103 in 2014.

It looks like a very uncommon scenario:

  1. You are logged in with your account A.
  2. You request a password change for account B (which most interfaces won’t let you do anyway).
  3. Then you open the link yourself (while still logged in on account A) and you enter your new password etc.
  4. When done you are still logged in under account A but the password for B has changed.

Very strange when thinking about it but maybe it has a use-case.

I did the same, but i ignored the done-callback and it seems to work. Not sure, if it is really needed.

That may make sense:

The normal login process is suspended until this function is called

It seems this functionality is somehow related to the login process. I assume that if your are handling this password reset process while https://docs.meteor.com/api/accounts.html#Meteor-loggingIn === true you may encounter some issues but this is all not very likely.

Yeeeeeeeah, I’m not really sure that this “feature” or Meteor adds anything except complexity. But that’s how it was, so I just documented it and made public APIs.

The idea is, let’s say someone borrowed your computer and logged in to their account. Then you open a password reset link. It would be weird if it went to a page where your friend is logged in.

But I think that’s a relatively small edge case. I don’t think this is something we could remove at this point without breaking lots of stuff.

1 Like

Thanks for the clarification! @sashko, if there’s a better way to handle this than what I’m doing (see second post), let me know!

The way I’ve been doing is having a server side file like this:

import { Accounts } from 'meteor/accounts-base';
import { Meteor } from 'meteor/meteor';

  Accounts.urls.resetPassword = function reset(token) {
    return Meteor.absoluteUrl('reset-password/' + token);
  };

Then, in my router (I use React Router), I set up a route/custom page for that link.

1 Like

Well, I learned some new stuff here! Accounts.urls appears to be undocumented, but it is in the Meteor Guide. Very cool. I also didn’t know about Meteor.absoluteUrl! Now I can get rid of my Meteor.settings.public.baseUrl.

Thanks!

2 Likes

That’s about what we are doing: https://github.com/meteor/meteor/blob/abd574f38008b45f5e2a6bc322b10bcdde44763a/packages/accounts-ui-unstyled/login_buttons_dialogs.js#L4-L27

I always forget to document how I do it all the time. Going to try this immediately.

Yes, setting a custom url and then creating that page and using router is the best way to handle this.