Skip to content
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

captured attemptedTransition retry always fails #2287

Open
arenoir opened this issue Mar 31, 2021 · 5 comments
Open

captured attemptedTransition retry always fails #2287

arenoir opened this issue Mar 31, 2021 · 5 comments
Labels

Comments

@arenoir
Copy link

arenoir commented Mar 31, 2021

Since upgrading to version 3.1 my application fails to retry the pre login captured transition.

The attemptedTransition is set in the session service but it always fails on retry.

Any ideas as to why all attemptedTransition fails?

I have hacked the handleAuthentication hook to transition to the captured named route but this is not a solution.

import { inject as service } from '@ember/service';
import Service from 'ember-simple-auth/services/session';

export default class SessionService extends Service {
  @service router;
  handleAuthentication() {         
    if (this.attemptedTransition) {
      this.router.transitionTo(this.attemptedTransition.to.name);
    } else {
      this.router.transitionTo('/');
    }
  }
}

Test that was passing using version ember-simple-auth 3.0.

  test('visiting /jobs redirects to login page and upon successful login redirects to jobs page ', async function (assert) {
    mockValidLogin();
    await visit('/jobs');
    assert.equal(currentURL(), '/login');
    await fillIn('input', 'aaron');
    await fillIn('input[type=password]', 'password');
    await click('button[type=submit]');
    assert.equal(currentURL(), '/jobs');
  });
@arenoir
Copy link
Author

arenoir commented Apr 2, 2021

Something else to note I am requiring authentication in the the application route beforeModel hook like so.

  beforeModel(transition) {
    if (transition.targetName !== 'login') {
      this.session.requireAuthentication(transition, 'login');
    }
  }

@marcoow
Copy link
Member

marcoow commented May 7, 2021

I cannot reproduce this. Would you be able to set up a reproduction app?

Also be aware that the application route's beforeModel route is only called when you visit the first route in the app/when the app boots up. It will not be called when you transition between routes after that so you'd still have to explicitly requireAuthentication for all routes in your app that require the session to be authenticated.

@marcoow marcoow added the triage label May 7, 2021
@sacarino
Copy link

sacarino commented May 13, 2021

@arenoir just curious, are you using a custom authenticator? I'm wiring up to auth0-js and running into the same thing. Since auth0 has their hosted login page and then it sends the user to a callback, the attemptedTransition is lost in the page reload.

@arenoir
Copy link
Author

arenoir commented May 13, 2021

@sacarino, yes I am using a custom authenticator. This is a good bit of information. I haven't had much time to investigate but let me know if you get anywhere.

@sacarino
Copy link

sacarino commented May 13, 2021

Okay - at least in my case it's definitely an OAuth2 thing - a few other issues refer to it. Here's a Google OAuth2 one, but there's others.

Found an interesting comment about overriding ESA's cookie, but that doesn't work in this case since the page reload wipes out the session. As a result, whatever you had manually set becomes the callback's route as soon as they hit it.

It was nudge in a useful direction though... using ember-cookies, this rough take is working.

Worth mentioning that I have a base route that all my other routes extend, to address @marcoow's point

It will not be called when you transition between routes after that so you'd still have to explicitly requireAuthentication for all routes in your app that require the session to be authenticated.

baseRoute.js

@service session;
@service cookies;

beforeModel(transition) {
 
   ... other code
 
   if (!this.session.isAuthenticated) {
     this.saveDestination(transition);
   }
   
   this.session.requireAuthentication(transition, 'login');
},

saveDestination(transition) {
    if (transition.to.name !== 'login' &&
    transition.to.name !== 'callback') {
      // User has a preferred deep link
      let cookiesService = this.cookies;

      if (cookiesService.exists('desired-redirectTarget')) {
        // this workaround courtesy of firefox
        // https://github.com/simplabs/ember-cookies/issues/152#issuecomment-377833568
        cookiesService.write('desired-redirectTarget', '', { path: '/', expires: new Date().toISOString() });
        cookiesService.clear('desired-redirectTarget');
      }
      cookiesService.write('desired-redirectTarget', transition.intent.url, { path: '/', expires: new Date().toISOString() });
    }
  },

and then in my callback's route, which does NOT extend baseRoute

@service session;
@service cookies;

beforeModel() {
    // inside the callback route
    // try to authenticate
    // then send us to home (or their happy place, if exists)
    this.session
      .authenticate('authenticator:auth0')
      .then(() => {
        let cookiesService = this.cookies;
        let desiredUrl = cookiesService.read('desired-redirectTarget');
        
        if (desiredUrl) {
          this.transitionTo(desiredUrl);
          cookiesService.clear('desired-redirectTarget');
        } else {
          this.transitionTo('home')
        }
      });
  }

Hopefully that helps you solve your issue as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants