diff --git a/addon/mixins/unauthenticated-route-mixin.js b/addon/mixins/unauthenticated-route-mixin.js index ad1dcf1d6..bd4942cb2 100644 --- a/addon/mixins/unauthenticated-route-mixin.js +++ b/addon/mixins/unauthenticated-route-mixin.js @@ -4,6 +4,20 @@ import { assert } from '@ember/debug'; import { computed } from '@ember/object'; import Configuration from './../configuration'; import isFastBoot from 'ember-simple-auth/utils/is-fastboot'; +import { getOwner } from '@ember/application'; + +/** + * + * @param {ApplicationInstance} owner The ApplicationInstance that owns the session service + * @param {(...args: [any]) => any} callback Callback that will be invoked if the user is authenticated + */ +function runIfAuthenticated(owner, callback) { + const sessionSvc = owner.lookup('service:session'); + if (sessionSvc.get('isAuthenticated')) { + callback(); + return true; + } +} /** __This mixin is used to make routes accessible only if the session is @@ -62,16 +76,16 @@ export default Mixin.create({ `beforeModel` method is actually executed. @method beforeModel - @param {Transition} transition The transition that lead to this route @public */ beforeModel() { - if (this.get('session').get('isAuthenticated')) { + const didRedirect = runIfAuthenticated(getOwner(this), () => { let routeIfAlreadyAuthenticated = this.get('routeIfAlreadyAuthenticated'); assert('The route configured as Configuration.routeIfAlreadyAuthenticated cannot implement the UnauthenticatedRouteMixin mixin as that leads to an infinite transitioning loop!', this.get('routeName') !== routeIfAlreadyAuthenticated); this.transitionTo(routeIfAlreadyAuthenticated); - } else { + }); + if (!didRedirect) { return this._super(...arguments); } } diff --git a/tests/unit/mixins/unauthenticated-route-mixin-test.js b/tests/unit/mixins/unauthenticated-route-mixin-test.js index 35aac0a83..dd6ab3ed5 100644 --- a/tests/unit/mixins/unauthenticated-route-mixin-test.js +++ b/tests/unit/mixins/unauthenticated-route-mixin-test.js @@ -7,11 +7,13 @@ import sinon from 'sinon'; import UnauthenticatedRouteMixin from 'ember-simple-auth/mixins/unauthenticated-route-mixin'; import InternalSession from 'ember-simple-auth/internal-session'; import EphemeralStore from 'ember-simple-auth/session-stores/ephemeral'; +import createWithContainer from '../../helpers/create-with-container'; describe('UnauthenticatedRouteMixin', () => { let route; let session; let transition; + let containerMock; describe('#beforeModel', function() { beforeEach(function() { @@ -20,18 +22,23 @@ describe('UnauthenticatedRouteMixin', () => { return RSVP.resolve('upstreamReturnValue'); } }); - session = InternalSession.create({ store: EphemeralStore.create() }); + transition = { send() {} }; + containerMock = { + lookup: sinon.stub() + }; - route = Route.extend(MixinImplementingBeforeModel, UnauthenticatedRouteMixin, { + containerMock.lookup.withArgs('service:session').returns(session); + + route = createWithContainer(Route.extend(MixinImplementingBeforeModel, UnauthenticatedRouteMixin, { // pretend this is never FastBoot - _isFastBoot: false, // replace actual transitionTo as the router isn't set up etc. transitionTo() {} - }).create({ session }); + }), { session }, containerMock); + sinon.spy(route, 'transitionTo'); });