4
votes

I am building a custom authentication system using accounts-password in meteor. My question is why when i remove the default hash that meteor provides for reset password links i do also lose my resetPasswors token session? So far i have this code but im not able to access the condition in my template to change my password. Seems like something wrong when setting up a custom reset password route.

router.js

Router.route('/reset-password', {name: 'resetPassword'});

Router.route('/reset-password/:token', function () {
  this.render('resetPassword');
});

reset_password.html

<template name="resetPassword">
  <div class="reset-container">
    {{#if resetPassword}}   
      <form class="reset-password">
        <div class="form-group">
          <label for="password" class="control-label">New password</label>
          <input type="password" name="password" class="form-control"
            title="Please enter a new password" id="password" placeholder="Password">
          <span class="help-block small"> Your strong password</span> 
        </div>
        <input type="submit" class="btn btn-success btn-block" value="Reset password">   
      </form>               
    {{else}}
      <form class="forgot-password">
        <div class="form-group">
          <label for="email" class="control-label">Email</label>
          <input type="text" name="email" class="form-control"
            title="Please enter your email" id="email" placeholder="[email protected]">
          <span class="help-block small"> Your unique email address</span>   
        </div>
        <input type="submit" class="btn btn-success btn-block" value="Send instructions!">   
      </form>           
    {{/if}}
  </div>
</template>

reset_password.js

if (Accounts._resetPasswordToken) {  
  Session.set('resetPasswordToken', Accounts._resetPasswordToken);
}

Template.resetPassword.helpers({  
  resetPassword: function() {
    return Session.get('resetPasswordToken');
  }
});

Template.resetPassword.events({  
  "submit .forgot-password": function(event) {
    // Prevent default browser form submit
    event.preventDefault();

    // Get value from form element
    email = event.target.email.value;

    if (email) {
      Accounts.forgotPassword({email: email}, function (error) {
        if (error) {
          if (error.message === 'User not found [403]') {
            throwAlert('This email address does not exist.', 'danger');
          } else {
          throwAlert('We are sorry but something went wrong.', 'danger');
          }
        } else {
          throwAlert('We have sent you an email with basic instructions to reset your password.', 'success');
        }
      });
    } else {
      throwAlert('Your email address cannot be empty.', 'danger');
    }
  },
  "submit .reset-password": function (event) {
    // Prevent default browser form submit
    event.preventDefault();

    // Get value from form element
    password = event.target.password.value;

    // If the password is valid, we can reset it.
    if (password) {
      Accounts.resetPassword(Session.get('resetPasswordToken'), password, function (error) {
        if (error) {
          throwAlert('We are sorry but something went wrong.', 'danger');
        } else {
          throwAlert('Your password has been changed. Welcome back!', 'success');
          Session.set('resetPasswordToken', null);
          Router.go('postsList');
        }
      });
    } else {
      throwAlert('Your password cannot be empty. Create a good one!', 'danger');
    }
  }
});

server/config.js

Meteor.startup(function() {
  Accounts.emailTemplates.resetPassword.text = function(user, url) {
    var token = url.substring(url.lastIndexOf('/') + 1, url.length);
    var newUrl = Meteor.absoluteUrl('reset-password/' + token);
    var str = 'Hello, \n';
        str+= 'Click on the following link to reset your password \n';
        str+= newUrl;
    return str;
  };
});
1

1 Answers

3
votes

same, i do:

  this.route('password.reset', {
     path: '/password/reset/:token',
     onBeforeAction: function() {
        Accounts._resetPasswordToken = this.params.token;
        this.next();
     },
     template: 'resetPassword'
  });

and move the if(Accounts._resetPasswordToken) in the onCreated

Template.resetPassword.onCreated(function() {
   if(Accounts._resetPasswordToken) {
    Session.set(RESET_PASSWORD, Accounts._resetPasswordToken);
   }
  ...