-
Notifications
You must be signed in to change notification settings - Fork 414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Iron-router swallows Accounts.sendEnrollmentEmail #3
Comments
iron-router doesn't deal with hashbang urls yet. Does accounts-ui use the hashbang url to open the dialog? |
As a short-term solution, you could create your own enroll account route and handle that route by manually calling the enroll account method on Meteor. |
So I've got this working like this: Router file:
And a server file that overrides the urls with # paths that Meteor creates, so that the Iron-Router can work:
|
@samhatoum, Awesome. Glad you got this working in the short-term. Was this an issue with support a hash url? Curious because it will impact how we end up supporting IE<10. |
Yep it was. If you look at the Accounts.urls.* methods in the last code snip, that's where I've forced Meteor to create paths without #'s when constructing links for the mail shots. |
Hey @samhatoum, See my comment on the reference above. I think this issue has been fixed now. Instead of wiping out the html body (along with the accounts-ui dialogs) now the router appends to the body. |
I'm on 0.5.4 and cannot grab the token from a /#/reset-password/token URL. If I change the URL to /reset-password/token I can grab it just fine. Is the reference to a fix above referring only to the append to body, and not to the /#/ issue? ... and I need to apply a workaround like Sam's? Please confirm. |
@dgtlife do you by any chance have the HTML5-History package or the 'page-ie-support' package in your .packages file ? If so, i had to remove those packages as they were removing the '/#/' from the URL |
Ignore my last comment, i was confused about the rendering versus supporting of '/#/' urls which i believe is not supported yet @cmather ? |
Hey @dgtlife, I thought this was working for me a few weeks ago when I tried it out. I'll take a closer look after this next round of improvements on the rendering branch. I'll make sure to test this case. |
Thanks @cmather. As background, here is my list of packages: standard-app-packages I've currently deployed an override of the Meteor URLs to remove "#/" and everything works fine. |
Hi, just wanted to let you know that other users keep having this issue. http://stackoverflow.com/questions/19112450/meteor-account-email-verify-fails-two-ways/ |
Hey guys I'm pretty sure this is fixed on dev. It just hasn't been released yet. If it still isn't working for you on the dev branch let me know. Actually, let me know either way :-). PS - Thanks for the link to SO. I had missed that. |
To be more clear, to test this scenario I did the following:
I pasted this url: 'http://localhost:3000/#/enroll-account/uC537KPMJ5ojPwzeF' into the browser. The accounts-base package properly sees the hash, and sets the proper Accounts reactive variable which causes the dialog box to open. |
Hmmm... I don't use accounts-ui, but I do use accounts-base, and accounts-password. Here's what's in my packages file: standard-app-packages
preserve-inputs
accounts-base
accounts-facebook
accounts-google
accounts-twitter
accounts-password
amplify
email
http
spiderable
underscore
jquery-validation
moment
bootstrap-3
iron-router My tests basically involve console logging the token in the Route Controller function to see if it is properly parsed out. I tried with dev (4818286), inherit-handles (4129706), and initial-state (9418fbd). For me, dev is completely broken; it does not render anything but
With the other two, both fail to parse out the token with '/#/enroll-account/...', but pass with '/enroll-account/...'. This is how I have had the routes and controller that I use with the overridden Accounts.urls.enrollAccount function: this.route('enrollAccount', {
path: '/enroll-account/:token',
controller: 'SetPasswordController'
});
...
this.route('setPassword', {
path: '/set-password/:token',
controller: 'SetPasswordController'
});
...
SetPasswordController = RouteController.extend({
run: function () {
var setPasswordToken = this.params.token;
Session.set('setPasswordToken', setPasswordToken);
console.log(setPasswordToken);
this.render('setPassword');
}
}); The above works fine with master (0.5.4) and the other commits, but not with dev, since dev appears to be currently hosed. By "works" I mean that if I use (paste in and hit Enter) a tokenized url without the '/#' as in '/enroll-account/uC537KPMJ5ojPwzeF'), I get directed to the Set Password page and the token in correctly logged in the console. I had tested tons of user signups and password resets with this configuration. However, when I use a tokenized url with '/#' as in '/#/enroll-account/uC537KPMJ5ojPwzeF' with the code below, I just get directed to the home page and nothing is logged in the console. Release 0.5.4 and the two commits mentioned all fail this test. And again, current dev is hosed. this.route('enrollAccount', {
path: '/#/enroll-account/:token',
controller: 'SetPasswordController'
});
...
this.route('setPassword', {
path: '/#/set-password/:token',
controller: 'SetPasswordController'
});
...
SetPasswordController = RouteController.extend({
run: function () {
var setPasswordToken = this.params.token;
Session.set('setPasswordToken', setPasswordToken);
console.log(setPasswordToken); // debug
this.render('setPassword');
}
}); So I'll continue to use the override as I've been doing, and perhaps take a look at the iron-router code in some spare moments (hah!). |
I just pushed a fix for the manual rendering issue ([document fragment] in body). See #148. For the accounts-base (sorry I had said accounts-ui previously but you're right; all the url stuff is in accounts-base) I'm observing normal Meteor behavior, but in iron-router 0.5.4 we weren't dealing with hashes properly. Now we are. Here's what I can observe is happening when I paste the enroll-account url into the browser:
|
@cmather so when defining the route, is it best to add or remove the '/#' ? |
For the accounts urls I think it's best not try conflict with Meteor internals. So, anytime Meteor sees a url that looks like /#/enroll-account or any of the other email urls, it will strip everything after the hash out of the url. This will happen as soon as the accounts-base code executes on the client. In general, the hash fragment of a url is considered variable to the router and shouldn't be used as a dynamic segment in the path. The value of the hash fragment will be made available in the parameters object under the Examples: Router.map(function () {
this.route('someRoute', {
path: '/somepath/:_id',
action: function () {
var hashValue = this.params.hash;
var _idValue = this.params._id;
}
});
}); For the above code both of the below urls will dispatch to the someRoute route:
EDIT |
First of all, dev has improved, but is still broken; I put the comment with Issue #148. OK, I now understand what has been going on with those match calls in meteor/packages/accounts-base/url_client.js looking for hash fragments and stripping out the fragment. I also read the why cited for this.
To circumvent all of this, I can override Accounts.sendEnrollmentEmail and Accounts.sendResetPasswordEmail functions to send the raw token, and the url to my Set Password page, in the email. Once there, the user can copy and paste the token in to a form field. Another option that works is to override your Accounts.urls by adding your desired destination path before the hash, so that when Meteor strips everything out you end up at your desired location and your Accounts._resetPasswordToken is still intact.
|
+1 |
Interesting.... The latest dev version did not work. I ended up adding my own route, and handling the Account._* variables myself. |
@samhatoum's solution seems to still be necessary. Although I had to change the method call on |
Any updates to this |
I am using @samhatoum's solution, and still not working. Its getting redirected to my index page "/" |
@KrishManohar If you could post a summary of what you did in code, perhaps I can help. Otherwise, it's impossible to know what exactly you did "using samhatoum's solution". |
I posted more information here: https://groups.google.com/forum/#!topic/meteor-talk/p4xlSiaQKq8 So my application signup sends a verification email to our users: http://localhost:3000/#/verify-email/11da222dadtokendadadtTOKEN_Dad After the user gets the email and click on it - it ends up Redirecting to our home page. I follow #3 = samhatoum post Router Code: this.route('verifyEmail',
{
controller: 'AccountController',
path: '/verify-email/:token',
action: 'verifyEmail'
}); Controller Code: AccountController = RouteController.extend({
verifyEmail: function () {
Accounts.verifyEmail(this.params.token, function () {
Router.go('/login');
});
}
}); My Before Action Code: var mustBeSignedIn = function(pause) {
if (!(Meteor.user() || Meteor.loggingIn())) {
Router.go('login');
pause();
}
};
var goToDashboard = function(pause) {
if (Meteor.user()) {
Meteor.logout();
Router.go('library');
pause();
}
};
Router.onBeforeAction(goToDashboard, {only:['home', 'login'] }); //Add Back Login
Router.onBeforeAction(mustBeSignedIn, {except: ['login', 'verifyEmail', 'resetPassword']}); Now Server Code For Absolute URL: (function () {
"use strict";
Accounts.urls.resetPassword = function (token) {
return Meteor.absoluteUrl('reset-password/' + token);
};
Accounts.urls.verifyEmail = function (token) {
return Meteor.absoluteUrl('verify-email/' + token);
};
})(); |
Iron Router is not what is causing this. The meteor accounts system detects |
@KrishManohar I don't think you are following samhatoum's solution properly. If you were, the URL generated by the server that's placed in the email would not have a "#" in it. Meteor's accounts-base package contains code like this
This code strips out everything after the "#", before iron-router can get to parse it, and it leaves your path as "/". So, where are you placing the server code which is supposed to generate a URL without a "#"? |
So its my fault... That email was generated before i looked up why... and use samhatoum's code. I will run another signup process.... Update: It work! Thank you so much for pointing this out... I should have read meteor doc on absolute url |
Great! Good luck with the rest of your app. |
Thank you. |
Just a quick question, is there a possibility that in the near future the issue is fixed by a code change either in iron-router or in meteor? |
This is really a question to pose to the authors/contributors of Iron Router and Meteor. I believe any change to the behavior you observed is unlikely (look at the dates on this thread). I have worked around it and moved on. |
Sorry, Can someone tell me please when After the password is successully confirmed I get redirected to my UserDashboard Page. But then I logout and should be redirected to login but I get redirected to the password confirmation again because #Router
Router.route('/register', {
name: 'register',
template: 'Register',
title: 'Register'
})
Router.route('/', {
name: 'login',
layoutTemplate: 'Frontpage',
layout: 'Login',
title: 'Home'
}); @LoginController = RouteController.extend(
onBeforeAction: ->
if Meteor.user()
Router.go('dashboard')
else
@next()
waitOn: ->
data: ->
action: ->
# in order to catch the iron:router hashtag issue
# requests will be redirected here
#
console.log "from action:"
console.log Accounts._resetPasswordToken
if Accounts._resetPasswordToken
Router.go('recover_password', token: Accounts._resetPasswordToken)
else
@render()
) @RecoverPasswordController = RouteController.extend(
onBeforeAction: ->
if Meteor.user()
Router.go('dashboard')
else
@next()
waitOn: ->
data: ->
action: ->
@render()
)
# RecoverPassword: Event Handlers and Helpers
Template.RecoverPassword.events
'submit form#form-lock': (e, tpl) ->
e.preventDefault
if AutoForm.validateForm('form-lock')
email = tpl.find('#recover-email-field').value
Session.set('loading', true);
Accounts.forgotPassword(email: email, (err) ->
if (err)
Session.set('errorMessages', err.reason)
else
Session.set('errorMessages', 'Email Sent! Please check your email.')
)
Session.set('loading', false);
else
Session.set 'errorMessages', 'Form not valid'
false
'submit form#form-new-password': (e, tpl) ->
e.preventDefault
if AutoForm.validateForm('form-new-password')
password = tpl.find('#new-password-field').value
token = Session.get('resetPassword')
Accounts.resetPassword(token, password, (err) ->
if err != undefined
console.log "ERRROR"
Session.set('errorMessages', err.reason)
else
console.log 'SUCCESS'
Session.set('errorMessages', null)
Session.set('loading', true)
Session.set('resetPassword', null)
Router.go('login')
)
else
Session.set 'errorMessages', 'Form incorrect. Please review it.'
false
Template.RecoverPassword.helpers
recoverPasswordSchema: ->
Schema.UserRecoverPassword
newPasswordSchema: ->
Schema.UserNewPassword
errorMessages: ->
Session.get('errorMessages')
resetPassword: ->
Session.get('resetPassword')
# RecoverPassword: Lifecycle Hooks
Template.RecoverPassword.created = ->
Template.RecoverPassword.rendered = ->
Template.RecoverPassword.destroyed = ->
if (Accounts._resetPasswordToken)
Session.set('resetPassword', Accounts._resetPasswordToken) |
I'm using a Meteor method to send an enrollment email to users, which looks like this:
http://localhost:3000/#/enroll-account/uC537KPMJ5ojPwzeF
I've verified that by moving the packages directory out of my app (to remove iron-router) the link above correctly presents the "change password" dialog, however when the router is in there, the dialog does not appear.
I'm using the accounts-ui package, which handles the password behavior.
Suggestions?
The text was updated successfully, but these errors were encountered: